blob: a58bc064121eb3fe0119f2b5c5ae7f237a234289 [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>
blueswir124646c72008-11-07 16:55:48 +000047#include <arpa/inet.h>
bellard9d728e82004-09-05 23:09:03 +000048#include <dirent.h>
bellard7c9d8e02005-11-15 22:16:05 +000049#include <netdb.h>
thscb4b9762007-09-13 12:39:35 +000050#include <sys/select.h>
Juan Quintela71e72a12009-07-27 16:12:56 +020051#ifdef CONFIG_BSD
bellard7d3505c2004-05-12 19:32:15 +000052#include <sys/stat.h>
blueswir1c5e97232009-03-07 20:06:23 +000053#if defined(__FreeBSD__) || defined(__DragonFly__)
bellard7d3505c2004-05-12 19:32:15 +000054#include <libutil.h>
blueswir124646c72008-11-07 16:55:48 +000055#else
56#include <util.h>
blueswir1128ab2f2008-08-15 18:33:42 +000057#endif
ths5c40d2b2007-06-23 16:03:36 +000058#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
59#include <freebsd/stdlib.h>
bellard7d3505c2004-05-12 19:32:15 +000060#else
blueswir1223f0d72008-09-30 18:12:18 +000061#ifdef __linux__
bellard7d3505c2004-05-12 19:32:15 +000062#include <pty.h>
63#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000064#include <linux/rtc.h>
Andi Kleen18894652009-07-02 09:34:17 +020065#include <sys/prctl.h>
thsbd494f42007-09-16 20:03:23 +000066
67/* For the benefit of older linux systems which don't supply it,
68 we use a local copy of hpet.h. */
69/* #include <linux/hpet.h> */
70#include "hpet.h"
71
bellarde57a8c02005-11-10 23:58:52 +000072#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000073#include <linux/parport.h>
blueswir1223f0d72008-09-30 18:12:18 +000074#endif
75#ifdef __sun__
thsd5d10bc2007-02-17 22:54:49 +000076#include <sys/stat.h>
77#include <sys/ethernet.h>
78#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000079#include <netinet/arp.h>
80#include <netinet/in.h>
81#include <netinet/in_systm.h>
82#include <netinet/ip.h>
83#include <netinet/ip_icmp.h> // must come after ip.h
84#include <netinet/udp.h>
85#include <netinet/tcp.h>
86#include <net/if.h>
87#include <syslog.h>
88#include <stropts.h>
Blue Swirl8d32cf02009-10-02 19:32:12 +000089/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
90 discussion about Solaris header problems */
91extern int madvise(caddr_t, size_t, int);
bellard67b915a2004-03-31 23:37:16 +000092#endif
bellard7d3505c2004-05-12 19:32:15 +000093#endif
bellardec530c82006-04-25 22:36:06 +000094#endif
bellard67b915a2004-03-31 23:37:16 +000095
blueswir19892fbf2008-08-24 10:34:20 +000096#if defined(__OpenBSD__)
97#include <util.h>
98#endif
99
ths8a16d272008-07-19 09:56:24 +0000100#if defined(CONFIG_VDE)
101#include <libvdeplug.h>
102#endif
103
bellard67b915a2004-03-31 23:37:16 +0000104#ifdef _WIN32
aliguori49dc7682009-03-08 16:26:59 +0000105#include <windows.h>
ths4fddf622007-12-17 04:42:29 +0000106#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000107#endif
108
bellard73332e52004-04-04 20:22:28 +0000109#ifdef CONFIG_SDL
Stefan Weil59a36a22009-06-18 20:11:03 +0200110#if defined(__APPLE__) || defined(main)
Stefan Weil66936652009-06-13 13:19:11 +0200111#include <SDL.h>
malc880fec52009-02-15 20:18:41 +0000112int qemu_main(int argc, char **argv, char **envp);
113int main(int argc, char **argv)
114{
Stefan Weil59a36a22009-06-18 20:11:03 +0200115 return qemu_main(argc, argv, NULL);
malc880fec52009-02-15 20:18:41 +0000116}
117#undef main
118#define main qemu_main
bellard96bcd4f2004-07-10 16:26:15 +0000119#endif
bellard73332e52004-04-04 20:22:28 +0000120#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000121
bellard5b0753e2005-03-01 21:37:28 +0000122#ifdef CONFIG_COCOA
123#undef main
124#define main qemu_main
125#endif /* CONFIG_COCOA */
126
blueswir1511d2b12009-03-07 15:32:56 +0000127#include "hw/hw.h"
128#include "hw/boards.h"
129#include "hw/usb.h"
130#include "hw/pcmcia.h"
131#include "hw/pc.h"
132#include "hw/audiodev.h"
133#include "hw/isa.h"
134#include "hw/baum.h"
135#include "hw/bt.h"
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +0100136#include "hw/watchdog.h"
aliguorib6f6e3d2009-04-17 18:59:56 +0000137#include "hw/smbios.h"
aliguorie37630c2009-04-22 15:19:10 +0000138#include "hw/xen.h"
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +0200139#include "hw/qdev.h"
Gerd Hoffmann45a50b12009-10-01 16:42:33 +0200140#include "hw/loader.h"
aurel325ef4efa2009-03-10 21:43:35 +0000141#include "bt-host.h"
blueswir1511d2b12009-03-07 15:32:56 +0000142#include "net.h"
143#include "monitor.h"
144#include "console.h"
145#include "sysemu.h"
146#include "gdbstub.h"
147#include "qemu-timer.h"
148#include "qemu-char.h"
149#include "cache-utils.h"
150#include "block.h"
blueswir1a718ace2009-03-28 08:24:44 +0000151#include "dma.h"
blueswir1511d2b12009-03-07 15:32:56 +0000152#include "audio/audio.h"
153#include "migration.h"
154#include "kvm.h"
155#include "balloon.h"
Kevin Wolfd3f24362009-05-18 16:42:09 +0200156#include "qemu-option.h"
Gerd Hoffmann7282a032009-07-31 12:25:35 +0200157#include "qemu-config.h"
blueswir1511d2b12009-03-07 15:32:56 +0000158
bellard0824d6f2003-06-24 13:42:40 +0000159#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000160
bellard8a7ddc32004-03-31 19:00:16 +0000161#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000162
blueswir1511d2b12009-03-07 15:32:56 +0000163#include "qemu_socket.h"
164
Jan Kiszkad918f232009-06-24 14:42:30 +0200165#include "slirp/libslirp.h"
blueswir1511d2b12009-03-07 15:32:56 +0000166
Blue Swirl72cf2d42009-09-12 07:36:22 +0000167#include "qemu-queue.h"
168
blueswir19dc63a12008-10-04 07:25:46 +0000169//#define DEBUG_NET
170//#define DEBUG_SLIRP
bellard330d0412003-07-26 18:11:40 +0000171
bellard1bfe8562004-07-08 21:17:50 +0000172#define DEFAULT_RAM_SIZE 128
bellard313aa562003-08-10 21:52:11 +0000173
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +0200174/* Maximum number of monitor devices */
175#define MAX_MONITOR_DEVICES 10
176
Paul Brook5cea8592009-05-30 00:52:44 +0100177static const char *data_dir;
j_mayer1192dad2007-10-05 13:08:35 +0000178const char *bios_name = NULL;
thse4bcb142007-12-02 04:51:10 +0000179/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000180 to store the VM snapshots */
Blue Swirl72cf2d42009-09-12 07:36:22 +0000181struct drivelist drives = QTAILQ_HEAD_INITIALIZER(drives);
182struct driveoptlist driveopts = QTAILQ_HEAD_INITIALIZER(driveopts);
malccb5a7aa2008-09-28 00:42:12 +0000183enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
aliguori3023f332009-01-16 19:04:14 +0000184static DisplayState *display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -0500185DisplayType display_type = DT_DEFAULT;
bellard3d11d0e2004-12-12 16:56:30 +0000186const char* keyboard_layout = NULL;
Anthony Liguoric227f092009-10-01 16:12:16 -0500187ram_addr_t ram_size;
bellardc4b1fcc2004-03-14 21:44:30 +0000188int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000189NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000190int vm_running;
Paolo Bonzinid399f672009-07-27 23:17:51 +0200191int autostart;
balrogf6503052008-02-17 11:42:19 +0000192static int rtc_utc = 1;
193static int rtc_date_offset = -1; /* -1 means no change */
Jan Kiszka68752042009-09-15 13:36:04 +0200194QEMUClock *rtc_clock;
Zachary Amsden86176752009-07-30 00:15:02 -1000195int vga_interface_type = VGA_CIRRUS;
bellardd8272202005-04-06 20:32:23 +0000196#ifdef TARGET_SPARC
197int graphic_width = 1024;
198int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000199int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000200#else
bellard1bfe8562004-07-08 21:17:50 +0000201int graphic_width = 800;
202int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000203int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000204#endif
blueswir1dbed7e42008-10-01 19:38:09 +0000205static int full_screen = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000206#ifdef CONFIG_SDL
blueswir1dbed7e42008-10-01 19:38:09 +0000207static int no_frame = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000208#endif
ths667acca2006-12-11 02:08:05 +0000209int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000210CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000211CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
aliguori9ede2fd2009-01-15 20:05:25 +0000212CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
bellarda09db212005-04-30 16:10:35 +0000213#ifdef TARGET_I386
214int win2k_install_hack = 0;
aliguori73822ec2009-01-15 20:11:34 +0000215int rtc_td_hack = 0;
bellarda09db212005-04-30 16:10:35 +0000216#endif
bellardbb36d472005-11-05 14:22:28 +0000217int usb_enabled = 0;
aurel321b530a62009-04-05 20:08:59 +0000218int singlestep = 0;
bellard6a00d602005-11-21 23:25:50 +0000219int smp_cpus = 1;
Jes Sorensen6be68d72009-07-23 17:03:42 +0200220int max_cpus = 0;
Andre Przywaradc6b1c02009-08-19 15:42:40 +0200221int smp_cores = 1;
222int smp_threads = 1;
ths73fc9742006-12-22 02:09:07 +0000223const char *vnc_display;
bellard6515b202006-05-03 22:02:44 +0000224int acpi_enabled = 1;
aliguori16b29ae2008-12-17 23:28:44 +0000225int no_hpet = 0;
bellard52ca8d62006-06-14 16:03:05 +0000226int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000227int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000228int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000229int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000230int graphic_rotate = 0;
Jes Sorensen6b35e7b2009-08-06 16:25:50 +0200231uint8_t irq0override = 1;
blueswir1b9e82a52009-04-05 18:03:31 +0000232#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +0000233int daemonize = 0;
blueswir1b9e82a52009-04-05 18:03:31 +0000234#endif
Markus Armbruster09aaa162009-08-21 10:31:34 +0200235const char *watchdog;
ths9ae02552007-01-05 17:39:04 +0000236const char *option_rom[MAX_OPTION_ROMS];
237int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000238int semihosting_enabled = 0;
balrog2b8f2d42007-07-27 22:08:46 +0000239#ifdef TARGET_ARM
240int old_param = 0;
241#endif
thsc35734b2007-03-19 15:17:08 +0000242const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000243int alt_grab = 0;
Dustin Kirkland0ca9f8a2009-09-17 15:48:04 -0500244int ctrl_grab = 0;
blueswir195efd112008-12-24 20:26:14 +0000245#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +0000246unsigned int nb_prom_envs = 0;
247const char *prom_envs[MAX_PROM_ENVS];
248#endif
Jan Kiszka95387492009-07-02 00:19:02 +0200249int boot_menu;
bellard0824d6f2003-06-24 13:42:40 +0000250
aliguori268a3622009-04-21 22:30:27 +0000251int nb_numa_nodes;
252uint64_t node_mem[MAX_NODES];
253uint64_t node_cpumask[MAX_NODES];
254
balrogee5605e2007-12-03 03:01:40 +0000255static CPUState *cur_cpu;
256static CPUState *next_cpu;
aliguori43b96852009-04-24 18:03:33 +0000257static int timer_alarm_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000258/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000259static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000260/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000261#define MAX_ICOUNT_SHIFT 10
262/* Compensate for varying guest execution speed. */
263static int64_t qemu_icount_bias;
blueswir1dbed7e42008-10-01 19:38:09 +0000264static QEMUTimer *icount_rt_timer;
265static QEMUTimer *icount_vm_timer;
blueswir19043b622009-01-21 19:28:13 +0000266static QEMUTimer *nographic_timer;
balrogee5605e2007-12-03 03:01:40 +0000267
blueswir18fcb1b92008-09-18 18:29:08 +0000268uint8_t qemu_uuid[16];
269
Jan Kiszka76e30d02009-07-02 00:19:02 +0200270static QEMUBootSetHandler *boot_set_handler;
271static void *boot_set_opaque;
272
bellard0824d6f2003-06-24 13:42:40 +0000273/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000274/* x86 ISA bus support */
275
Anthony Liguoric227f092009-10-01 16:12:16 -0500276target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000277PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000278
bellard0824d6f2003-06-24 13:42:40 +0000279/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000280void hw_error(const char *fmt, ...)
281{
282 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000283 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000284
285 va_start(ap, fmt);
286 fprintf(stderr, "qemu: hardware error: ");
287 vfprintf(stderr, fmt, ap);
288 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000289 for(env = first_cpu; env != NULL; env = env->next_cpu) {
290 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000291#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000292 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000293#else
bellard6a00d602005-11-21 23:25:50 +0000294 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000295#endif
bellard6a00d602005-11-21 23:25:50 +0000296 }
bellard0824d6f2003-06-24 13:42:40 +0000297 va_end(ap);
298 abort();
299}
Andi Kleen18894652009-07-02 09:34:17 +0200300
301static void set_proc_name(const char *s)
302{
Nathan Froyd6ca8d0f2009-08-03 07:32:12 -0700303#if defined(__linux__) && defined(PR_SET_NAME)
Andi Kleen18894652009-07-02 09:34:17 +0200304 char name[16];
305 if (!s)
306 return;
307 name[sizeof(name) - 1] = 0;
308 strncpy(name, s, sizeof(name));
309 /* Could rewrite argv[0] too, but that's a bit more complicated.
310 This simple way is enough for `top'. */
311 prctl(PR_SET_NAME, name);
312#endif
313}
aliguoridf751fa2008-12-04 20:19:35 +0000314
315/***************/
316/* ballooning */
317
318static QEMUBalloonEvent *qemu_balloon_event;
319void *qemu_balloon_event_opaque;
320
321void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
322{
323 qemu_balloon_event = func;
324 qemu_balloon_event_opaque = opaque;
325}
326
Anthony Liguoric227f092009-10-01 16:12:16 -0500327void qemu_balloon(ram_addr_t target)
aliguoridf751fa2008-12-04 20:19:35 +0000328{
329 if (qemu_balloon_event)
330 qemu_balloon_event(qemu_balloon_event_opaque, target);
331}
332
Anthony Liguoric227f092009-10-01 16:12:16 -0500333ram_addr_t qemu_balloon_status(void)
aliguoridf751fa2008-12-04 20:19:35 +0000334{
335 if (qemu_balloon_event)
336 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
337 return 0;
338}
bellard0824d6f2003-06-24 13:42:40 +0000339
bellard8a7ddc32004-03-31 19:00:16 +0000340/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000341/* keyboard/mouse */
342
343static QEMUPutKBDEvent *qemu_put_kbd_event;
344static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000345static QEMUPutMouseEntry *qemu_put_mouse_event_head;
346static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000347
348void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
349{
350 qemu_put_kbd_event_opaque = opaque;
351 qemu_put_kbd_event = func;
352}
353
ths455204e2007-01-05 16:42:13 +0000354QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
355 void *opaque, int absolute,
356 const char *name)
bellard63066f42004-06-03 18:45:02 +0000357{
ths455204e2007-01-05 16:42:13 +0000358 QEMUPutMouseEntry *s, *cursor;
359
360 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
ths455204e2007-01-05 16:42:13 +0000361
362 s->qemu_put_mouse_event = func;
363 s->qemu_put_mouse_event_opaque = opaque;
364 s->qemu_put_mouse_event_absolute = absolute;
365 s->qemu_put_mouse_event_name = qemu_strdup(name);
366 s->next = NULL;
367
368 if (!qemu_put_mouse_event_head) {
369 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
370 return s;
371 }
372
373 cursor = qemu_put_mouse_event_head;
374 while (cursor->next != NULL)
375 cursor = cursor->next;
376
377 cursor->next = s;
378 qemu_put_mouse_event_current = s;
379
380 return s;
381}
382
383void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
384{
385 QEMUPutMouseEntry *prev = NULL, *cursor;
386
387 if (!qemu_put_mouse_event_head || entry == NULL)
388 return;
389
390 cursor = qemu_put_mouse_event_head;
391 while (cursor != NULL && cursor != entry) {
392 prev = cursor;
393 cursor = cursor->next;
394 }
395
396 if (cursor == NULL) // does not exist or list empty
397 return;
398 else if (prev == NULL) { // entry is head
399 qemu_put_mouse_event_head = cursor->next;
400 if (qemu_put_mouse_event_current == entry)
401 qemu_put_mouse_event_current = cursor->next;
402 qemu_free(entry->qemu_put_mouse_event_name);
403 qemu_free(entry);
404 return;
405 }
406
407 prev->next = entry->next;
408
409 if (qemu_put_mouse_event_current == entry)
410 qemu_put_mouse_event_current = prev;
411
412 qemu_free(entry->qemu_put_mouse_event_name);
413 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000414}
415
416void kbd_put_keycode(int keycode)
417{
418 if (qemu_put_kbd_event) {
419 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
420 }
421}
422
423void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
424{
ths455204e2007-01-05 16:42:13 +0000425 QEMUPutMouseEvent *mouse_event;
426 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000427 int width;
ths455204e2007-01-05 16:42:13 +0000428
429 if (!qemu_put_mouse_event_current) {
430 return;
431 }
432
433 mouse_event =
434 qemu_put_mouse_event_current->qemu_put_mouse_event;
435 mouse_event_opaque =
436 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
437
438 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000439 if (graphic_rotate) {
440 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
441 width = 0x7fff;
442 else
aurel32b94ed572008-03-10 19:34:27 +0000443 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000444 mouse_event(mouse_event_opaque,
445 width - dy, dx, dz, buttons_state);
446 } else
447 mouse_event(mouse_event_opaque,
448 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000449 }
450}
451
bellard09b26c52006-04-12 21:09:08 +0000452int kbd_mouse_is_absolute(void)
453{
ths455204e2007-01-05 16:42:13 +0000454 if (!qemu_put_mouse_event_current)
455 return 0;
456
457 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
458}
459
aliguori376253e2009-03-05 23:01:23 +0000460void do_info_mice(Monitor *mon)
ths455204e2007-01-05 16:42:13 +0000461{
462 QEMUPutMouseEntry *cursor;
463 int index = 0;
464
465 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000466 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000467 return;
468 }
469
aliguori376253e2009-03-05 23:01:23 +0000470 monitor_printf(mon, "Mouse devices available:\n");
ths455204e2007-01-05 16:42:13 +0000471 cursor = qemu_put_mouse_event_head;
472 while (cursor != NULL) {
aliguori376253e2009-03-05 23:01:23 +0000473 monitor_printf(mon, "%c Mouse #%d: %s\n",
474 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
475 index, cursor->qemu_put_mouse_event_name);
ths455204e2007-01-05 16:42:13 +0000476 index++;
477 cursor = cursor->next;
478 }
479}
480
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300481void do_mouse_set(Monitor *mon, const QDict *qdict)
ths455204e2007-01-05 16:42:13 +0000482{
483 QEMUPutMouseEntry *cursor;
484 int i = 0;
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300485 int index = qdict_get_int(qdict, "index");
ths455204e2007-01-05 16:42:13 +0000486
487 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000488 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000489 return;
490 }
491
492 cursor = qemu_put_mouse_event_head;
493 while (cursor != NULL && index != i) {
494 i++;
495 cursor = cursor->next;
496 }
497
498 if (cursor != NULL)
499 qemu_put_mouse_event_current = cursor;
500 else
aliguori376253e2009-03-05 23:01:23 +0000501 monitor_printf(mon, "Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000502}
503
bellard87858c82003-06-27 12:01:39 +0000504/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000505uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000506{
507 union {
508 uint64_t ll;
509 struct {
Juan Quintelae2542fe2009-07-27 16:13:06 +0200510#ifdef HOST_WORDS_BIGENDIAN
bellard87858c82003-06-27 12:01:39 +0000511 uint32_t high, low;
512#else
513 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000514#endif
bellard87858c82003-06-27 12:01:39 +0000515 } l;
516 } u, res;
517 uint64_t rl, rh;
518
519 u.ll = a;
520 rl = (uint64_t)u.l.low * (uint64_t)b;
521 rh = (uint64_t)u.l.high * (uint64_t)b;
522 rh += (rl >> 32);
523 res.l.high = rh / c;
524 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
525 return res.ll;
526}
527
bellard1dce7c32006-07-13 23:20:22 +0000528/***********************************************************/
529/* real time host monotonic timer */
530
Jan Kiszka21d5d122009-09-15 13:36:04 +0200531static int64_t get_clock_realtime(void)
532{
533 struct timeval tv;
534
535 gettimeofday(&tv, NULL);
536 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
537}
538
bellard1dce7c32006-07-13 23:20:22 +0000539#ifdef WIN32
540
541static int64_t clock_freq;
542
543static void init_get_clock(void)
544{
bellarda8e5ac32006-07-14 09:36:13 +0000545 LARGE_INTEGER freq;
546 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000547 ret = QueryPerformanceFrequency(&freq);
548 if (ret == 0) {
549 fprintf(stderr, "Could not calibrate ticks\n");
550 exit(1);
551 }
552 clock_freq = freq.QuadPart;
553}
554
555static int64_t get_clock(void)
556{
557 LARGE_INTEGER ti;
558 QueryPerformanceCounter(&ti);
Anthony Liguori274dfed2009-09-11 10:28:26 -0500559 return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
bellard1dce7c32006-07-13 23:20:22 +0000560}
561
562#else
563
564static int use_rt_clock;
565
566static void init_get_clock(void)
567{
568 use_rt_clock = 0;
blueswir1c5e97232009-03-07 20:06:23 +0000569#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
570 || defined(__DragonFly__)
bellard1dce7c32006-07-13 23:20:22 +0000571 {
572 struct timespec ts;
573 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
574 use_rt_clock = 1;
575 }
576 }
577#endif
578}
579
580static int64_t get_clock(void)
581{
blueswir1c5e97232009-03-07 20:06:23 +0000582#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
583 || defined(__DragonFly__)
bellard1dce7c32006-07-13 23:20:22 +0000584 if (use_rt_clock) {
585 struct timespec ts;
586 clock_gettime(CLOCK_MONOTONIC, &ts);
587 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000588 } else
bellard1dce7c32006-07-13 23:20:22 +0000589#endif
590 {
591 /* XXX: using gettimeofday leads to problems if the date
592 changes, so it should be avoided. */
Jan Kiszka21d5d122009-09-15 13:36:04 +0200593 return get_clock_realtime();
bellard1dce7c32006-07-13 23:20:22 +0000594 }
595}
bellard1dce7c32006-07-13 23:20:22 +0000596#endif
597
pbrook2e70f6e2008-06-29 01:03:05 +0000598/* Return the virtual CPU time, based on the instruction counter. */
599static int64_t cpu_get_icount(void)
600{
601 int64_t icount;
602 CPUState *env = cpu_single_env;;
603 icount = qemu_icount;
604 if (env) {
605 if (!can_do_io(env))
606 fprintf(stderr, "Bad clock read\n");
607 icount -= (env->icount_decr.u16.low + env->icount_extra);
608 }
609 return qemu_icount_bias + (icount << icount_time_shift);
610}
611
bellard1dce7c32006-07-13 23:20:22 +0000612/***********************************************************/
613/* guest cycle counter */
614
Juan Quintela6f68e332009-09-10 03:04:27 +0200615typedef struct TimersState {
616 int64_t cpu_ticks_prev;
617 int64_t cpu_ticks_offset;
618 int64_t cpu_clock_offset;
619 int32_t cpu_ticks_enabled;
Anthony Liguori274dfed2009-09-11 10:28:26 -0500620 int64_t dummy;
Juan Quintela6f68e332009-09-10 03:04:27 +0200621} TimersState;
622
623TimersState timers_state;
bellard1dce7c32006-07-13 23:20:22 +0000624
625/* return the host CPU cycle counter and handle stop/restart */
626int64_t cpu_get_ticks(void)
627{
pbrook2e70f6e2008-06-29 01:03:05 +0000628 if (use_icount) {
629 return cpu_get_icount();
630 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200631 if (!timers_state.cpu_ticks_enabled) {
632 return timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000633 } else {
634 int64_t ticks;
635 ticks = cpu_get_real_ticks();
Juan Quintela6f68e332009-09-10 03:04:27 +0200636 if (timers_state.cpu_ticks_prev > ticks) {
bellard1dce7c32006-07-13 23:20:22 +0000637 /* Note: non increasing ticks may happen if the host uses
638 software suspend */
Juan Quintela6f68e332009-09-10 03:04:27 +0200639 timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
bellard1dce7c32006-07-13 23:20:22 +0000640 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200641 timers_state.cpu_ticks_prev = ticks;
642 return ticks + timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000643 }
644}
645
646/* return the host CPU monotonic timer and handle stop/restart */
647static int64_t cpu_get_clock(void)
648{
649 int64_t ti;
Juan Quintela6f68e332009-09-10 03:04:27 +0200650 if (!timers_state.cpu_ticks_enabled) {
651 return timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000652 } else {
653 ti = get_clock();
Juan Quintela6f68e332009-09-10 03:04:27 +0200654 return ti + timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000655 }
656}
657
658/* enable cpu_get_ticks() */
659void cpu_enable_ticks(void)
660{
Juan Quintela6f68e332009-09-10 03:04:27 +0200661 if (!timers_state.cpu_ticks_enabled) {
662 timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
663 timers_state.cpu_clock_offset -= get_clock();
664 timers_state.cpu_ticks_enabled = 1;
bellard1dce7c32006-07-13 23:20:22 +0000665 }
666}
667
668/* disable cpu_get_ticks() : the clock is stopped. You must not call
669 cpu_get_ticks() after that. */
670void cpu_disable_ticks(void)
671{
Juan Quintela6f68e332009-09-10 03:04:27 +0200672 if (timers_state.cpu_ticks_enabled) {
673 timers_state.cpu_ticks_offset = cpu_get_ticks();
674 timers_state.cpu_clock_offset = cpu_get_clock();
675 timers_state.cpu_ticks_enabled = 0;
bellard1dce7c32006-07-13 23:20:22 +0000676 }
677}
678
679/***********************************************************/
680/* timers */
ths5fafdf22007-09-16 21:08:06 +0000681
Jan Kiszka0fdddf82009-09-15 13:36:04 +0200682#define QEMU_CLOCK_REALTIME 0
683#define QEMU_CLOCK_VIRTUAL 1
Jan Kiszka21d5d122009-09-15 13:36:04 +0200684#define QEMU_CLOCK_HOST 2
bellard8a7ddc32004-03-31 19:00:16 +0000685
686struct QEMUClock {
687 int type;
688 /* XXX: add frequency */
689};
690
691struct QEMUTimer {
692 QEMUClock *clock;
693 int64_t expire_time;
694 QEMUTimerCB *cb;
695 void *opaque;
696 struct QEMUTimer *next;
697};
698
thsc8994012007-08-19 21:56:03 +0000699struct qemu_alarm_timer {
700 char const *name;
thsefe75412007-08-24 01:36:32 +0000701 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000702
703 int (*start)(struct qemu_alarm_timer *t);
704 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000705 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000706 void *priv;
707};
708
thsefe75412007-08-24 01:36:32 +0000709#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000710#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000711
712static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
713{
Jean-Christophe Duboise3323402009-05-17 18:38:39 +0200714 return t && (t->flags & ALARM_FLAG_DYNTICKS);
thsefe75412007-08-24 01:36:32 +0000715}
716
717static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
718{
719 if (!alarm_has_dynticks(t))
720 return;
721
722 t->rearm(t);
723}
724
725/* TODO: MIN_TIMER_REARM_US should be optimized */
726#define MIN_TIMER_REARM_US 250
727
thsc8994012007-08-19 21:56:03 +0000728static struct qemu_alarm_timer *alarm_timer;
729
730#ifdef _WIN32
731
732struct qemu_alarm_win32 {
733 MMRESULT timerId;
thsc8994012007-08-19 21:56:03 +0000734 unsigned int period;
Blue Swirlef28c4b2009-04-25 12:56:37 +0000735} alarm_win32_data = {0, -1};
thsc8994012007-08-19 21:56:03 +0000736
737static int win32_start_timer(struct qemu_alarm_timer *t);
738static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000739static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000740
741#else
742
743static int unix_start_timer(struct qemu_alarm_timer *t);
744static void unix_stop_timer(struct qemu_alarm_timer *t);
745
ths231c6582007-08-26 17:29:15 +0000746#ifdef __linux__
747
thsefe75412007-08-24 01:36:32 +0000748static int dynticks_start_timer(struct qemu_alarm_timer *t);
749static void dynticks_stop_timer(struct qemu_alarm_timer *t);
750static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
751
thsc40ec5a2007-08-19 22:09:40 +0000752static int hpet_start_timer(struct qemu_alarm_timer *t);
753static void hpet_stop_timer(struct qemu_alarm_timer *t);
754
thsc8994012007-08-19 21:56:03 +0000755static int rtc_start_timer(struct qemu_alarm_timer *t);
756static void rtc_stop_timer(struct qemu_alarm_timer *t);
757
thsefe75412007-08-24 01:36:32 +0000758#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000759
760#endif /* _WIN32 */
761
pbrook2e70f6e2008-06-29 01:03:05 +0000762/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000763 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000764 When the guest is idle real and virtual time will be aligned in
765 the IO wait loop. */
Anthony Liguori274dfed2009-09-11 10:28:26 -0500766#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
pbrook2e70f6e2008-06-29 01:03:05 +0000767
768static void icount_adjust(void)
769{
770 int64_t cur_time;
771 int64_t cur_icount;
772 int64_t delta;
773 static int64_t last_delta;
774 /* If the VM is not running, then do nothing. */
775 if (!vm_running)
776 return;
777
778 cur_time = cpu_get_clock();
779 cur_icount = qemu_get_clock(vm_clock);
780 delta = cur_icount - cur_time;
781 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
782 if (delta > 0
783 && last_delta + ICOUNT_WOBBLE < delta * 2
784 && icount_time_shift > 0) {
785 /* The guest is getting too far ahead. Slow time down. */
786 icount_time_shift--;
787 }
788 if (delta < 0
789 && last_delta - ICOUNT_WOBBLE > delta * 2
790 && icount_time_shift < MAX_ICOUNT_SHIFT) {
791 /* The guest is getting too far behind. Speed time up. */
792 icount_time_shift++;
793 }
794 last_delta = delta;
795 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
796}
797
798static void icount_adjust_rt(void * opaque)
799{
800 qemu_mod_timer(icount_rt_timer,
801 qemu_get_clock(rt_clock) + 1000);
802 icount_adjust();
803}
804
805static void icount_adjust_vm(void * opaque)
806{
807 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500808 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000809 icount_adjust();
810}
811
812static void init_icount_adjust(void)
813{
814 /* Have both realtime and virtual time triggers for speed adjustment.
815 The realtime trigger catches emulated time passing too slowly,
816 the virtual time trigger catches emulated time passing too fast.
817 Realtime triggers occur even when idle, so use them less frequently
818 than VM triggers. */
819 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
820 qemu_mod_timer(icount_rt_timer,
821 qemu_get_clock(rt_clock) + 1000);
822 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
823 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500824 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000825}
826
thsc8994012007-08-19 21:56:03 +0000827static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000828#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000829#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000830 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
831 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000832 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +0000833 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000834 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +0000835 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000836#endif
thsefe75412007-08-24 01:36:32 +0000837 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000838#else
thsefe75412007-08-24 01:36:32 +0000839 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
840 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
841 {"win32", 0, win32_start_timer,
842 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +0000843#endif
844 {NULL, }
845};
846
blueswir13f47aa82008-03-09 06:59:01 +0000847static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +0000848{
849 int i;
850
851 printf("Available alarm timers, in order of precedence:\n");
852 for (i = 0; alarm_timers[i].name; i++)
853 printf("%s\n", alarm_timers[i].name);
854}
855
856static void configure_alarms(char const *opt)
857{
858 int i;
859 int cur = 0;
malcb1503cd2008-12-22 20:33:55 +0000860 int count = ARRAY_SIZE(alarm_timers) - 1;
thsf3dcfad2007-08-24 01:26:02 +0000861 char *arg;
862 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +0000863 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +0000864
aurel323adda042008-03-09 23:43:49 +0000865 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +0000866 show_available_alarms();
867 exit(0);
868 }
869
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200870 arg = qemu_strdup(opt);
thsf3dcfad2007-08-24 01:26:02 +0000871
872 /* Reorder the array */
873 name = strtok(arg, ",");
874 while (name) {
balroge2b577e2007-09-17 21:25:20 +0000875 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +0000876 if (!strcmp(alarm_timers[i].name, name))
877 break;
878 }
879
880 if (i == count) {
881 fprintf(stderr, "Unknown clock %s\n", name);
882 goto next;
883 }
884
885 if (i < cur)
886 /* Ignore */
887 goto next;
888
889 /* Swap */
890 tmp = alarm_timers[i];
891 alarm_timers[i] = alarm_timers[cur];
892 alarm_timers[cur] = tmp;
893
894 cur++;
895next:
896 name = strtok(NULL, ",");
897 }
898
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200899 qemu_free(arg);
thsf3dcfad2007-08-24 01:26:02 +0000900
901 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +0000902 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +0000903 for (i = cur; i < count; i++)
904 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +0000905 } else {
906 show_available_alarms();
907 exit(1);
thsf3dcfad2007-08-24 01:26:02 +0000908 }
thsf3dcfad2007-08-24 01:26:02 +0000909}
910
Jan Kiszka21d5d122009-09-15 13:36:04 +0200911#define QEMU_NUM_CLOCKS 3
912
bellard8a7ddc32004-03-31 19:00:16 +0000913QEMUClock *rt_clock;
914QEMUClock *vm_clock;
Jan Kiszka21d5d122009-09-15 13:36:04 +0200915QEMUClock *host_clock;
bellard8a7ddc32004-03-31 19:00:16 +0000916
Jan Kiszka21d5d122009-09-15 13:36:04 +0200917static QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
bellard8a7ddc32004-03-31 19:00:16 +0000918
pbrook9596ebb2007-11-18 01:44:38 +0000919static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +0000920{
921 QEMUClock *clock;
922 clock = qemu_mallocz(sizeof(QEMUClock));
bellard8a7ddc32004-03-31 19:00:16 +0000923 clock->type = type;
924 return clock;
925}
926
927QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
928{
929 QEMUTimer *ts;
930
931 ts = qemu_mallocz(sizeof(QEMUTimer));
932 ts->clock = clock;
933 ts->cb = cb;
934 ts->opaque = opaque;
935 return ts;
936}
937
938void qemu_free_timer(QEMUTimer *ts)
939{
940 qemu_free(ts);
941}
942
943/* stop a timer, but do not dealloc it */
944void qemu_del_timer(QEMUTimer *ts)
945{
946 QEMUTimer **pt, *t;
947
948 /* NOTE: this code must be signal safe because
949 qemu_timer_expired() can be called from a signal. */
950 pt = &active_timers[ts->clock->type];
951 for(;;) {
952 t = *pt;
953 if (!t)
954 break;
955 if (t == ts) {
956 *pt = t->next;
957 break;
958 }
959 pt = &t->next;
960 }
961}
962
963/* modify the current timer so that it will be fired when current_time
964 >= expire_time. The corresponding callback will be called. */
965void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
966{
967 QEMUTimer **pt, *t;
968
969 qemu_del_timer(ts);
970
971 /* add the timer in the sorted list */
972 /* NOTE: this code must be signal safe because
973 qemu_timer_expired() can be called from a signal. */
974 pt = &active_timers[ts->clock->type];
975 for(;;) {
976 t = *pt;
977 if (!t)
978 break;
ths5fafdf22007-09-16 21:08:06 +0000979 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +0000980 break;
981 pt = &t->next;
982 }
983 ts->expire_time = expire_time;
984 ts->next = *pt;
985 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +0000986
987 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +0000988 if (pt == &active_timers[ts->clock->type]) {
989 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
990 qemu_rearm_alarm_timer(alarm_timer);
991 }
992 /* Interrupt execution to force deadline recalculation. */
aliguorid9f75a42009-04-24 18:03:11 +0000993 if (use_icount)
994 qemu_notify_event();
pbrook2e70f6e2008-06-29 01:03:05 +0000995 }
bellard8a7ddc32004-03-31 19:00:16 +0000996}
997
998int qemu_timer_pending(QEMUTimer *ts)
999{
1000 QEMUTimer *t;
1001 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1002 if (t == ts)
1003 return 1;
1004 }
1005 return 0;
1006}
1007
Stefano Stabellini2430ffe2009-08-03 10:56:01 +01001008int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001009{
1010 if (!timer_head)
1011 return 0;
1012 return (timer_head->expire_time <= current_time);
1013}
1014
1015static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1016{
1017 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001018
bellard8a7ddc32004-03-31 19:00:16 +00001019 for(;;) {
1020 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001021 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001022 break;
1023 /* remove timer from the list before calling the callback */
1024 *ptimer_head = ts->next;
1025 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001026
bellard8a7ddc32004-03-31 19:00:16 +00001027 /* run the callback (the timer list can be modified) */
1028 ts->cb(ts->opaque);
1029 }
1030}
1031
1032int64_t qemu_get_clock(QEMUClock *clock)
1033{
1034 switch(clock->type) {
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001035 case QEMU_CLOCK_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001036 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001037 default:
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001038 case QEMU_CLOCK_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001039 if (use_icount) {
1040 return cpu_get_icount();
1041 } else {
1042 return cpu_get_clock();
1043 }
Jan Kiszka21d5d122009-09-15 13:36:04 +02001044 case QEMU_CLOCK_HOST:
1045 return get_clock_realtime();
bellard8a7ddc32004-03-31 19:00:16 +00001046 }
1047}
1048
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001049static void init_clocks(void)
bellard1dce7c32006-07-13 23:20:22 +00001050{
1051 init_get_clock();
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001052 rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
1053 vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001054 host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
Jan Kiszka68752042009-09-15 13:36:04 +02001055
1056 rtc_clock = host_clock;
bellard1dce7c32006-07-13 23:20:22 +00001057}
1058
bellard8a7ddc32004-03-31 19:00:16 +00001059/* save a timer */
1060void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1061{
1062 uint64_t expire_time;
1063
1064 if (qemu_timer_pending(ts)) {
1065 expire_time = ts->expire_time;
1066 } else {
1067 expire_time = -1;
1068 }
1069 qemu_put_be64(f, expire_time);
1070}
1071
1072void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1073{
1074 uint64_t expire_time;
1075
1076 expire_time = qemu_get_be64(f);
1077 if (expire_time != -1) {
1078 qemu_mod_timer(ts, expire_time);
1079 } else {
1080 qemu_del_timer(ts);
1081 }
1082}
1083
Juan Quintela2faf58c2009-09-10 03:04:28 +02001084static const VMStateDescription vmstate_timers = {
1085 .name = "timer",
1086 .version_id = 2,
1087 .minimum_version_id = 1,
1088 .minimum_version_id_old = 1,
1089 .fields = (VMStateField []) {
1090 VMSTATE_INT64(cpu_ticks_offset, TimersState),
Anthony Liguori274dfed2009-09-11 10:28:26 -05001091 VMSTATE_INT64(dummy, TimersState),
Juan Quintela2faf58c2009-09-10 03:04:28 +02001092 VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
1093 VMSTATE_END_OF_LIST()
bellardc88676f2006-08-06 13:36:11 +00001094 }
Juan Quintela2faf58c2009-09-10 03:04:28 +02001095};
bellard8a7ddc32004-03-31 19:00:16 +00001096
aliguori50317c72009-04-24 18:03:29 +00001097static void qemu_event_increment(void);
1098
bellard67b915a2004-03-31 23:37:16 +00001099#ifdef _WIN32
blueswir1b9e82a52009-04-05 18:03:31 +00001100static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1101 DWORD_PTR dwUser, DWORD_PTR dw1,
1102 DWORD_PTR dw2)
bellard67b915a2004-03-31 23:37:16 +00001103#else
bellard8a7ddc32004-03-31 19:00:16 +00001104static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001105#endif
bellard8a7ddc32004-03-31 19:00:16 +00001106{
bellard02ba45c2004-06-25 14:46:23 +00001107#if 0
1108#define DISP_FREQ 1000
1109 {
1110 static int64_t delta_min = INT64_MAX;
1111 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1112 static int count;
1113 ti = qemu_get_clock(vm_clock);
1114 if (last_clock != 0) {
1115 delta = ti - last_clock;
1116 if (delta < delta_min)
1117 delta_min = delta;
1118 if (delta > delta_max)
1119 delta_max = delta;
1120 delta_cum += delta;
1121 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001122 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
Juan Quintela6ee093c2009-09-10 03:04:26 +02001123 muldiv64(delta_min, 1000000, get_ticks_per_sec()),
1124 muldiv64(delta_max, 1000000, get_ticks_per_sec()),
1125 muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
1126 (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
bellard02ba45c2004-06-25 14:46:23 +00001127 count = 0;
1128 delta_min = INT64_MAX;
1129 delta_max = 0;
1130 delta_cum = 0;
1131 }
1132 }
1133 last_clock = ti;
1134 }
1135#endif
thsefe75412007-08-24 01:36:32 +00001136 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001137 (!use_icount &&
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001138 qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
pbrook2e70f6e2008-06-29 01:03:05 +00001139 qemu_get_clock(vm_clock))) ||
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001140 qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
Jan Kiszka21d5d122009-09-15 13:36:04 +02001141 qemu_get_clock(rt_clock)) ||
1142 qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
1143 qemu_get_clock(host_clock))) {
aliguori50317c72009-04-24 18:03:29 +00001144 qemu_event_increment();
Jean-Christophe Duboise3323402009-05-17 18:38:39 +02001145 if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
balrogd5d08332008-01-05 19:41:47 +00001146
aliguorid6dc3d42009-04-24 18:04:07 +00001147#ifndef CONFIG_IOTHREAD
1148 if (next_cpu) {
balrog4f8eb8d2007-12-16 12:39:38 +00001149 /* stop the currently executing cpu because a timer occured */
aliguorid6dc3d42009-04-24 18:04:07 +00001150 cpu_exit(next_cpu);
balrog4f8eb8d2007-12-16 12:39:38 +00001151 }
aliguorid6dc3d42009-04-24 18:04:07 +00001152#endif
aliguori43b96852009-04-24 18:03:33 +00001153 timer_alarm_pending = 1;
aliguorid9f75a42009-04-24 18:03:11 +00001154 qemu_notify_event();
bellard8a7ddc32004-03-31 19:00:16 +00001155 }
1156}
1157
pbrook2e70f6e2008-06-29 01:03:05 +00001158static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001159{
Jan Kiszka21d5d122009-09-15 13:36:04 +02001160 /* To avoid problems with overflow limit this to 2^32. */
1161 int64_t delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001162
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001163 if (active_timers[QEMU_CLOCK_VIRTUAL]) {
1164 delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001165 qemu_get_clock(vm_clock);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001166 }
1167 if (active_timers[QEMU_CLOCK_HOST]) {
1168 int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
1169 qemu_get_clock(host_clock);
1170 if (hdelta < delta)
1171 delta = hdelta;
thsefe75412007-08-24 01:36:32 +00001172 }
1173
pbrook2e70f6e2008-06-29 01:03:05 +00001174 if (delta < 0)
1175 delta = 0;
thsefe75412007-08-24 01:36:32 +00001176
pbrook2e70f6e2008-06-29 01:03:05 +00001177 return delta;
1178}
1179
Jan Kiszkaf64382b2009-09-15 13:36:04 +02001180#if defined(__linux__)
pbrook2e70f6e2008-06-29 01:03:05 +00001181static uint64_t qemu_next_deadline_dyntick(void)
1182{
1183 int64_t delta;
1184 int64_t rtdelta;
1185
1186 if (use_icount)
1187 delta = INT32_MAX;
1188 else
1189 delta = (qemu_next_deadline() + 999) / 1000;
1190
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001191 if (active_timers[QEMU_CLOCK_REALTIME]) {
1192 rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001193 qemu_get_clock(rt_clock))*1000;
1194 if (rtdelta < delta)
1195 delta = rtdelta;
1196 }
1197
1198 if (delta < MIN_TIMER_REARM_US)
1199 delta = MIN_TIMER_REARM_US;
1200
1201 return delta;
thsefe75412007-08-24 01:36:32 +00001202}
blueswir18632fb92008-09-14 13:59:34 +00001203#endif
thsefe75412007-08-24 01:36:32 +00001204
bellardfd872592004-05-12 19:11:15 +00001205#ifndef _WIN32
1206
aliguori7183b4b2008-11-05 20:40:18 +00001207/* Sets a specific flag */
1208static int fcntl_setfl(int fd, int flag)
1209{
1210 int flags;
1211
1212 flags = fcntl(fd, F_GETFL);
1213 if (flags == -1)
1214 return -errno;
1215
1216 if (fcntl(fd, F_SETFL, flags | flag) == -1)
1217 return -errno;
1218
1219 return 0;
1220}
1221
bellard829309c2004-05-20 13:20:12 +00001222#if defined(__linux__)
1223
bellardfd872592004-05-12 19:11:15 +00001224#define RTC_FREQ 1024
1225
aurel32de9a95f2008-11-11 13:41:01 +00001226static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001227{
thsc8994012007-08-19 21:56:03 +00001228 struct sigaction act;
1229
1230 /* timer signal */
1231 sigfillset(&act.sa_mask);
1232 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001233 act.sa_handler = host_alarm_handler;
1234
1235 sigaction(SIGIO, &act, NULL);
aliguori7183b4b2008-11-05 20:40:18 +00001236 fcntl_setfl(fd, O_ASYNC);
thsc8994012007-08-19 21:56:03 +00001237 fcntl(fd, F_SETOWN, getpid());
1238}
1239
thsc40ec5a2007-08-19 22:09:40 +00001240static int hpet_start_timer(struct qemu_alarm_timer *t)
1241{
1242 struct hpet_info info;
1243 int r, fd;
1244
1245 fd = open("/dev/hpet", O_RDONLY);
1246 if (fd < 0)
1247 return -1;
1248
1249 /* Set frequency */
1250 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1251 if (r < 0) {
1252 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1253 "error, but for better emulation accuracy type:\n"
1254 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1255 goto fail;
1256 }
1257
1258 /* Check capabilities */
1259 r = ioctl(fd, HPET_INFO, &info);
1260 if (r < 0)
1261 goto fail;
1262
1263 /* Enable periodic mode */
1264 r = ioctl(fd, HPET_EPI, 0);
1265 if (info.hi_flags && (r < 0))
1266 goto fail;
1267
1268 /* Enable interrupt */
1269 r = ioctl(fd, HPET_IE_ON, 0);
1270 if (r < 0)
1271 goto fail;
1272
1273 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001274 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001275
1276 return 0;
1277fail:
1278 close(fd);
1279 return -1;
1280}
1281
1282static void hpet_stop_timer(struct qemu_alarm_timer *t)
1283{
pbrookfcdc2122007-08-23 20:22:22 +00001284 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001285
1286 close(fd);
1287}
1288
thsc8994012007-08-19 21:56:03 +00001289static int rtc_start_timer(struct qemu_alarm_timer *t)
1290{
1291 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001292 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001293
balrogaeb30be2007-07-02 15:03:13 +00001294 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001295 if (rtc_fd < 0)
1296 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001297 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1298 if (current_rtc_freq != RTC_FREQ &&
1299 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001300 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1301 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1302 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1303 goto fail;
1304 }
1305 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1306 fail:
1307 close(rtc_fd);
1308 return -1;
1309 }
thsc8994012007-08-19 21:56:03 +00001310
1311 enable_sigio_timer(rtc_fd);
1312
pbrookfcdc2122007-08-23 20:22:22 +00001313 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001314
bellardfd872592004-05-12 19:11:15 +00001315 return 0;
1316}
1317
thsc8994012007-08-19 21:56:03 +00001318static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001319{
pbrookfcdc2122007-08-23 20:22:22 +00001320 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001321
1322 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001323}
1324
thsefe75412007-08-24 01:36:32 +00001325static int dynticks_start_timer(struct qemu_alarm_timer *t)
1326{
1327 struct sigevent ev;
1328 timer_t host_timer;
1329 struct sigaction act;
1330
1331 sigfillset(&act.sa_mask);
1332 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001333 act.sa_handler = host_alarm_handler;
1334
1335 sigaction(SIGALRM, &act, NULL);
1336
Jean-Christophe Dubois9ed415b2009-05-17 18:41:16 +02001337 /*
1338 * Initialize ev struct to 0 to avoid valgrind complaining
1339 * about uninitialized data in timer_create call
1340 */
1341 memset(&ev, 0, sizeof(ev));
thsefe75412007-08-24 01:36:32 +00001342 ev.sigev_value.sival_int = 0;
1343 ev.sigev_notify = SIGEV_SIGNAL;
1344 ev.sigev_signo = SIGALRM;
1345
1346 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1347 perror("timer_create");
1348
1349 /* disable dynticks */
1350 fprintf(stderr, "Dynamic Ticks disabled\n");
1351
1352 return -1;
1353 }
1354
blueswir10399bfe2008-11-16 11:37:18 +00001355 t->priv = (void *)(long)host_timer;
thsefe75412007-08-24 01:36:32 +00001356
1357 return 0;
1358}
1359
1360static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1361{
blueswir10399bfe2008-11-16 11:37:18 +00001362 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001363
1364 timer_delete(host_timer);
1365}
1366
1367static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1368{
blueswir10399bfe2008-11-16 11:37:18 +00001369 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001370 struct itimerspec timeout;
1371 int64_t nearest_delta_us = INT64_MAX;
1372 int64_t current_us;
1373
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001374 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001375 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1376 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001377 return;
thsefe75412007-08-24 01:36:32 +00001378
pbrook2e70f6e2008-06-29 01:03:05 +00001379 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001380
1381 /* check whether a timer is already running */
1382 if (timer_gettime(host_timer, &timeout)) {
1383 perror("gettime");
1384 fprintf(stderr, "Internal timer error: aborting\n");
1385 exit(1);
1386 }
1387 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1388 if (current_us && current_us <= nearest_delta_us)
1389 return;
1390
1391 timeout.it_interval.tv_sec = 0;
1392 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1393 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1394 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1395 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1396 perror("settime");
1397 fprintf(stderr, "Internal timer error: aborting\n");
1398 exit(1);
1399 }
1400}
1401
ths70744b32007-08-26 17:31:30 +00001402#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001403
thsc8994012007-08-19 21:56:03 +00001404static int unix_start_timer(struct qemu_alarm_timer *t)
1405{
1406 struct sigaction act;
1407 struct itimerval itv;
1408 int err;
1409
1410 /* timer signal */
1411 sigfillset(&act.sa_mask);
1412 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001413 act.sa_handler = host_alarm_handler;
1414
1415 sigaction(SIGALRM, &act, NULL);
1416
1417 itv.it_interval.tv_sec = 0;
1418 /* for i386 kernel 2.6 to get 1 ms */
1419 itv.it_interval.tv_usec = 999;
1420 itv.it_value.tv_sec = 0;
1421 itv.it_value.tv_usec = 10 * 1000;
1422
1423 err = setitimer(ITIMER_REAL, &itv, NULL);
1424 if (err)
1425 return -1;
1426
1427 return 0;
1428}
1429
1430static void unix_stop_timer(struct qemu_alarm_timer *t)
1431{
1432 struct itimerval itv;
1433
1434 memset(&itv, 0, sizeof(itv));
1435 setitimer(ITIMER_REAL, &itv, NULL);
1436}
1437
bellard829309c2004-05-20 13:20:12 +00001438#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001439
aliguorif49e58d2008-11-05 21:22:34 +00001440
thsc8994012007-08-19 21:56:03 +00001441#ifdef _WIN32
1442
1443static int win32_start_timer(struct qemu_alarm_timer *t)
1444{
1445 TIMECAPS tc;
1446 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001447 UINT flags;
thsc8994012007-08-19 21:56:03 +00001448
thsc8994012007-08-19 21:56:03 +00001449 memset(&tc, 0, sizeof(tc));
1450 timeGetDevCaps(&tc, sizeof(tc));
1451
1452 if (data->period < tc.wPeriodMin)
1453 data->period = tc.wPeriodMin;
1454
1455 timeBeginPeriod(data->period);
1456
thsefe75412007-08-24 01:36:32 +00001457 flags = TIME_CALLBACK_FUNCTION;
1458 if (alarm_has_dynticks(t))
1459 flags |= TIME_ONESHOT;
1460 else
1461 flags |= TIME_PERIODIC;
1462
thsc8994012007-08-19 21:56:03 +00001463 data->timerId = timeSetEvent(1, // interval (ms)
1464 data->period, // resolution
1465 host_alarm_handler, // function
1466 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001467 flags);
thsc8994012007-08-19 21:56:03 +00001468
1469 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001470 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
malc705e83f2009-09-27 14:30:33 +04001471 GetLastError());
thsc8994012007-08-19 21:56:03 +00001472 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001473 return -1;
1474 }
1475
thsc8994012007-08-19 21:56:03 +00001476 return 0;
1477}
1478
1479static void win32_stop_timer(struct qemu_alarm_timer *t)
1480{
1481 struct qemu_alarm_win32 *data = t->priv;
1482
1483 timeKillEvent(data->timerId);
1484 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001485}
1486
thsefe75412007-08-24 01:36:32 +00001487static void win32_rearm_timer(struct qemu_alarm_timer *t)
1488{
1489 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001490
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001491 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001492 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1493 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001494 return;
thsefe75412007-08-24 01:36:32 +00001495
thsefe75412007-08-24 01:36:32 +00001496 timeKillEvent(data->timerId);
1497
1498 data->timerId = timeSetEvent(1,
1499 data->period,
1500 host_alarm_handler,
1501 (DWORD)t,
1502 TIME_ONESHOT | TIME_PERIODIC);
1503
1504 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001505 fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
malc705e83f2009-09-27 14:30:33 +04001506 GetLastError());
thsefe75412007-08-24 01:36:32 +00001507
1508 timeEndPeriod(data->period);
thsefe75412007-08-24 01:36:32 +00001509 exit(1);
1510 }
1511}
1512
thsc8994012007-08-19 21:56:03 +00001513#endif /* _WIN32 */
1514
aliguori7183b4b2008-11-05 20:40:18 +00001515static int init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001516{
blueswir1223f0d72008-09-30 18:12:18 +00001517 struct qemu_alarm_timer *t = NULL;
thsc8994012007-08-19 21:56:03 +00001518 int i, err = -1;
aliguorif49e58d2008-11-05 21:22:34 +00001519
thsc8994012007-08-19 21:56:03 +00001520 for (i = 0; alarm_timers[i].name; i++) {
1521 t = &alarm_timers[i];
1522
thsc8994012007-08-19 21:56:03 +00001523 err = t->start(t);
1524 if (!err)
1525 break;
bellard67b915a2004-03-31 23:37:16 +00001526 }
bellardfd872592004-05-12 19:11:15 +00001527
thsc8994012007-08-19 21:56:03 +00001528 if (err) {
aliguori7183b4b2008-11-05 20:40:18 +00001529 err = -ENOENT;
1530 goto fail;
bellard67b915a2004-03-31 23:37:16 +00001531 }
thsc8994012007-08-19 21:56:03 +00001532
1533 alarm_timer = t;
aliguori7183b4b2008-11-05 20:40:18 +00001534
aliguori6abfbd72008-11-05 20:49:37 +00001535 return 0;
aliguori7183b4b2008-11-05 20:40:18 +00001536
1537fail:
aliguori7183b4b2008-11-05 20:40:18 +00001538 return err;
bellard8a7ddc32004-03-31 19:00:16 +00001539}
1540
pbrook9596ebb2007-11-18 01:44:38 +00001541static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001542{
thsc8994012007-08-19 21:56:03 +00001543 alarm_timer->stop(alarm_timer);
1544 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001545}
1546
bellardc4b1fcc2004-03-14 21:44:30 +00001547/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001548/* host time/date access */
1549void qemu_get_timedate(struct tm *tm, int offset)
1550{
1551 time_t ti;
1552 struct tm *ret;
1553
1554 time(&ti);
1555 ti += offset;
1556 if (rtc_date_offset == -1) {
1557 if (rtc_utc)
1558 ret = gmtime(&ti);
1559 else
1560 ret = localtime(&ti);
1561 } else {
1562 ti -= rtc_date_offset;
1563 ret = gmtime(&ti);
1564 }
1565
1566 memcpy(tm, ret, sizeof(struct tm));
1567}
1568
1569int qemu_timedate_diff(struct tm *tm)
1570{
1571 time_t seconds;
1572
1573 if (rtc_date_offset == -1)
1574 if (rtc_utc)
1575 seconds = mktimegm(tm);
1576 else
1577 seconds = mktime(tm);
1578 else
1579 seconds = mktimegm(tm) + rtc_date_offset;
1580
1581 return seconds - time(NULL);
1582}
1583
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02001584static void configure_rtc_date_offset(const char *startdate, int legacy)
1585{
1586 time_t rtc_start_date;
1587 struct tm tm;
1588
1589 if (!strcmp(startdate, "now") && legacy) {
1590 rtc_date_offset = -1;
1591 } else {
1592 if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
1593 &tm.tm_year,
1594 &tm.tm_mon,
1595 &tm.tm_mday,
1596 &tm.tm_hour,
1597 &tm.tm_min,
1598 &tm.tm_sec) == 6) {
1599 /* OK */
1600 } else if (sscanf(startdate, "%d-%d-%d",
1601 &tm.tm_year,
1602 &tm.tm_mon,
1603 &tm.tm_mday) == 3) {
1604 tm.tm_hour = 0;
1605 tm.tm_min = 0;
1606 tm.tm_sec = 0;
1607 } else {
1608 goto date_fail;
1609 }
1610 tm.tm_year -= 1900;
1611 tm.tm_mon--;
1612 rtc_start_date = mktimegm(&tm);
1613 if (rtc_start_date == -1) {
1614 date_fail:
1615 fprintf(stderr, "Invalid date format. Valid formats are:\n"
1616 "'2006-06-17T16:01:21' or '2006-06-17'\n");
1617 exit(1);
1618 }
1619 rtc_date_offset = time(NULL) - rtc_start_date;
1620 }
1621}
1622
1623static void configure_rtc(QemuOpts *opts)
1624{
1625 const char *value;
1626
1627 value = qemu_opt_get(opts, "base");
1628 if (value) {
1629 if (!strcmp(value, "utc")) {
1630 rtc_utc = 1;
1631 } else if (!strcmp(value, "localtime")) {
1632 rtc_utc = 0;
1633 } else {
1634 configure_rtc_date_offset(value, 0);
1635 }
1636 }
Jan Kiszka68752042009-09-15 13:36:04 +02001637 value = qemu_opt_get(opts, "clock");
1638 if (value) {
1639 if (!strcmp(value, "host")) {
1640 rtc_clock = host_clock;
1641 } else if (!strcmp(value, "vm")) {
1642 rtc_clock = vm_clock;
1643 } else {
1644 fprintf(stderr, "qemu: invalid option value '%s'\n", value);
1645 exit(1);
1646 }
1647 }
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02001648#ifdef CONFIG_TARGET_I386
1649 value = qemu_opt_get(opts, "driftfix");
1650 if (value) {
1651 if (!strcmp(buf, "slew")) {
1652 rtc_td_hack = 1;
1653 } else if (!strcmp(buf, "none")) {
1654 rtc_td_hack = 0;
1655 } else {
1656 fprintf(stderr, "qemu: invalid option value '%s'\n", value);
1657 exit(1);
1658 }
1659 }
1660#endif
1661}
1662
bellardfd1dff42006-02-01 21:29:26 +00001663#ifdef _WIN32
bellardfd1dff42006-02-01 21:29:26 +00001664static void socket_cleanup(void)
1665{
1666 WSACleanup();
1667}
bellard82c643f2004-07-14 17:28:13 +00001668
bellardfd1dff42006-02-01 21:29:26 +00001669static int socket_init(void)
1670{
1671 WSADATA Data;
1672 int ret, err;
1673
1674 ret = WSAStartup(MAKEWORD(2,2), &Data);
1675 if (ret != 0) {
1676 err = WSAGetLastError();
1677 fprintf(stderr, "WSAStartup: %d\n", err);
1678 return -1;
1679 }
1680 atexit(socket_cleanup);
1681 return 0;
1682}
aurel3264b7b732008-05-05 10:05:31 +00001683#endif
1684
balrog1ae26a12008-09-28 23:19:47 +00001685/***********************************************************/
1686/* Bluetooth support */
1687static int nb_hcis;
1688static int cur_hci;
1689static struct HCIInfo *hci_table[MAX_NICS];
balrogdc72ac12008-11-09 00:04:26 +00001690
balrog1ae26a12008-09-28 23:19:47 +00001691static struct bt_vlan_s {
1692 struct bt_scatternet_s net;
1693 int id;
1694 struct bt_vlan_s *next;
1695} *first_bt_vlan;
1696
1697/* find or alloc a new bluetooth "VLAN" */
blueswir1674bb262008-09-30 18:18:27 +00001698static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
balrog1ae26a12008-09-28 23:19:47 +00001699{
1700 struct bt_vlan_s **pvlan, *vlan;
1701 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
1702 if (vlan->id == id)
1703 return &vlan->net;
1704 }
1705 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
1706 vlan->id = id;
1707 pvlan = &first_bt_vlan;
1708 while (*pvlan != NULL)
1709 pvlan = &(*pvlan)->next;
1710 *pvlan = vlan;
1711 return &vlan->net;
1712}
1713
1714static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
1715{
1716}
1717
1718static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
1719{
1720 return -ENOTSUP;
1721}
1722
1723static struct HCIInfo null_hci = {
1724 .cmd_send = null_hci_send,
1725 .sco_send = null_hci_send,
1726 .acl_send = null_hci_send,
1727 .bdaddr_set = null_hci_addr_set,
1728};
1729
1730struct HCIInfo *qemu_next_hci(void)
1731{
1732 if (cur_hci == nb_hcis)
1733 return &null_hci;
1734
1735 return hci_table[cur_hci++];
1736}
1737
balrogdc72ac12008-11-09 00:04:26 +00001738static struct HCIInfo *hci_init(const char *str)
1739{
1740 char *endp;
1741 struct bt_scatternet_s *vlan = 0;
1742
1743 if (!strcmp(str, "null"))
1744 /* null */
1745 return &null_hci;
1746 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
1747 /* host[:hciN] */
1748 return bt_host_hci(str[4] ? str + 5 : "hci0");
1749 else if (!strncmp(str, "hci", 3)) {
1750 /* hci[,vlan=n] */
1751 if (str[3]) {
1752 if (!strncmp(str + 3, ",vlan=", 6)) {
1753 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
1754 if (*endp)
1755 vlan = 0;
1756 }
1757 } else
1758 vlan = qemu_find_bt_vlan(0);
1759 if (vlan)
1760 return bt_new_hci(vlan);
1761 }
1762
1763 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
1764
1765 return 0;
1766}
1767
1768static int bt_hci_parse(const char *str)
1769{
1770 struct HCIInfo *hci;
Anthony Liguoric227f092009-10-01 16:12:16 -05001771 bdaddr_t bdaddr;
balrogdc72ac12008-11-09 00:04:26 +00001772
1773 if (nb_hcis >= MAX_NICS) {
1774 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
1775 return -1;
1776 }
1777
1778 hci = hci_init(str);
1779 if (!hci)
1780 return -1;
1781
1782 bdaddr.b[0] = 0x52;
1783 bdaddr.b[1] = 0x54;
1784 bdaddr.b[2] = 0x00;
1785 bdaddr.b[3] = 0x12;
1786 bdaddr.b[4] = 0x34;
1787 bdaddr.b[5] = 0x56 + nb_hcis;
1788 hci->bdaddr_set(hci, bdaddr.b);
1789
1790 hci_table[nb_hcis++] = hci;
1791
1792 return 0;
1793}
1794
1795static void bt_vhci_add(int vlan_id)
1796{
1797 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
1798
1799 if (!vlan->slave)
1800 fprintf(stderr, "qemu: warning: adding a VHCI to "
1801 "an empty scatternet %i\n", vlan_id);
1802
1803 bt_vhci_init(bt_new_hci(vlan));
1804}
1805
1806static struct bt_device_s *bt_device_add(const char *opt)
1807{
1808 struct bt_scatternet_s *vlan;
1809 int vlan_id = 0;
1810 char *endp = strstr(opt, ",vlan=");
1811 int len = (endp ? endp - opt : strlen(opt)) + 1;
1812 char devname[10];
1813
1814 pstrcpy(devname, MIN(sizeof(devname), len), opt);
1815
1816 if (endp) {
1817 vlan_id = strtol(endp + 6, &endp, 0);
1818 if (*endp) {
1819 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
1820 return 0;
1821 }
1822 }
1823
1824 vlan = qemu_find_bt_vlan(vlan_id);
1825
1826 if (!vlan->slave)
1827 fprintf(stderr, "qemu: warning: adding a slave device to "
1828 "an empty scatternet %i\n", vlan_id);
1829
1830 if (!strcmp(devname, "keyboard"))
1831 return bt_keyboard_init(vlan);
1832
1833 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
1834 return 0;
1835}
1836
1837static int bt_parse(const char *opt)
1838{
1839 const char *endp, *p;
1840 int vlan;
1841
1842 if (strstart(opt, "hci", &endp)) {
1843 if (!*endp || *endp == ',') {
1844 if (*endp)
1845 if (!strstart(endp, ",vlan=", 0))
1846 opt = endp + 1;
1847
1848 return bt_hci_parse(opt);
1849 }
1850 } else if (strstart(opt, "vhci", &endp)) {
1851 if (!*endp || *endp == ',') {
1852 if (*endp) {
1853 if (strstart(endp, ",vlan=", &p)) {
1854 vlan = strtol(p, (char **) &endp, 0);
1855 if (*endp) {
1856 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
1857 return 1;
1858 }
1859 } else {
1860 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
1861 return 1;
1862 }
1863 } else
1864 vlan = 0;
1865
1866 bt_vhci_add(vlan);
1867 return 0;
1868 }
1869 } else if (strstart(opt, "device:", &endp))
1870 return !bt_device_add(endp);
1871
1872 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
1873 return 1;
1874}
1875
balrog1ae26a12008-09-28 23:19:47 +00001876/***********************************************************/
1877/* QEMU Block devices */
1878
balrog609497a2008-01-14 02:56:53 +00001879#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00001880#define CDROM_ALIAS "index=2,media=cdrom"
thse4bcb142007-12-02 04:51:10 +00001881#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00001882#define PFLASH_ALIAS "if=pflash"
1883#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00001884#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00001885
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001886QemuOpts *drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00001887{
1888 va_list ap;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001889 char optstr[1024];
1890 QemuOpts *opts;
thse4bcb142007-12-02 04:51:10 +00001891
thse4bcb142007-12-02 04:51:10 +00001892 va_start(ap, fmt);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001893 vsnprintf(optstr, sizeof(optstr), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00001894 va_end(ap);
1895
Gerd Hoffmann7282a032009-07-31 12:25:35 +02001896 opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001897 if (!opts) {
1898 fprintf(stderr, "%s: huh? duplicate? (%s)\n",
1899 __FUNCTION__, optstr);
1900 return NULL;
1901 }
1902 if (file)
1903 qemu_opt_set(opts, "file", file);
1904 return opts;
aliguorib01b1112009-02-11 15:20:20 +00001905}
1906
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001907DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00001908{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001909 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001910
1911 /* seek interface, bus and unit */
1912
Blue Swirl72cf2d42009-09-12 07:36:22 +00001913 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001914 if (dinfo->type == type &&
1915 dinfo->bus == bus &&
1916 dinfo->unit == unit)
1917 return dinfo;
1918 }
thse4bcb142007-12-02 04:51:10 +00001919
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001920 return NULL;
thse4bcb142007-12-02 04:51:10 +00001921}
1922
Gerd Hoffmann2e810b32009-07-31 12:25:38 +02001923DriveInfo *drive_get_by_id(const char *id)
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001924{
1925 DriveInfo *dinfo;
1926
Blue Swirl72cf2d42009-09-12 07:36:22 +00001927 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001928 if (strcmp(id, dinfo->id))
1929 continue;
1930 return dinfo;
1931 }
1932 return NULL;
1933}
1934
thsf60d39b2007-12-17 03:55:57 +00001935int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00001936{
1937 int max_bus;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001938 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001939
1940 max_bus = -1;
Blue Swirl72cf2d42009-09-12 07:36:22 +00001941 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001942 if(dinfo->type == type &&
1943 dinfo->bus > max_bus)
1944 max_bus = dinfo->bus;
thse4bcb142007-12-02 04:51:10 +00001945 }
1946 return max_bus;
1947}
1948
aliguorifa879c62009-01-07 17:32:33 +00001949const char *drive_get_serial(BlockDriverState *bdrv)
1950{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001951 DriveInfo *dinfo;
aliguorifa879c62009-01-07 17:32:33 +00001952
Blue Swirl72cf2d42009-09-12 07:36:22 +00001953 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001954 if (dinfo->bdrv == bdrv)
1955 return dinfo->serial;
1956 }
aliguorifa879c62009-01-07 17:32:33 +00001957
1958 return "\0";
1959}
1960
aliguori428c5702009-01-21 18:59:04 +00001961BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
1962{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001963 DriveInfo *dinfo;
aliguori428c5702009-01-21 18:59:04 +00001964
Blue Swirl72cf2d42009-09-12 07:36:22 +00001965 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001966 if (dinfo->bdrv == bdrv)
1967 return dinfo->onerror;
1968 }
aliguori428c5702009-01-21 18:59:04 +00001969
aliguoricdad4bd2009-02-28 16:51:01 +00001970 return BLOCK_ERR_STOP_ENOSPC;
aliguori428c5702009-01-21 18:59:04 +00001971}
1972
aurel32a1620fa2008-04-29 05:58:01 +00001973static void bdrv_format_print(void *opaque, const char *name)
1974{
1975 fprintf(stderr, " %s", name);
1976}
1977
Gerd Hoffmann56a14932009-09-25 21:42:46 +02001978void drive_uninit(DriveInfo *dinfo)
aliguorib01b1112009-02-11 15:20:20 +00001979{
Gerd Hoffmann56a14932009-09-25 21:42:46 +02001980 qemu_opts_del(dinfo->opts);
1981 bdrv_delete(dinfo->bdrv);
1982 QTAILQ_REMOVE(&drives, dinfo, next);
1983 qemu_free(dinfo);
aliguorib01b1112009-02-11 15:20:20 +00001984}
1985
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001986DriveInfo *drive_init(QemuOpts *opts, void *opaque,
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001987 int *fatal_error)
thse4bcb142007-12-02 04:51:10 +00001988{
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001989 const char *buf;
1990 const char *file = NULL;
balrogc8522bd2007-12-06 22:11:20 +00001991 char devname[128];
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001992 const char *serial;
balrogc8522bd2007-12-06 22:11:20 +00001993 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00001994 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00001995 enum { MEDIA_DISK, MEDIA_CDROM } media;
1996 int bus_id, unit_id;
1997 int cyls, heads, secs, translation;
aurel321e72d3b2008-04-28 20:26:45 +00001998 BlockDriver *drv = NULL;
aliguori4d73cd32009-02-11 15:20:46 +00001999 QEMUMachine *machine = opaque;
thse4bcb142007-12-02 04:51:10 +00002000 int max_devs;
2001 int index;
balrog33f00272007-12-24 14:33:24 +00002002 int cache;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002003 int aio = 0;
aliguori428c5702009-01-21 18:59:04 +00002004 int bdrv_flags, onerror;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002005 const char *devaddr;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002006 DriveInfo *dinfo;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002007 int snapshot = 0;
2008
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002009 *fatal_error = 1;
thse4bcb142007-12-02 04:51:10 +00002010
thse4bcb142007-12-02 04:51:10 +00002011 translation = BIOS_ATA_TRANSLATION_AUTO;
Kevin Wolf0aa217e2009-06-30 13:06:04 +02002012 cache = 1;
thse4bcb142007-12-02 04:51:10 +00002013
Gerd Hoffmann4d007812009-08-31 14:23:57 +02002014 if (machine && machine->use_scsi) {
thsf60d39b2007-12-17 03:55:57 +00002015 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002016 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002017 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00002018 } else {
thsf60d39b2007-12-17 03:55:57 +00002019 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002020 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002021 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00002022 }
2023 media = MEDIA_DISK;
2024
2025 /* extract parameters */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002026 bus_id = qemu_opt_get_number(opts, "bus", 0);
2027 unit_id = qemu_opt_get_number(opts, "unit", -1);
2028 index = qemu_opt_get_number(opts, "index", -1);
thse4bcb142007-12-02 04:51:10 +00002029
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002030 cyls = qemu_opt_get_number(opts, "cyls", 0);
2031 heads = qemu_opt_get_number(opts, "heads", 0);
2032 secs = qemu_opt_get_number(opts, "secs", 0);
thse4bcb142007-12-02 04:51:10 +00002033
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002034 snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
thse4bcb142007-12-02 04:51:10 +00002035
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002036 file = qemu_opt_get(opts, "file");
2037 serial = qemu_opt_get(opts, "serial");
2038
2039 if ((buf = qemu_opt_get(opts, "if")) != NULL) {
bellardae45d362008-06-11 09:44:44 +00002040 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00002041 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00002042 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002043 max_devs = MAX_IDE_DEVS;
2044 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00002045 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002046 max_devs = MAX_SCSI_DEVS;
2047 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00002048 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00002049 max_devs = 0;
2050 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00002051 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00002052 max_devs = 0;
2053 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00002054 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00002055 max_devs = 0;
2056 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00002057 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00002058 max_devs = 0;
aliguori6e02c382008-12-04 19:52:44 +00002059 } else if (!strcmp(buf, "virtio")) {
2060 type = IF_VIRTIO;
2061 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002062 } else if (!strcmp(buf, "xen")) {
2063 type = IF_XEN;
2064 max_devs = 0;
Gerd Hoffmanna8659e92009-07-31 12:25:39 +02002065 } else if (!strcmp(buf, "none")) {
2066 type = IF_NONE;
2067 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002068 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002069 fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002070 return NULL;
thse4bcb142007-12-02 04:51:10 +00002071 }
2072 }
2073
thse4bcb142007-12-02 04:51:10 +00002074 if (cyls || heads || secs) {
Blue Swirl5afe3f02009-10-17 09:08:47 +00002075 if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002076 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002077 return NULL;
thse4bcb142007-12-02 04:51:10 +00002078 }
Blue Swirl5afe3f02009-10-17 09:08:47 +00002079 if (heads < 1 || (type == IF_IDE && heads > 16)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002080 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002081 return NULL;
thse4bcb142007-12-02 04:51:10 +00002082 }
Blue Swirl5afe3f02009-10-17 09:08:47 +00002083 if (secs < 1 || (type == IF_IDE && secs > 63)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002084 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002085 return NULL;
thse4bcb142007-12-02 04:51:10 +00002086 }
2087 }
2088
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002089 if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002090 if (!cyls) {
2091 fprintf(stderr,
2092 "qemu: '%s' trans must be used with cyls,heads and secs\n",
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002093 buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002094 return NULL;
thse4bcb142007-12-02 04:51:10 +00002095 }
2096 if (!strcmp(buf, "none"))
2097 translation = BIOS_ATA_TRANSLATION_NONE;
2098 else if (!strcmp(buf, "lba"))
2099 translation = BIOS_ATA_TRANSLATION_LBA;
2100 else if (!strcmp(buf, "auto"))
2101 translation = BIOS_ATA_TRANSLATION_AUTO;
2102 else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002103 fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002104 return NULL;
thse4bcb142007-12-02 04:51:10 +00002105 }
2106 }
2107
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002108 if ((buf = qemu_opt_get(opts, "media")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002109 if (!strcmp(buf, "disk")) {
2110 media = MEDIA_DISK;
2111 } else if (!strcmp(buf, "cdrom")) {
2112 if (cyls || secs || heads) {
2113 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002114 "qemu: '%s' invalid physical CHS format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002115 return NULL;
thse4bcb142007-12-02 04:51:10 +00002116 }
2117 media = MEDIA_CDROM;
2118 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002119 fprintf(stderr, "qemu: '%s' invalid media\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002120 return NULL;
thse4bcb142007-12-02 04:51:10 +00002121 }
2122 }
2123
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002124 if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
aliguori9f7965c2008-10-14 14:42:54 +00002125 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
balrog33f00272007-12-24 14:33:24 +00002126 cache = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002127 else if (!strcmp(buf, "writethrough"))
balrog33f00272007-12-24 14:33:24 +00002128 cache = 1;
aliguori9f7965c2008-10-14 14:42:54 +00002129 else if (!strcmp(buf, "writeback"))
2130 cache = 2;
balrog33f00272007-12-24 14:33:24 +00002131 else {
2132 fprintf(stderr, "qemu: invalid cache option\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002133 return NULL;
balrog33f00272007-12-24 14:33:24 +00002134 }
2135 }
2136
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002137#ifdef CONFIG_LINUX_AIO
2138 if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
2139 if (!strcmp(buf, "threads"))
2140 aio = 0;
2141 else if (!strcmp(buf, "native"))
2142 aio = 1;
2143 else {
2144 fprintf(stderr, "qemu: invalid aio option\n");
2145 return NULL;
2146 }
2147 }
2148#endif
2149
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002150 if ((buf = qemu_opt_get(opts, "format")) != NULL) {
aurel32a1620fa2008-04-29 05:58:01 +00002151 if (strcmp(buf, "?") == 0) {
2152 fprintf(stderr, "qemu: Supported formats:");
2153 bdrv_iterate_format(bdrv_format_print, NULL);
2154 fprintf(stderr, "\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002155 return NULL;
aurel32a1620fa2008-04-29 05:58:01 +00002156 }
aurel321e72d3b2008-04-28 20:26:45 +00002157 drv = bdrv_find_format(buf);
2158 if (!drv) {
2159 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002160 return NULL;
aurel321e72d3b2008-04-28 20:26:45 +00002161 }
2162 }
2163
aliguoricdad4bd2009-02-28 16:51:01 +00002164 onerror = BLOCK_ERR_STOP_ENOSPC;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002165 if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
aliguori869a5c62009-01-22 19:52:25 +00002166 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
aliguoriea8a5d72009-01-22 19:52:21 +00002167 fprintf(stderr, "werror is no supported by this format\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002168 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002169 }
2170 if (!strcmp(buf, "ignore"))
2171 onerror = BLOCK_ERR_IGNORE;
2172 else if (!strcmp(buf, "enospc"))
2173 onerror = BLOCK_ERR_STOP_ENOSPC;
2174 else if (!strcmp(buf, "stop"))
2175 onerror = BLOCK_ERR_STOP_ANY;
2176 else if (!strcmp(buf, "report"))
2177 onerror = BLOCK_ERR_REPORT;
2178 else {
2179 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002180 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002181 }
2182 }
2183
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002184 if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002185 if (type != IF_VIRTIO) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002186 fprintf(stderr, "addr is not supported\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002187 return NULL;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002188 }
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002189 }
2190
thse4bcb142007-12-02 04:51:10 +00002191 /* compute bus and unit according index */
2192
2193 if (index != -1) {
2194 if (bus_id != 0 || unit_id != -1) {
2195 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002196 "qemu: index cannot be used with bus and unit\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002197 return NULL;
thse4bcb142007-12-02 04:51:10 +00002198 }
2199 if (max_devs == 0)
2200 {
2201 unit_id = index;
2202 bus_id = 0;
2203 } else {
2204 unit_id = index % max_devs;
2205 bus_id = index / max_devs;
2206 }
2207 }
2208
2209 /* if user doesn't specify a unit_id,
2210 * try to find the first free
2211 */
2212
2213 if (unit_id == -1) {
2214 unit_id = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002215 while (drive_get(type, bus_id, unit_id) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002216 unit_id++;
2217 if (max_devs && unit_id >= max_devs) {
2218 unit_id -= max_devs;
2219 bus_id++;
2220 }
2221 }
2222 }
2223
2224 /* check unit id */
2225
2226 if (max_devs && unit_id >= max_devs) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002227 fprintf(stderr, "qemu: unit %d too big (max is %d)\n",
2228 unit_id, max_devs - 1);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002229 return NULL;
thse4bcb142007-12-02 04:51:10 +00002230 }
2231
2232 /*
2233 * ignore multiple definitions
2234 */
2235
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002236 if (drive_get(type, bus_id, unit_id) != NULL) {
2237 *fatal_error = 0;
2238 return NULL;
2239 }
thse4bcb142007-12-02 04:51:10 +00002240
2241 /* init */
2242
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002243 dinfo = qemu_mallocz(sizeof(*dinfo));
Gerd Hoffmanne23d9c42009-07-31 12:25:34 +02002244 if ((buf = qemu_opts_id(opts)) != NULL) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002245 dinfo->id = qemu_strdup(buf);
2246 } else {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002247 /* no id supplied -> create one */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002248 dinfo->id = qemu_mallocz(32);
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002249 if (type == IF_IDE || type == IF_SCSI)
2250 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
2251 if (max_devs)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002252 snprintf(dinfo->id, 32, "%s%i%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002253 devname, bus_id, mediastr, unit_id);
2254 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002255 snprintf(dinfo->id, 32, "%s%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002256 devname, mediastr, unit_id);
2257 }
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002258 dinfo->bdrv = bdrv_new(dinfo->id);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002259 dinfo->devaddr = devaddr;
2260 dinfo->type = type;
2261 dinfo->bus = bus_id;
2262 dinfo->unit = unit_id;
2263 dinfo->onerror = onerror;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002264 dinfo->opts = opts;
2265 if (serial)
2266 strncpy(dinfo->serial, serial, sizeof(serial));
Blue Swirl72cf2d42009-09-12 07:36:22 +00002267 QTAILQ_INSERT_TAIL(&drives, dinfo, next);
thse4bcb142007-12-02 04:51:10 +00002268
thsf60d39b2007-12-17 03:55:57 +00002269 switch(type) {
thse4bcb142007-12-02 04:51:10 +00002270 case IF_IDE:
2271 case IF_SCSI:
aliguori62d23ef2009-04-22 15:19:30 +00002272 case IF_XEN:
Gerd Hoffmannc2193312009-09-15 19:23:28 +00002273 case IF_NONE:
thse4bcb142007-12-02 04:51:10 +00002274 switch(media) {
2275 case MEDIA_DISK:
2276 if (cyls != 0) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002277 bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
2278 bdrv_set_translation_hint(dinfo->bdrv, translation);
thse4bcb142007-12-02 04:51:10 +00002279 }
2280 break;
2281 case MEDIA_CDROM:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002282 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
thse4bcb142007-12-02 04:51:10 +00002283 break;
2284 }
2285 break;
2286 case IF_SD:
2287 /* FIXME: This isn't really a floppy, but it's a reasonable
2288 approximation. */
2289 case IF_FLOPPY:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002290 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
thse4bcb142007-12-02 04:51:10 +00002291 break;
2292 case IF_PFLASH:
2293 case IF_MTD:
2294 break;
Gerd Hoffmannd176c492009-07-31 12:25:41 +02002295 case IF_VIRTIO:
2296 /* add virtio block device */
2297 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
2298 qemu_opt_set(opts, "driver", "virtio-blk-pci");
2299 qemu_opt_set(opts, "drive", dinfo->id);
2300 if (devaddr)
2301 qemu_opt_set(opts, "addr", devaddr);
2302 break;
Paul Brookaae94602009-05-14 22:35:06 +01002303 case IF_COUNT:
2304 abort();
thse4bcb142007-12-02 04:51:10 +00002305 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002306 if (!file) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002307 *fatal_error = 0;
2308 return NULL;
2309 }
balrog33f00272007-12-24 14:33:24 +00002310 bdrv_flags = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002311 if (snapshot) {
balrog33f00272007-12-24 14:33:24 +00002312 bdrv_flags |= BDRV_O_SNAPSHOT;
aliguori9f7965c2008-10-14 14:42:54 +00002313 cache = 2; /* always use write-back with snapshot */
2314 }
2315 if (cache == 0) /* no caching */
2316 bdrv_flags |= BDRV_O_NOCACHE;
2317 else if (cache == 2) /* write-back */
2318 bdrv_flags |= BDRV_O_CACHE_WB;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002319
2320 if (aio == 1) {
2321 bdrv_flags |= BDRV_O_NATIVE_AIO;
2322 } else {
2323 bdrv_flags &= ~BDRV_O_NATIVE_AIO;
2324 }
2325
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002326 if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05002327 fprintf(stderr, "qemu: could not open disk image %s: %s\n",
2328 file, strerror(errno));
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002329 return NULL;
thse4bcb142007-12-02 04:51:10 +00002330 }
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002331
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002332 if (bdrv_key_required(dinfo->bdrv))
aliguoric0f4ce72009-03-05 23:01:01 +00002333 autostart = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002334 *fatal_error = 0;
2335 return dinfo;
thse4bcb142007-12-02 04:51:10 +00002336}
2337
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002338static int drive_init_func(QemuOpts *opts, void *opaque)
2339{
2340 QEMUMachine *machine = opaque;
2341 int fatal_error = 0;
2342
2343 if (drive_init(opts, machine, &fatal_error) == NULL) {
2344 if (fatal_error)
2345 return 1;
2346 }
2347 return 0;
2348}
2349
2350static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
2351{
2352 if (NULL == qemu_opt_get(opts, "snapshot")) {
2353 qemu_opt_set(opts, "snapshot", "on");
2354 }
2355 return 0;
2356}
2357
Jan Kiszka76e30d02009-07-02 00:19:02 +02002358void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
2359{
2360 boot_set_handler = func;
2361 boot_set_opaque = opaque;
2362}
2363
2364int qemu_boot_set(const char *boot_devices)
2365{
2366 if (!boot_set_handler) {
2367 return -EINVAL;
2368 }
2369 return boot_set_handler(boot_set_opaque, boot_devices);
2370}
2371
Jan Kiszkaef3adf62009-07-02 00:19:02 +02002372static int parse_bootdevices(char *devices)
2373{
2374 /* We just do some generic consistency checks */
2375 const char *p;
2376 int bitmap = 0;
2377
2378 for (p = devices; *p != '\0'; p++) {
2379 /* Allowed boot devices are:
2380 * a-b: floppy disk drives
2381 * c-f: IDE disk drives
2382 * g-m: machine implementation dependant drives
2383 * n-p: network devices
2384 * It's up to each machine implementation to check if the given boot
2385 * devices match the actual hardware implementation and firmware
2386 * features.
2387 */
2388 if (*p < 'a' || *p > 'p') {
2389 fprintf(stderr, "Invalid boot device '%c'\n", *p);
2390 exit(1);
2391 }
2392 if (bitmap & (1 << (*p - 'a'))) {
2393 fprintf(stderr, "Boot device '%c' was given twice\n", *p);
2394 exit(1);
2395 }
2396 bitmap |= 1 << (*p - 'a');
2397 }
2398 return bitmap;
2399}
2400
Jan Kiszkae0f084b2009-07-02 00:19:02 +02002401static void restore_boot_devices(void *opaque)
2402{
2403 char *standard_boot_devices = opaque;
2404
2405 qemu_boot_set(standard_boot_devices);
2406
2407 qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
2408 qemu_free(standard_boot_devices);
2409}
2410
aliguori268a3622009-04-21 22:30:27 +00002411static void numa_add(const char *optarg)
2412{
2413 char option[128];
2414 char *endptr;
2415 unsigned long long value, endvalue;
2416 int nodenr;
2417
2418 optarg = get_opt_name(option, 128, optarg, ',') + 1;
2419 if (!strcmp(option, "node")) {
2420 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
2421 nodenr = nb_numa_nodes;
2422 } else {
2423 nodenr = strtoull(option, NULL, 10);
2424 }
2425
2426 if (get_param_value(option, 128, "mem", optarg) == 0) {
2427 node_mem[nodenr] = 0;
2428 } else {
2429 value = strtoull(option, &endptr, 0);
2430 switch (*endptr) {
2431 case 0: case 'M': case 'm':
2432 value <<= 20;
2433 break;
2434 case 'G': case 'g':
2435 value <<= 30;
2436 break;
2437 }
2438 node_mem[nodenr] = value;
2439 }
2440 if (get_param_value(option, 128, "cpus", optarg) == 0) {
2441 node_cpumask[nodenr] = 0;
2442 } else {
2443 value = strtoull(option, &endptr, 10);
2444 if (value >= 64) {
2445 value = 63;
2446 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
2447 } else {
2448 if (*endptr == '-') {
2449 endvalue = strtoull(endptr+1, &endptr, 10);
2450 if (endvalue >= 63) {
2451 endvalue = 62;
2452 fprintf(stderr,
2453 "only 63 CPUs in NUMA mode supported.\n");
2454 }
2455 value = (1 << (endvalue + 1)) - (1 << value);
2456 } else {
2457 value = 1 << value;
2458 }
2459 }
2460 node_cpumask[nodenr] = value;
2461 }
2462 nb_numa_nodes++;
2463 }
2464 return;
2465}
2466
Andre Przywaradc6b1c02009-08-19 15:42:40 +02002467static void smp_parse(const char *optarg)
2468{
2469 int smp, sockets = 0, threads = 0, cores = 0;
2470 char *endptr;
2471 char option[128];
2472
2473 smp = strtoul(optarg, &endptr, 10);
2474 if (endptr != optarg) {
2475 if (*endptr == ',') {
2476 endptr++;
2477 }
2478 }
2479 if (get_param_value(option, 128, "sockets", endptr) != 0)
2480 sockets = strtoull(option, NULL, 10);
2481 if (get_param_value(option, 128, "cores", endptr) != 0)
2482 cores = strtoull(option, NULL, 10);
2483 if (get_param_value(option, 128, "threads", endptr) != 0)
2484 threads = strtoull(option, NULL, 10);
2485 if (get_param_value(option, 128, "maxcpus", endptr) != 0)
2486 max_cpus = strtoull(option, NULL, 10);
2487
2488 /* compute missing values, prefer sockets over cores over threads */
2489 if (smp == 0 || sockets == 0) {
2490 sockets = sockets > 0 ? sockets : 1;
2491 cores = cores > 0 ? cores : 1;
2492 threads = threads > 0 ? threads : 1;
2493 if (smp == 0) {
2494 smp = cores * threads * sockets;
2495 } else {
2496 sockets = smp / (cores * threads);
2497 }
2498 } else {
2499 if (cores == 0) {
2500 threads = threads > 0 ? threads : 1;
2501 cores = smp / (sockets * threads);
2502 } else {
2503 if (sockets == 0) {
2504 sockets = smp / (cores * threads);
2505 } else {
2506 threads = smp / (cores * sockets);
2507 }
2508 }
2509 }
2510 smp_cpus = smp;
2511 smp_cores = cores > 0 ? cores : 1;
2512 smp_threads = threads > 0 ? threads : 1;
2513 if (max_cpus == 0)
2514 max_cpus = smp_cpus;
2515}
2516
bellard330d0412003-07-26 18:11:40 +00002517/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00002518/* USB devices */
2519
aliguoribb5fc202009-03-05 23:01:15 +00002520static void usb_msd_password_cb(void *opaque, int err)
2521{
2522 USBDevice *dev = opaque;
2523
2524 if (!err)
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002525 usb_device_attach(dev);
aliguoribb5fc202009-03-05 23:01:15 +00002526 else
Gerd Hoffmann806b6022009-08-31 14:23:59 +02002527 dev->info->handle_destroy(dev);
aliguoribb5fc202009-03-05 23:01:15 +00002528}
2529
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002530static struct {
2531 const char *name;
2532 const char *qdev;
2533} usbdevs[] = {
2534 {
2535 .name = "mouse",
2536 .qdev = "QEMU USB Mouse",
2537 },{
2538 .name = "tablet",
2539 .qdev = "QEMU USB Tablet",
2540 },{
2541 .name = "keyboard",
2542 .qdev = "QEMU USB Keyboard",
2543 },{
2544 .name = "wacom-tablet",
2545 .qdev = "QEMU PenPartner Tablet",
2546 }
2547};
2548
aliguoric0f4ce72009-03-05 23:01:01 +00002549static int usb_device_add(const char *devname, int is_hotplug)
bellarda594cfb2005-11-06 16:13:29 +00002550{
2551 const char *p;
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002552 USBBus *bus = usb_bus_find(-1 /* any */);
2553 USBDevice *dev = NULL;
2554 int i;
bellarda594cfb2005-11-06 16:13:29 +00002555
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002556 if (!usb_enabled)
bellarda594cfb2005-11-06 16:13:29 +00002557 return -1;
2558
Gerd Hoffmann0958b4c2009-10-26 15:56:45 +01002559 /* drivers with .usbdevice_name entry in USBDeviceInfo */
2560 dev = usbdevice_create(devname);
2561 if (dev)
2562 goto done;
2563
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002564 /* simple devices which don't need extra care */
2565 for (i = 0; i < ARRAY_SIZE(usbdevs); i++) {
2566 if (strcmp(devname, usbdevs[i].name) != 0)
2567 continue;
2568 dev = usb_create_simple(bus, usbdevs[i].qdev);
2569 goto done;
2570 }
2571
2572 /* the other ones */
bellarda594cfb2005-11-06 16:13:29 +00002573 if (strstart(devname, "host:", &p)) {
2574 dev = usb_host_device_open(p);
pbrook2e5d83b2006-05-25 23:58:51 +00002575 } else if (strstart(devname, "disk:", &p)) {
aliguoric0f4ce72009-03-05 23:01:01 +00002576 BlockDriverState *bs;
2577
aliguoribb5fc202009-03-05 23:01:15 +00002578 dev = usb_msd_init(p);
aliguoric0f4ce72009-03-05 23:01:01 +00002579 if (!dev)
2580 return -1;
aliguoribb5fc202009-03-05 23:01:15 +00002581 bs = usb_msd_get_bdrv(dev);
aliguoric0f4ce72009-03-05 23:01:01 +00002582 if (bdrv_key_required(bs)) {
2583 autostart = 0;
aliguoribb5fc202009-03-05 23:01:15 +00002584 if (is_hotplug) {
aliguori376253e2009-03-05 23:01:23 +00002585 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
2586 dev);
aliguoribb5fc202009-03-05 23:01:15 +00002587 return 0;
aliguoric0f4ce72009-03-05 23:01:01 +00002588 }
2589 }
balroga7954212008-01-14 03:41:02 +00002590 } else if (strstart(devname, "serial:", &p)) {
2591 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00002592#ifdef CONFIG_BRLAPI
2593 } else if (!strcmp(devname, "braille")) {
2594 dev = usb_baum_init();
2595#endif
balrog6c9f8862008-07-17 20:47:13 +00002596 } else if (strstart(devname, "net:", &p)) {
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002597 QemuOpts *opts;
2598 int idx;
balrog6c9f8862008-07-17 20:47:13 +00002599
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002600 opts = qemu_opts_parse(&qemu_net_opts, p, NULL);
2601 if (!opts) {
balrog6c9f8862008-07-17 20:47:13 +00002602 return -1;
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002603 }
2604
2605 qemu_opt_set(opts, "type", "nic");
2606 qemu_opt_set(opts, "model", "usb");
2607
Mark McLoughlinf6b134a2009-10-08 19:58:27 +01002608 idx = net_client_init(NULL, opts, 0);
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002609 if (idx == -1) {
2610 return -1;
2611 }
2612
2613 dev = usb_net_init(&nd_table[idx]);
balrogdc72ac12008-11-09 00:04:26 +00002614 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
2615 dev = usb_bt_init(devname[2] ? hci_init(p) :
2616 bt_new_hci(qemu_find_bt_vlan(0)));
bellarda594cfb2005-11-06 16:13:29 +00002617 } else {
2618 return -1;
2619 }
pbrook0d92ed32006-05-21 16:30:15 +00002620 if (!dev)
2621 return -1;
2622
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002623done:
bellarda594cfb2005-11-06 16:13:29 +00002624 return 0;
2625}
2626
aliguori1f3870a2008-08-21 19:27:48 +00002627static int usb_device_del(const char *devname)
2628{
2629 int bus_num, addr;
2630 const char *p;
2631
aliguori5d0c5752008-09-14 01:07:41 +00002632 if (strstart(devname, "host:", &p))
2633 return usb_host_device_close(p);
2634
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002635 if (!usb_enabled)
aliguori1f3870a2008-08-21 19:27:48 +00002636 return -1;
2637
2638 p = strchr(devname, '.');
2639 if (!p)
2640 return -1;
2641 bus_num = strtoul(devname, NULL, 0);
2642 addr = strtoul(p + 1, NULL, 0);
2643
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002644 return usb_device_delete_addr(bus_num, addr);
aliguori1f3870a2008-08-21 19:27:48 +00002645}
2646
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02002647static int usb_parse(const char *cmdline)
2648{
2649 return usb_device_add(cmdline, 0);
2650}
2651
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002652void do_usb_add(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002653{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002654 usb_device_add(qdict_get_str(qdict, "devname"), 1);
bellarda594cfb2005-11-06 16:13:29 +00002655}
2656
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002657void do_usb_del(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002658{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002659 usb_device_del(qdict_get_str(qdict, "devname"));
bellarda594cfb2005-11-06 16:13:29 +00002660}
2661
bellardf7cce892004-12-08 22:21:25 +00002662/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00002663/* PCMCIA/Cardbus */
2664
2665static struct pcmcia_socket_entry_s {
Paul Brookbc24a222009-05-10 01:44:56 +01002666 PCMCIASocket *socket;
balrog201a51f2007-04-30 00:51:09 +00002667 struct pcmcia_socket_entry_s *next;
2668} *pcmcia_sockets = 0;
2669
Paul Brookbc24a222009-05-10 01:44:56 +01002670void pcmcia_socket_register(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002671{
2672 struct pcmcia_socket_entry_s *entry;
2673
2674 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
2675 entry->socket = socket;
2676 entry->next = pcmcia_sockets;
2677 pcmcia_sockets = entry;
2678}
2679
Paul Brookbc24a222009-05-10 01:44:56 +01002680void pcmcia_socket_unregister(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002681{
2682 struct pcmcia_socket_entry_s *entry, **ptr;
2683
2684 ptr = &pcmcia_sockets;
2685 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
2686 if (entry->socket == socket) {
2687 *ptr = entry->next;
2688 qemu_free(entry);
2689 }
2690}
2691
aliguori376253e2009-03-05 23:01:23 +00002692void pcmcia_info(Monitor *mon)
balrog201a51f2007-04-30 00:51:09 +00002693{
2694 struct pcmcia_socket_entry_s *iter;
aliguori376253e2009-03-05 23:01:23 +00002695
balrog201a51f2007-04-30 00:51:09 +00002696 if (!pcmcia_sockets)
aliguori376253e2009-03-05 23:01:23 +00002697 monitor_printf(mon, "No PCMCIA sockets\n");
balrog201a51f2007-04-30 00:51:09 +00002698
2699 for (iter = pcmcia_sockets; iter; iter = iter->next)
aliguori376253e2009-03-05 23:01:23 +00002700 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
2701 iter->socket->attached ? iter->socket->card_string :
2702 "Empty");
balrog201a51f2007-04-30 00:51:09 +00002703}
2704
2705/***********************************************************/
aliguori3023f332009-01-16 19:04:14 +00002706/* register display */
2707
aliguori7b5d76d2009-03-13 15:02:13 +00002708struct DisplayAllocator default_allocator = {
2709 defaultallocator_create_displaysurface,
2710 defaultallocator_resize_displaysurface,
2711 defaultallocator_free_displaysurface
2712};
2713
aliguori3023f332009-01-16 19:04:14 +00002714void register_displaystate(DisplayState *ds)
2715{
2716 DisplayState **s;
2717 s = &display_state;
2718 while (*s != NULL)
2719 s = &(*s)->next;
2720 ds->next = NULL;
2721 *s = ds;
2722}
2723
2724DisplayState *get_displaystate(void)
2725{
2726 return display_state;
2727}
2728
aliguori7b5d76d2009-03-13 15:02:13 +00002729DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
2730{
2731 if(ds->allocator == &default_allocator) ds->allocator = da;
2732 return ds->allocator;
2733}
2734
ths2ff89792007-06-21 23:34:19 +00002735/* dumb display */
2736
aliguori8f391ab2009-01-19 16:34:10 +00002737static void dumb_display_init(void)
ths2ff89792007-06-21 23:34:19 +00002738{
aliguori8f391ab2009-01-19 16:34:10 +00002739 DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
aliguori7b5d76d2009-03-13 15:02:13 +00002740 ds->allocator = &default_allocator;
2741 ds->surface = qemu_create_displaysurface(ds, 640, 480);
aliguori8f391ab2009-01-19 16:34:10 +00002742 register_displaystate(ds);
ths2ff89792007-06-21 23:34:19 +00002743}
2744
2745/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002746/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00002747
bellardc4b1fcc2004-03-14 21:44:30 +00002748typedef struct IOHandlerRecord {
2749 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00002750 IOCanRWHandler *fd_read_poll;
2751 IOHandler *fd_read;
2752 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00002753 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00002754 void *opaque;
2755 /* temporary data */
2756 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00002757 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00002758} IOHandlerRecord;
2759
bellard8a7ddc32004-03-31 19:00:16 +00002760static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00002761
bellard7c9d8e02005-11-15 22:16:05 +00002762/* XXX: fd_read_poll should be suppressed, but an API change is
2763 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00002764int qemu_set_fd_handler2(int fd,
2765 IOCanRWHandler *fd_read_poll,
2766 IOHandler *fd_read,
2767 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002768 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00002769{
bellard8a7ddc32004-03-31 19:00:16 +00002770 IOHandlerRecord **pioh, *ioh;
2771
bellard7c9d8e02005-11-15 22:16:05 +00002772 if (!fd_read && !fd_write) {
2773 pioh = &first_io_handler;
2774 for(;;) {
2775 ioh = *pioh;
2776 if (ioh == NULL)
2777 break;
2778 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00002779 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00002780 break;
2781 }
2782 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00002783 }
bellard7c9d8e02005-11-15 22:16:05 +00002784 } else {
2785 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2786 if (ioh->fd == fd)
2787 goto found;
2788 }
2789 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
bellard7c9d8e02005-11-15 22:16:05 +00002790 ioh->next = first_io_handler;
2791 first_io_handler = ioh;
2792 found:
2793 ioh->fd = fd;
2794 ioh->fd_read_poll = fd_read_poll;
2795 ioh->fd_read = fd_read;
2796 ioh->fd_write = fd_write;
2797 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00002798 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00002799 }
bellard7c9d8e02005-11-15 22:16:05 +00002800 return 0;
2801}
2802
ths5fafdf22007-09-16 21:08:06 +00002803int qemu_set_fd_handler(int fd,
2804 IOHandler *fd_read,
2805 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002806 void *opaque)
2807{
2808 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00002809}
2810
aliguori56f3a5d2008-10-31 18:07:17 +00002811#ifdef _WIN32
bellard8a7ddc32004-03-31 19:00:16 +00002812/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00002813/* Polling handling */
2814
2815typedef struct PollingEntry {
2816 PollingFunc *func;
2817 void *opaque;
2818 struct PollingEntry *next;
2819} PollingEntry;
2820
2821static PollingEntry *first_polling_entry;
2822
2823int qemu_add_polling_cb(PollingFunc *func, void *opaque)
2824{
2825 PollingEntry **ppe, *pe;
2826 pe = qemu_mallocz(sizeof(PollingEntry));
bellardf3311102006-04-12 20:21:17 +00002827 pe->func = func;
2828 pe->opaque = opaque;
2829 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
2830 *ppe = pe;
2831 return 0;
2832}
2833
2834void qemu_del_polling_cb(PollingFunc *func, void *opaque)
2835{
2836 PollingEntry **ppe, *pe;
2837 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
2838 pe = *ppe;
2839 if (pe->func == func && pe->opaque == opaque) {
2840 *ppe = pe->next;
2841 qemu_free(pe);
2842 break;
2843 }
2844 }
2845}
2846
bellarda18e5242006-06-25 17:18:27 +00002847/***********************************************************/
2848/* Wait objects support */
2849typedef struct WaitObjects {
2850 int num;
2851 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
2852 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
2853 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
2854} WaitObjects;
2855
2856static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00002857
bellarda18e5242006-06-25 17:18:27 +00002858int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2859{
2860 WaitObjects *w = &wait_objects;
2861
2862 if (w->num >= MAXIMUM_WAIT_OBJECTS)
2863 return -1;
2864 w->events[w->num] = handle;
2865 w->func[w->num] = func;
2866 w->opaque[w->num] = opaque;
2867 w->num++;
2868 return 0;
2869}
2870
2871void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2872{
2873 int i, found;
2874 WaitObjects *w = &wait_objects;
2875
2876 found = 0;
2877 for (i = 0; i < w->num; i++) {
2878 if (w->events[i] == handle)
2879 found = 1;
2880 if (found) {
2881 w->events[i] = w->events[i + 1];
2882 w->func[i] = w->func[i + 1];
2883 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00002884 }
bellarda18e5242006-06-25 17:18:27 +00002885 }
2886 if (found)
2887 w->num--;
2888}
2889#endif
2890
bellard8a7ddc32004-03-31 19:00:16 +00002891/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002892/* ram save/restore */
2893
Juan Quintela94fb0902009-09-10 03:04:23 +02002894#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
aliguori475e4272008-10-06 20:21:51 +00002895#define RAM_SAVE_FLAG_COMPRESS 0x02
2896#define RAM_SAVE_FLAG_MEM_SIZE 0x04
2897#define RAM_SAVE_FLAG_PAGE 0x08
2898#define RAM_SAVE_FLAG_EOS 0x10
2899
2900static int is_dup_page(uint8_t *page, uint8_t ch)
bellardc88676f2006-08-06 13:36:11 +00002901{
aliguori475e4272008-10-06 20:21:51 +00002902 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
2903 uint32_t *array = (uint32_t *)page;
2904 int i;
ths3b46e622007-09-17 08:09:54 +00002905
aliguori475e4272008-10-06 20:21:51 +00002906 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
2907 if (array[i] != val)
2908 return 0;
bellardc88676f2006-08-06 13:36:11 +00002909 }
aliguori475e4272008-10-06 20:21:51 +00002910
2911 return 1;
bellardc88676f2006-08-06 13:36:11 +00002912}
2913
aliguori475e4272008-10-06 20:21:51 +00002914static int ram_save_block(QEMUFile *f)
2915{
Anthony Liguoric227f092009-10-01 16:12:16 -05002916 static ram_addr_t current_addr = 0;
2917 ram_addr_t saved_addr = current_addr;
2918 ram_addr_t addr = 0;
aliguori475e4272008-10-06 20:21:51 +00002919 int found = 0;
2920
pbrook94a6b542009-04-11 17:15:54 +00002921 while (addr < last_ram_offset) {
aliguori475e4272008-10-06 20:21:51 +00002922 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
pbrook5579c7f2009-04-11 14:47:08 +00002923 uint8_t *p;
aliguori475e4272008-10-06 20:21:51 +00002924
2925 cpu_physical_memory_reset_dirty(current_addr,
2926 current_addr + TARGET_PAGE_SIZE,
2927 MIGRATION_DIRTY_FLAG);
2928
pbrook5579c7f2009-04-11 14:47:08 +00002929 p = qemu_get_ram_ptr(current_addr);
aliguori475e4272008-10-06 20:21:51 +00002930
pbrook5579c7f2009-04-11 14:47:08 +00002931 if (is_dup_page(p, *p)) {
aliguori475e4272008-10-06 20:21:51 +00002932 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
pbrook5579c7f2009-04-11 14:47:08 +00002933 qemu_put_byte(f, *p);
aliguori475e4272008-10-06 20:21:51 +00002934 } else {
2935 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
pbrook5579c7f2009-04-11 14:47:08 +00002936 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
aliguori475e4272008-10-06 20:21:51 +00002937 }
2938
2939 found = 1;
2940 break;
2941 }
2942 addr += TARGET_PAGE_SIZE;
pbrook94a6b542009-04-11 17:15:54 +00002943 current_addr = (saved_addr + addr) % last_ram_offset;
aliguori475e4272008-10-06 20:21:51 +00002944 }
2945
2946 return found;
2947}
2948
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002949static uint64_t bytes_transferred = 0;
aliguori475e4272008-10-06 20:21:51 +00002950
Anthony Liguoric227f092009-10-01 16:12:16 -05002951static ram_addr_t ram_save_remaining(void)
aliguori475e4272008-10-06 20:21:51 +00002952{
Anthony Liguoric227f092009-10-01 16:12:16 -05002953 ram_addr_t addr;
2954 ram_addr_t count = 0;
aliguori475e4272008-10-06 20:21:51 +00002955
pbrook94a6b542009-04-11 17:15:54 +00002956 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00002957 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2958 count++;
2959 }
2960
2961 return count;
2962}
2963
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002964uint64_t ram_bytes_remaining(void)
2965{
2966 return ram_save_remaining() * TARGET_PAGE_SIZE;
2967}
2968
2969uint64_t ram_bytes_transferred(void)
2970{
2971 return bytes_transferred;
2972}
2973
2974uint64_t ram_bytes_total(void)
2975{
2976 return last_ram_offset;
2977}
2978
aliguori475e4272008-10-06 20:21:51 +00002979static int ram_save_live(QEMUFile *f, int stage, void *opaque)
2980{
Anthony Liguoric227f092009-10-01 16:12:16 -05002981 ram_addr_t addr;
Glauber Costaa0a3fd62009-05-28 15:22:57 -04002982 uint64_t bytes_transferred_last;
2983 double bwidth = 0;
2984 uint64_t expected_time = 0;
aliguori475e4272008-10-06 20:21:51 +00002985
Jan Kiszka9fa06382009-05-22 23:51:45 +02002986 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
Jan Kiszkab0a46a32009-05-02 00:22:51 +02002987 qemu_file_set_error(f);
2988 return 0;
2989 }
2990
aliguori475e4272008-10-06 20:21:51 +00002991 if (stage == 1) {
2992 /* Make sure all dirty bits are set */
pbrook94a6b542009-04-11 17:15:54 +00002993 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00002994 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2995 cpu_physical_memory_set_dirty(addr);
2996 }
Jan Kiszkab0a46a32009-05-02 00:22:51 +02002997
aliguori475e4272008-10-06 20:21:51 +00002998 /* Enable dirty memory tracking */
2999 cpu_physical_memory_set_dirty_tracking(1);
3000
pbrook94a6b542009-04-11 17:15:54 +00003001 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
aliguori475e4272008-10-06 20:21:51 +00003002 }
3003
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003004 bytes_transferred_last = bytes_transferred;
3005 bwidth = get_clock();
3006
aliguori475e4272008-10-06 20:21:51 +00003007 while (!qemu_file_rate_limit(f)) {
3008 int ret;
3009
3010 ret = ram_save_block(f);
Glauber Costa9f9e28c2009-05-21 17:38:01 -04003011 bytes_transferred += ret * TARGET_PAGE_SIZE;
aliguori475e4272008-10-06 20:21:51 +00003012 if (ret == 0) /* no more blocks */
3013 break;
3014 }
3015
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003016 bwidth = get_clock() - bwidth;
3017 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
3018
3019 /* if we haven't transferred anything this round, force expected_time to a
3020 * a very high value, but without crashing */
3021 if (bwidth == 0)
3022 bwidth = 0.000001;
3023
aliguori475e4272008-10-06 20:21:51 +00003024 /* try transferring iterative blocks of memory */
3025
3026 if (stage == 3) {
aliguori475e4272008-10-06 20:21:51 +00003027
3028 /* flush all remaining blocks regardless of rate limiting */
Glauber Costa9f9e28c2009-05-21 17:38:01 -04003029 while (ram_save_block(f) != 0) {
3030 bytes_transferred += TARGET_PAGE_SIZE;
3031 }
aliguori8215e912009-04-05 19:30:55 +00003032 cpu_physical_memory_set_dirty_tracking(0);
aliguori475e4272008-10-06 20:21:51 +00003033 }
3034
3035 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
3036
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003037 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
3038
3039 return (stage == 2) && (expected_time <= migrate_max_downtime());
aliguori475e4272008-10-06 20:21:51 +00003040}
3041
aliguori475e4272008-10-06 20:21:51 +00003042static int ram_load(QEMUFile *f, void *opaque, int version_id)
3043{
Anthony Liguoric227f092009-10-01 16:12:16 -05003044 ram_addr_t addr;
aliguori475e4272008-10-06 20:21:51 +00003045 int flags;
3046
aliguori475e4272008-10-06 20:21:51 +00003047 if (version_id != 3)
3048 return -EINVAL;
3049
3050 do {
3051 addr = qemu_get_be64(f);
3052
3053 flags = addr & ~TARGET_PAGE_MASK;
3054 addr &= TARGET_PAGE_MASK;
3055
3056 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
pbrook94a6b542009-04-11 17:15:54 +00003057 if (addr != last_ram_offset)
aliguori475e4272008-10-06 20:21:51 +00003058 return -EINVAL;
3059 }
3060
aliguori475e4272008-10-06 20:21:51 +00003061 if (flags & RAM_SAVE_FLAG_COMPRESS) {
3062 uint8_t ch = qemu_get_byte(f);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003063 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
3064#ifndef _WIN32
Anthony Liguori30868442009-06-17 16:46:12 -05003065 if (ch == 0 &&
3066 (!kvm_enabled() || kvm_has_sync_mmu())) {
3067 madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003068 }
Anthony Liguori30868442009-06-17 16:46:12 -05003069#endif
aliguori475e4272008-10-06 20:21:51 +00003070 } else if (flags & RAM_SAVE_FLAG_PAGE)
pbrook5579c7f2009-04-11 14:47:08 +00003071 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
aliguori475e4272008-10-06 20:21:51 +00003072 } while (!(flags & RAM_SAVE_FLAG_EOS));
3073
bellardc88676f2006-08-06 13:36:11 +00003074 return 0;
3075}
3076
aliguori9e472e12008-10-08 19:50:24 +00003077void qemu_service_io(void)
3078{
aliguorid9f75a42009-04-24 18:03:11 +00003079 qemu_notify_event();
aliguori9e472e12008-10-08 19:50:24 +00003080}
3081
bellard8a7ddc32004-03-31 19:00:16 +00003082/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00003083/* machine registration */
3084
blueswir1bdaf78e2008-10-04 07:24:27 +00003085static QEMUMachine *first_machine = NULL;
aliguori6f338c32009-02-11 15:21:54 +00003086QEMUMachine *current_machine = NULL;
bellardcc1daa42005-06-05 14:49:17 +00003087
3088int qemu_register_machine(QEMUMachine *m)
3089{
3090 QEMUMachine **pm;
3091 pm = &first_machine;
3092 while (*pm != NULL)
3093 pm = &(*pm)->next;
3094 m->next = NULL;
3095 *pm = m;
3096 return 0;
3097}
3098
pbrook9596ebb2007-11-18 01:44:38 +00003099static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00003100{
3101 QEMUMachine *m;
3102
3103 for(m = first_machine; m != NULL; m = m->next) {
3104 if (!strcmp(m->name, name))
3105 return m;
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01003106 if (m->alias && !strcmp(m->alias, name))
3107 return m;
bellardcc1daa42005-06-05 14:49:17 +00003108 }
3109 return NULL;
3110}
3111
Anthony Liguori0c257432009-05-21 20:41:01 -05003112static QEMUMachine *find_default_machine(void)
3113{
3114 QEMUMachine *m;
3115
3116 for(m = first_machine; m != NULL; m = m->next) {
3117 if (m->is_default) {
3118 return m;
3119 }
3120 }
3121 return NULL;
3122}
3123
bellardcc1daa42005-06-05 14:49:17 +00003124/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00003125/* main execution loop */
3126
pbrook9596ebb2007-11-18 01:44:38 +00003127static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00003128{
aliguori7d957bd2009-01-15 22:14:11 +00003129 uint64_t interval = GUI_REFRESH_INTERVAL;
ths740733b2007-06-08 01:57:56 +00003130 DisplayState *ds = opaque;
aliguori7d957bd2009-01-15 22:14:11 +00003131 DisplayChangeListener *dcl = ds->listeners;
3132
3133 dpy_refresh(ds);
3134
3135 while (dcl != NULL) {
3136 if (dcl->gui_timer_interval &&
3137 dcl->gui_timer_interval < interval)
3138 interval = dcl->gui_timer_interval;
3139 dcl = dcl->next;
3140 }
3141 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00003142}
3143
blueswir19043b622009-01-21 19:28:13 +00003144static void nographic_update(void *opaque)
3145{
3146 uint64_t interval = GUI_REFRESH_INTERVAL;
3147
3148 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
3149}
3150
bellard0bd48852005-11-11 00:00:47 +00003151struct vm_change_state_entry {
3152 VMChangeStateHandler *cb;
3153 void *opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003154 QLIST_ENTRY (vm_change_state_entry) entries;
bellard0bd48852005-11-11 00:00:47 +00003155};
3156
Blue Swirl72cf2d42009-09-12 07:36:22 +00003157static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
bellard0bd48852005-11-11 00:00:47 +00003158
3159VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
3160 void *opaque)
3161{
3162 VMChangeStateEntry *e;
3163
3164 e = qemu_mallocz(sizeof (*e));
bellard0bd48852005-11-11 00:00:47 +00003165
3166 e->cb = cb;
3167 e->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003168 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
bellard0bd48852005-11-11 00:00:47 +00003169 return e;
3170}
3171
3172void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
3173{
Blue Swirl72cf2d42009-09-12 07:36:22 +00003174 QLIST_REMOVE (e, entries);
bellard0bd48852005-11-11 00:00:47 +00003175 qemu_free (e);
3176}
3177
aliguori9781e042009-01-22 17:15:29 +00003178static void vm_state_notify(int running, int reason)
bellard0bd48852005-11-11 00:00:47 +00003179{
3180 VMChangeStateEntry *e;
3181
3182 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
aliguori9781e042009-01-22 17:15:29 +00003183 e->cb(e->opaque, running, reason);
bellard0bd48852005-11-11 00:00:47 +00003184 }
3185}
3186
aliguorid6dc3d42009-04-24 18:04:07 +00003187static void resume_all_vcpus(void);
3188static void pause_all_vcpus(void);
3189
bellard8a7ddc32004-03-31 19:00:16 +00003190void vm_start(void)
3191{
3192 if (!vm_running) {
3193 cpu_enable_ticks();
3194 vm_running = 1;
aliguori9781e042009-01-22 17:15:29 +00003195 vm_state_notify(1, 0);
thsefe75412007-08-24 01:36:32 +00003196 qemu_rearm_alarm_timer(alarm_timer);
aliguorid6dc3d42009-04-24 18:04:07 +00003197 resume_all_vcpus();
bellard8a7ddc32004-03-31 19:00:16 +00003198 }
3199}
3200
bellardbb0c6722004-06-20 12:37:32 +00003201/* reset/shutdown handler */
3202
3203typedef struct QEMUResetEntry {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003204 QTAILQ_ENTRY(QEMUResetEntry) entry;
bellardbb0c6722004-06-20 12:37:32 +00003205 QEMUResetHandler *func;
3206 void *opaque;
bellardbb0c6722004-06-20 12:37:32 +00003207} QEMUResetEntry;
3208
Blue Swirl72cf2d42009-09-12 07:36:22 +00003209static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
3210 QTAILQ_HEAD_INITIALIZER(reset_handlers);
bellardbb0c6722004-06-20 12:37:32 +00003211static int reset_requested;
3212static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00003213static int powerdown_requested;
aliguorie5689022009-04-24 18:03:54 +00003214static int debug_requested;
aliguori6e29f5d2009-04-24 18:04:02 +00003215static int vmstop_requested;
bellardbb0c6722004-06-20 12:37:32 +00003216
aurel32cf7a2fe2008-03-18 06:53:05 +00003217int qemu_shutdown_requested(void)
3218{
3219 int r = shutdown_requested;
3220 shutdown_requested = 0;
3221 return r;
3222}
3223
3224int qemu_reset_requested(void)
3225{
3226 int r = reset_requested;
3227 reset_requested = 0;
3228 return r;
3229}
3230
3231int qemu_powerdown_requested(void)
3232{
3233 int r = powerdown_requested;
3234 powerdown_requested = 0;
3235 return r;
3236}
3237
aliguorie5689022009-04-24 18:03:54 +00003238static int qemu_debug_requested(void)
3239{
3240 int r = debug_requested;
3241 debug_requested = 0;
3242 return r;
3243}
3244
aliguori6e29f5d2009-04-24 18:04:02 +00003245static int qemu_vmstop_requested(void)
3246{
3247 int r = vmstop_requested;
3248 vmstop_requested = 0;
3249 return r;
3250}
3251
3252static void do_vm_stop(int reason)
3253{
3254 if (vm_running) {
3255 cpu_disable_ticks();
3256 vm_running = 0;
aliguorid6dc3d42009-04-24 18:04:07 +00003257 pause_all_vcpus();
aliguori6e29f5d2009-04-24 18:04:02 +00003258 vm_state_notify(0, reason);
3259 }
3260}
3261
Jan Kiszkaa08d4362009-06-27 09:25:07 +02003262void qemu_register_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003263{
Jan Kiszka55ddfe82009-07-02 00:19:02 +02003264 QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
bellardbb0c6722004-06-20 12:37:32 +00003265
bellardbb0c6722004-06-20 12:37:32 +00003266 re->func = func;
3267 re->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003268 QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
bellardbb0c6722004-06-20 12:37:32 +00003269}
3270
Jan Kiszkadda9b292009-07-02 00:19:02 +02003271void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003272{
3273 QEMUResetEntry *re;
3274
Blue Swirl72cf2d42009-09-12 07:36:22 +00003275 QTAILQ_FOREACH(re, &reset_handlers, entry) {
Jan Kiszkadda9b292009-07-02 00:19:02 +02003276 if (re->func == func && re->opaque == opaque) {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003277 QTAILQ_REMOVE(&reset_handlers, re, entry);
Jan Kiszkadda9b292009-07-02 00:19:02 +02003278 qemu_free(re);
3279 return;
3280 }
3281 }
3282}
3283
3284void qemu_system_reset(void)
3285{
3286 QEMUResetEntry *re, *nre;
3287
3288 /* reset all devices */
Blue Swirl72cf2d42009-09-12 07:36:22 +00003289 QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
bellardbb0c6722004-06-20 12:37:32 +00003290 re->func(re->opaque);
3291 }
3292}
3293
3294void qemu_system_reset_request(void)
3295{
bellardd1beab82006-10-02 19:44:22 +00003296 if (no_reboot) {
3297 shutdown_requested = 1;
3298 } else {
3299 reset_requested = 1;
3300 }
aliguorid9f75a42009-04-24 18:03:11 +00003301 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003302}
3303
3304void qemu_system_shutdown_request(void)
3305{
3306 shutdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003307 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003308}
3309
bellard34751872005-07-02 14:31:34 +00003310void qemu_system_powerdown_request(void)
3311{
3312 powerdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003313 qemu_notify_event();
3314}
3315
aliguorid6dc3d42009-04-24 18:04:07 +00003316#ifdef CONFIG_IOTHREAD
3317static void qemu_system_vmstop_request(int reason)
aliguorid9f75a42009-04-24 18:03:11 +00003318{
aliguorid6dc3d42009-04-24 18:04:07 +00003319 vmstop_requested = reason;
3320 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003321}
aliguorid6dc3d42009-04-24 18:04:07 +00003322#endif
bellardbb0c6722004-06-20 12:37:32 +00003323
aliguori50317c72009-04-24 18:03:29 +00003324#ifndef _WIN32
3325static int io_thread_fd = -1;
3326
3327static void qemu_event_increment(void)
3328{
3329 static const char byte = 0;
3330
3331 if (io_thread_fd == -1)
3332 return;
3333
3334 write(io_thread_fd, &byte, sizeof(byte));
3335}
3336
3337static void qemu_event_read(void *opaque)
3338{
3339 int fd = (unsigned long)opaque;
3340 ssize_t len;
3341
3342 /* Drain the notify pipe */
3343 do {
3344 char buffer[512];
3345 len = read(fd, buffer, sizeof(buffer));
3346 } while ((len == -1 && errno == EINTR) || len > 0);
3347}
3348
3349static int qemu_event_init(void)
3350{
3351 int err;
3352 int fds[2];
3353
3354 err = pipe(fds);
3355 if (err == -1)
3356 return -errno;
3357
3358 err = fcntl_setfl(fds[0], O_NONBLOCK);
3359 if (err < 0)
3360 goto fail;
3361
3362 err = fcntl_setfl(fds[1], O_NONBLOCK);
3363 if (err < 0)
3364 goto fail;
3365
3366 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
3367 (void *)(unsigned long)fds[0]);
3368
3369 io_thread_fd = fds[1];
Jan Kiszkaa7e21212009-04-29 18:38:28 +00003370 return 0;
3371
aliguori50317c72009-04-24 18:03:29 +00003372fail:
3373 close(fds[0]);
3374 close(fds[1]);
3375 return err;
3376}
3377#else
3378HANDLE qemu_event_handle;
3379
3380static void dummy_event_handler(void *opaque)
3381{
3382}
3383
3384static int qemu_event_init(void)
3385{
3386 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
3387 if (!qemu_event_handle) {
Blue Swirl20889d42009-09-27 20:03:56 +00003388 fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
aliguori50317c72009-04-24 18:03:29 +00003389 return -1;
3390 }
3391 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
3392 return 0;
3393}
3394
3395static void qemu_event_increment(void)
3396{
malcde1c90c2009-09-27 14:38:18 +04003397 if (!SetEvent(qemu_event_handle)) {
Blue Swirl20889d42009-09-27 20:03:56 +00003398 fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
malcde1c90c2009-09-27 14:38:18 +04003399 GetLastError());
3400 exit (1);
3401 }
aliguori50317c72009-04-24 18:03:29 +00003402}
3403#endif
3404
aliguorid6dc3d42009-04-24 18:04:07 +00003405static int cpu_can_run(CPUState *env)
3406{
3407 if (env->stop)
3408 return 0;
3409 if (env->stopped)
3410 return 0;
3411 return 1;
3412}
3413
3414#ifndef CONFIG_IOTHREAD
aliguori3fcf7b62009-04-24 18:03:25 +00003415static int qemu_init_main_loop(void)
3416{
aliguori50317c72009-04-24 18:03:29 +00003417 return qemu_event_init();
aliguori3fcf7b62009-04-24 18:03:25 +00003418}
3419
aliguori0bf46a42009-04-24 18:03:41 +00003420void qemu_init_vcpu(void *_env)
3421{
3422 CPUState *env = _env;
3423
3424 if (kvm_enabled())
3425 kvm_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003426 env->nr_cores = smp_cores;
3427 env->nr_threads = smp_threads;
aliguori0bf46a42009-04-24 18:03:41 +00003428 return;
3429}
3430
aliguori8edac962009-04-24 18:03:45 +00003431int qemu_cpu_self(void *env)
3432{
3433 return 1;
3434}
3435
aliguorid6dc3d42009-04-24 18:04:07 +00003436static void resume_all_vcpus(void)
3437{
3438}
3439
3440static void pause_all_vcpus(void)
3441{
3442}
3443
aliguori8edac962009-04-24 18:03:45 +00003444void qemu_cpu_kick(void *env)
3445{
3446 return;
3447}
3448
aliguorid6dc3d42009-04-24 18:04:07 +00003449void qemu_notify_event(void)
3450{
3451 CPUState *env = cpu_single_env;
3452
3453 if (env) {
3454 cpu_exit(env);
Anthony Liguori4a1418e2009-08-10 17:07:24 -05003455 }
aliguorid6dc3d42009-04-24 18:04:07 +00003456}
3457
Glauber Costad549db52009-10-07 16:38:03 -03003458void qemu_mutex_lock_iothread(void) {}
3459void qemu_mutex_unlock_iothread(void) {}
aliguori48708522009-04-24 18:03:49 +00003460
aliguori6e29f5d2009-04-24 18:04:02 +00003461void vm_stop(int reason)
3462{
3463 do_vm_stop(reason);
3464}
3465
aliguorid6dc3d42009-04-24 18:04:07 +00003466#else /* CONFIG_IOTHREAD */
3467
3468#include "qemu-thread.h"
3469
3470QemuMutex qemu_global_mutex;
3471static QemuMutex qemu_fair_mutex;
3472
3473static QemuThread io_thread;
3474
3475static QemuThread *tcg_cpu_thread;
3476static QemuCond *tcg_halt_cond;
3477
3478static int qemu_system_ready;
3479/* cpu creation */
3480static QemuCond qemu_cpu_cond;
3481/* system init */
3482static QemuCond qemu_system_cond;
3483static QemuCond qemu_pause_cond;
3484
3485static void block_io_signals(void);
3486static void unblock_io_signals(void);
3487static int tcg_has_work(void);
3488
3489static int qemu_init_main_loop(void)
3490{
3491 int ret;
3492
3493 ret = qemu_event_init();
3494 if (ret)
3495 return ret;
3496
3497 qemu_cond_init(&qemu_pause_cond);
3498 qemu_mutex_init(&qemu_fair_mutex);
3499 qemu_mutex_init(&qemu_global_mutex);
3500 qemu_mutex_lock(&qemu_global_mutex);
3501
3502 unblock_io_signals();
3503 qemu_thread_self(&io_thread);
3504
3505 return 0;
3506}
3507
3508static void qemu_wait_io_event(CPUState *env)
3509{
3510 while (!tcg_has_work())
3511 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
3512
3513 qemu_mutex_unlock(&qemu_global_mutex);
3514
3515 /*
3516 * Users of qemu_global_mutex can be starved, having no chance
3517 * to acquire it since this path will get to it first.
3518 * So use another lock to provide fairness.
3519 */
3520 qemu_mutex_lock(&qemu_fair_mutex);
3521 qemu_mutex_unlock(&qemu_fair_mutex);
3522
3523 qemu_mutex_lock(&qemu_global_mutex);
3524 if (env->stop) {
3525 env->stop = 0;
3526 env->stopped = 1;
3527 qemu_cond_signal(&qemu_pause_cond);
3528 }
3529}
3530
3531static int qemu_cpu_exec(CPUState *env);
3532
3533static void *kvm_cpu_thread_fn(void *arg)
3534{
3535 CPUState *env = arg;
3536
3537 block_io_signals();
3538 qemu_thread_self(env->thread);
Jean-Christophe DUBOIS321c1cb2009-09-02 23:59:04 +02003539 if (kvm_enabled())
3540 kvm_init_vcpu(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003541
3542 /* signal CPU creation */
3543 qemu_mutex_lock(&qemu_global_mutex);
3544 env->created = 1;
3545 qemu_cond_signal(&qemu_cpu_cond);
3546
3547 /* and wait for machine initialization */
3548 while (!qemu_system_ready)
3549 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3550
3551 while (1) {
3552 if (cpu_can_run(env))
3553 qemu_cpu_exec(env);
Anthony Liguori1c3173b2009-09-10 08:45:43 -05003554 qemu_wait_io_event(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003555 }
3556
3557 return NULL;
3558}
3559
3560static void tcg_cpu_exec(void);
3561
3562static void *tcg_cpu_thread_fn(void *arg)
3563{
3564 CPUState *env = arg;
3565
3566 block_io_signals();
3567 qemu_thread_self(env->thread);
3568
3569 /* signal CPU creation */
3570 qemu_mutex_lock(&qemu_global_mutex);
3571 for (env = first_cpu; env != NULL; env = env->next_cpu)
3572 env->created = 1;
3573 qemu_cond_signal(&qemu_cpu_cond);
3574
3575 /* and wait for machine initialization */
3576 while (!qemu_system_ready)
3577 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3578
3579 while (1) {
3580 tcg_cpu_exec();
3581 qemu_wait_io_event(cur_cpu);
3582 }
3583
3584 return NULL;
3585}
3586
3587void qemu_cpu_kick(void *_env)
3588{
3589 CPUState *env = _env;
3590 qemu_cond_broadcast(env->halt_cond);
3591 if (kvm_enabled())
3592 qemu_thread_signal(env->thread, SIGUSR1);
3593}
3594
Glauber Costae5bc2012009-09-28 15:27:44 -03003595int qemu_cpu_self(void *_env)
aliguorid6dc3d42009-04-24 18:04:07 +00003596{
Glauber Costae5bc2012009-09-28 15:27:44 -03003597 CPUState *env = _env;
3598 QemuThread this;
3599
3600 qemu_thread_self(&this);
3601
3602 return qemu_thread_equal(&this, env->thread);
aliguorid6dc3d42009-04-24 18:04:07 +00003603}
3604
3605static void cpu_signal(int sig)
3606{
3607 if (cpu_single_env)
3608 cpu_exit(cpu_single_env);
3609}
3610
3611static void block_io_signals(void)
3612{
3613 sigset_t set;
3614 struct sigaction sigact;
3615
3616 sigemptyset(&set);
3617 sigaddset(&set, SIGUSR2);
3618 sigaddset(&set, SIGIO);
3619 sigaddset(&set, SIGALRM);
3620 pthread_sigmask(SIG_BLOCK, &set, NULL);
3621
3622 sigemptyset(&set);
3623 sigaddset(&set, SIGUSR1);
3624 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3625
3626 memset(&sigact, 0, sizeof(sigact));
3627 sigact.sa_handler = cpu_signal;
3628 sigaction(SIGUSR1, &sigact, NULL);
3629}
3630
3631static void unblock_io_signals(void)
3632{
3633 sigset_t set;
3634
3635 sigemptyset(&set);
3636 sigaddset(&set, SIGUSR2);
3637 sigaddset(&set, SIGIO);
3638 sigaddset(&set, SIGALRM);
3639 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3640
3641 sigemptyset(&set);
3642 sigaddset(&set, SIGUSR1);
3643 pthread_sigmask(SIG_BLOCK, &set, NULL);
3644}
3645
3646static void qemu_signal_lock(unsigned int msecs)
3647{
3648 qemu_mutex_lock(&qemu_fair_mutex);
3649
3650 while (qemu_mutex_trylock(&qemu_global_mutex)) {
3651 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
3652 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
3653 break;
3654 }
3655 qemu_mutex_unlock(&qemu_fair_mutex);
3656}
3657
Glauber Costad549db52009-10-07 16:38:03 -03003658void qemu_mutex_lock_iothread(void)
aliguorid6dc3d42009-04-24 18:04:07 +00003659{
3660 if (kvm_enabled()) {
3661 qemu_mutex_lock(&qemu_fair_mutex);
3662 qemu_mutex_lock(&qemu_global_mutex);
3663 qemu_mutex_unlock(&qemu_fair_mutex);
3664 } else
3665 qemu_signal_lock(100);
3666}
3667
Glauber Costad549db52009-10-07 16:38:03 -03003668void qemu_mutex_unlock_iothread(void)
aliguorid6dc3d42009-04-24 18:04:07 +00003669{
3670 qemu_mutex_unlock(&qemu_global_mutex);
3671}
3672
3673static int all_vcpus_paused(void)
3674{
3675 CPUState *penv = first_cpu;
3676
3677 while (penv) {
3678 if (!penv->stopped)
3679 return 0;
3680 penv = (CPUState *)penv->next_cpu;
3681 }
3682
3683 return 1;
3684}
3685
3686static void pause_all_vcpus(void)
3687{
3688 CPUState *penv = first_cpu;
3689
3690 while (penv) {
3691 penv->stop = 1;
3692 qemu_thread_signal(penv->thread, SIGUSR1);
3693 qemu_cpu_kick(penv);
3694 penv = (CPUState *)penv->next_cpu;
3695 }
3696
3697 while (!all_vcpus_paused()) {
3698 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
3699 penv = first_cpu;
3700 while (penv) {
3701 qemu_thread_signal(penv->thread, SIGUSR1);
3702 penv = (CPUState *)penv->next_cpu;
3703 }
3704 }
3705}
3706
3707static void resume_all_vcpus(void)
3708{
3709 CPUState *penv = first_cpu;
3710
3711 while (penv) {
3712 penv->stop = 0;
3713 penv->stopped = 0;
3714 qemu_thread_signal(penv->thread, SIGUSR1);
3715 qemu_cpu_kick(penv);
3716 penv = (CPUState *)penv->next_cpu;
3717 }
3718}
3719
3720static void tcg_init_vcpu(void *_env)
3721{
3722 CPUState *env = _env;
3723 /* share a single thread for all cpus with TCG */
3724 if (!tcg_cpu_thread) {
3725 env->thread = qemu_mallocz(sizeof(QemuThread));
3726 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3727 qemu_cond_init(env->halt_cond);
3728 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
3729 while (env->created == 0)
3730 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3731 tcg_cpu_thread = env->thread;
3732 tcg_halt_cond = env->halt_cond;
3733 } else {
3734 env->thread = tcg_cpu_thread;
3735 env->halt_cond = tcg_halt_cond;
3736 }
3737}
3738
3739static void kvm_start_vcpu(CPUState *env)
3740{
aliguorid6dc3d42009-04-24 18:04:07 +00003741 env->thread = qemu_mallocz(sizeof(QemuThread));
3742 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3743 qemu_cond_init(env->halt_cond);
3744 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
3745 while (env->created == 0)
3746 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3747}
3748
3749void qemu_init_vcpu(void *_env)
3750{
3751 CPUState *env = _env;
3752
3753 if (kvm_enabled())
3754 kvm_start_vcpu(env);
3755 else
3756 tcg_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003757 env->nr_cores = smp_cores;
3758 env->nr_threads = smp_threads;
aliguorid6dc3d42009-04-24 18:04:07 +00003759}
3760
3761void qemu_notify_event(void)
3762{
3763 qemu_event_increment();
3764}
3765
3766void vm_stop(int reason)
3767{
3768 QemuThread me;
3769 qemu_thread_self(&me);
3770
3771 if (!qemu_thread_equal(&me, &io_thread)) {
3772 qemu_system_vmstop_request(reason);
3773 /*
3774 * FIXME: should not return to device code in case
3775 * vm_stop() has been requested.
3776 */
3777 if (cpu_single_env) {
3778 cpu_exit(cpu_single_env);
3779 cpu_single_env->stop = 1;
3780 }
3781 return;
3782 }
3783 do_vm_stop(reason);
3784}
3785
3786#endif
3787
3788
ths877cf882007-04-18 18:11:47 +00003789#ifdef _WIN32
blueswir169d64512008-12-07 19:30:18 +00003790static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003791{
3792 int ret, ret2, i;
bellardf3311102006-04-12 20:21:17 +00003793 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00003794
bellardf3311102006-04-12 20:21:17 +00003795
3796 /* XXX: need to suppress polling by better using win32 events */
3797 ret = 0;
3798 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
3799 ret |= pe->func(pe->opaque);
3800 }
thse6b1e552007-04-18 17:56:02 +00003801 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00003802 int err;
3803 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00003804
aliguori56f3a5d2008-10-31 18:07:17 +00003805 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
bellarda18e5242006-06-25 17:18:27 +00003806 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
3807 if (w->func[ret - WAIT_OBJECT_0])
3808 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00003809
ths5fafdf22007-09-16 21:08:06 +00003810 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00003811 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00003812
thse6b1e552007-04-18 17:56:02 +00003813 /* Check if event is signaled */
3814 ret2 = WaitForSingleObject(w->events[i], 0);
3815 if(ret2 == WAIT_OBJECT_0) {
3816 if (w->func[i])
3817 w->func[i](w->opaque[i]);
3818 } else if (ret2 == WAIT_TIMEOUT) {
3819 } else {
3820 err = GetLastError();
3821 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00003822 }
3823 }
bellarda18e5242006-06-25 17:18:27 +00003824 } else if (ret == WAIT_TIMEOUT) {
3825 } else {
3826 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00003827 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00003828 }
bellardf3311102006-04-12 20:21:17 +00003829 }
aliguori56f3a5d2008-10-31 18:07:17 +00003830
3831 *timeout = 0;
3832}
3833#else
blueswir169d64512008-12-07 19:30:18 +00003834static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003835{
3836}
bellardfd1dff42006-02-01 21:29:26 +00003837#endif
aliguori56f3a5d2008-10-31 18:07:17 +00003838
3839void main_loop_wait(int timeout)
3840{
3841 IOHandlerRecord *ioh;
3842 fd_set rfds, wfds, xfds;
3843 int ret, nfds;
3844 struct timeval tv;
3845
3846 qemu_bh_update_timeout(&timeout);
3847
3848 host_main_loop_wait(&timeout);
3849
bellardfd1dff42006-02-01 21:29:26 +00003850 /* poll any events */
3851 /* XXX: separate device handlers from system ones */
aliguori6abfbd72008-11-05 20:49:37 +00003852 nfds = -1;
bellardfd1dff42006-02-01 21:29:26 +00003853 FD_ZERO(&rfds);
3854 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00003855 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00003856 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00003857 if (ioh->deleted)
3858 continue;
bellardfd1dff42006-02-01 21:29:26 +00003859 if (ioh->fd_read &&
3860 (!ioh->fd_read_poll ||
3861 ioh->fd_read_poll(ioh->opaque) != 0)) {
3862 FD_SET(ioh->fd, &rfds);
3863 if (ioh->fd > nfds)
3864 nfds = ioh->fd;
3865 }
3866 if (ioh->fd_write) {
3867 FD_SET(ioh->fd, &wfds);
3868 if (ioh->fd > nfds)
3869 nfds = ioh->fd;
3870 }
3871 }
ths3b46e622007-09-17 08:09:54 +00003872
aliguori56f3a5d2008-10-31 18:07:17 +00003873 tv.tv_sec = timeout / 1000;
3874 tv.tv_usec = (timeout % 1000) * 1000;
3875
Jan Kiszkad918f232009-06-24 14:42:30 +02003876 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
3877
aliguori48708522009-04-24 18:03:49 +00003878 qemu_mutex_unlock_iothread();
bellarde0356492006-05-01 13:33:02 +00003879 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
aliguori48708522009-04-24 18:03:49 +00003880 qemu_mutex_lock_iothread();
bellardfd1dff42006-02-01 21:29:26 +00003881 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00003882 IOHandlerRecord **pioh;
3883
3884 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00003885 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003886 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00003887 }
ths6ab43fd2007-08-25 01:34:19 +00003888 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003889 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00003890 }
3891 }
thscafffd42007-02-28 21:59:44 +00003892
3893 /* remove deleted IO handlers */
3894 pioh = &first_io_handler;
3895 while (*pioh) {
3896 ioh = *pioh;
3897 if (ioh->deleted) {
3898 *pioh = ioh->next;
3899 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00003900 } else
thscafffd42007-02-28 21:59:44 +00003901 pioh = &ioh->next;
3902 }
bellardfd1dff42006-02-01 21:29:26 +00003903 }
Jan Kiszkad918f232009-06-24 14:42:30 +02003904
3905 slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
bellardc20709a2004-04-21 23:27:19 +00003906
aliguori50317c72009-04-24 18:03:29 +00003907 /* rearm timer, if not periodic */
3908 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
3909 alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
3910 qemu_rearm_alarm_timer(alarm_timer);
3911 }
3912
aliguori357c6922008-11-25 17:26:09 +00003913 /* vm time timers */
aliguorid6dc3d42009-04-24 18:04:07 +00003914 if (vm_running) {
3915 if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
Jan Kiszka0fdddf82009-09-15 13:36:04 +02003916 qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
3917 qemu_get_clock(vm_clock));
aliguorid6dc3d42009-04-24 18:04:07 +00003918 }
aliguori357c6922008-11-25 17:26:09 +00003919
3920 /* real time timers */
Jan Kiszka0fdddf82009-09-15 13:36:04 +02003921 qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
aliguori357c6922008-11-25 17:26:09 +00003922 qemu_get_clock(rt_clock));
3923
Jan Kiszka21d5d122009-09-15 13:36:04 +02003924 qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
3925 qemu_get_clock(host_clock));
3926
pbrook423f0742007-05-23 00:06:54 +00003927 /* Check bottom-halves last in case any of the earlier events triggered
3928 them. */
3929 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00003930
bellard5905b2e2004-08-01 21:53:26 +00003931}
3932
aliguori43b96852009-04-24 18:03:33 +00003933static int qemu_cpu_exec(CPUState *env)
bellard5905b2e2004-08-01 21:53:26 +00003934{
aliguori43b96852009-04-24 18:03:33 +00003935 int ret;
bellard89bfc102006-02-08 22:46:31 +00003936#ifdef CONFIG_PROFILER
3937 int64_t ti;
3938#endif
aliguori43b96852009-04-24 18:03:33 +00003939
3940#ifdef CONFIG_PROFILER
3941 ti = profile_getclock();
3942#endif
3943 if (use_icount) {
3944 int64_t count;
3945 int decr;
3946 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3947 env->icount_decr.u16.low = 0;
3948 env->icount_extra = 0;
3949 count = qemu_next_deadline();
3950 count = (count + (1 << icount_time_shift) - 1)
3951 >> icount_time_shift;
3952 qemu_icount += count;
3953 decr = (count > 0xffff) ? 0xffff : count;
3954 count -= decr;
3955 env->icount_decr.u16.low = decr;
3956 env->icount_extra = count;
3957 }
3958 ret = cpu_exec(env);
3959#ifdef CONFIG_PROFILER
3960 qemu_time += profile_getclock() - ti;
3961#endif
3962 if (use_icount) {
3963 /* Fold pending instructions back into the
3964 instruction counter, and clear the interrupt flag. */
3965 qemu_icount -= (env->icount_decr.u16.low
3966 + env->icount_extra);
3967 env->icount_decr.u32 = 0;
3968 env->icount_extra = 0;
3969 }
3970 return ret;
3971}
3972
aliguorie6e35b12009-04-24 18:03:57 +00003973static void tcg_cpu_exec(void)
3974{
aliguorid6dc3d42009-04-24 18:04:07 +00003975 int ret = 0;
aliguorie6e35b12009-04-24 18:03:57 +00003976
3977 if (next_cpu == NULL)
3978 next_cpu = first_cpu;
3979 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
3980 CPUState *env = cur_cpu = next_cpu;
3981
3982 if (!vm_running)
3983 break;
3984 if (timer_alarm_pending) {
3985 timer_alarm_pending = 0;
3986 break;
3987 }
aliguorid6dc3d42009-04-24 18:04:07 +00003988 if (cpu_can_run(env))
3989 ret = qemu_cpu_exec(env);
aliguorie6e35b12009-04-24 18:03:57 +00003990 if (ret == EXCP_DEBUG) {
3991 gdb_set_stop_cpu(env);
3992 debug_requested = 1;
3993 break;
3994 }
3995 }
3996}
3997
aliguori43b96852009-04-24 18:03:33 +00003998static int cpu_has_work(CPUState *env)
3999{
aliguorid6dc3d42009-04-24 18:04:07 +00004000 if (env->stop)
4001 return 1;
4002 if (env->stopped)
4003 return 0;
aliguori43b96852009-04-24 18:03:33 +00004004 if (!env->halted)
4005 return 1;
4006 if (qemu_cpu_has_work(env))
4007 return 1;
4008 return 0;
4009}
4010
4011static int tcg_has_work(void)
4012{
bellard6a00d602005-11-21 23:25:50 +00004013 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00004014
aliguori43b96852009-04-24 18:03:33 +00004015 for (env = first_cpu; env != NULL; env = env->next_cpu)
4016 if (cpu_has_work(env))
4017 return 1;
4018 return 0;
4019}
bellard15a76442005-11-23 21:01:03 +00004020
aliguori43b96852009-04-24 18:03:33 +00004021static int qemu_calculate_timeout(void)
4022{
Luiz Capitulinob3198202009-06-09 18:24:57 -03004023#ifndef CONFIG_IOTHREAD
aliguori43b96852009-04-24 18:03:33 +00004024 int timeout;
bellard15a76442005-11-23 21:01:03 +00004025
aliguori43b96852009-04-24 18:03:33 +00004026 if (!vm_running)
4027 timeout = 5000;
4028 else if (tcg_has_work())
4029 timeout = 0;
4030 else if (!use_icount)
4031 timeout = 5000;
4032 else {
4033 /* XXX: use timeout computed from timers */
4034 int64_t add;
4035 int64_t delta;
4036 /* Advance virtual time to the next event. */
4037 if (use_icount == 1) {
4038 /* When not using an adaptive execution frequency
4039 we tend to get badly out of sync with real time,
4040 so just delay for a reasonable amount of time. */
4041 delta = 0;
bellard5905b2e2004-08-01 21:53:26 +00004042 } else {
aliguori43b96852009-04-24 18:03:33 +00004043 delta = cpu_get_icount() - cpu_get_clock();
bellard5905b2e2004-08-01 21:53:26 +00004044 }
aliguori43b96852009-04-24 18:03:33 +00004045 if (delta > 0) {
4046 /* If virtual time is ahead of real time then just
4047 wait for IO. */
4048 timeout = (delta / 1000000) + 1;
4049 } else {
4050 /* Wait for either IO to occur or the next
4051 timer event. */
4052 add = qemu_next_deadline();
4053 /* We advance the timer before checking for IO.
4054 Limit the amount we advance so that early IO
4055 activity won't get the guest too far ahead. */
4056 if (add > 10000000)
4057 add = 10000000;
4058 delta += add;
4059 add = (add + (1 << icount_time_shift) - 1)
4060 >> icount_time_shift;
4061 qemu_icount += add;
4062 timeout = delta / 1000000;
4063 if (timeout < 0)
4064 timeout = 0;
4065 }
bellardb4608c02003-06-27 17:34:32 +00004066 }
aliguori43b96852009-04-24 18:03:33 +00004067
4068 return timeout;
Luiz Capitulinob3198202009-06-09 18:24:57 -03004069#else /* CONFIG_IOTHREAD */
4070 return 1000;
4071#endif
aliguori43b96852009-04-24 18:03:33 +00004072}
4073
4074static int vm_can_run(void)
4075{
4076 if (powerdown_requested)
4077 return 0;
4078 if (reset_requested)
4079 return 0;
4080 if (shutdown_requested)
4081 return 0;
aliguorie5689022009-04-24 18:03:54 +00004082 if (debug_requested)
4083 return 0;
aliguori43b96852009-04-24 18:03:33 +00004084 return 1;
4085}
4086
Blue Swirld9c32312009-08-09 08:42:19 +00004087qemu_irq qemu_system_powerdown;
4088
aliguori43b96852009-04-24 18:03:33 +00004089static void main_loop(void)
4090{
aliguori6e29f5d2009-04-24 18:04:02 +00004091 int r;
aliguori43b96852009-04-24 18:03:33 +00004092
aliguorid6dc3d42009-04-24 18:04:07 +00004093#ifdef CONFIG_IOTHREAD
4094 qemu_system_ready = 1;
4095 qemu_cond_broadcast(&qemu_system_cond);
4096#endif
4097
aliguori6e29f5d2009-04-24 18:04:02 +00004098 for (;;) {
aliguorie6e35b12009-04-24 18:03:57 +00004099 do {
4100#ifdef CONFIG_PROFILER
4101 int64_t ti;
4102#endif
aliguorid6dc3d42009-04-24 18:04:07 +00004103#ifndef CONFIG_IOTHREAD
aliguorie6e35b12009-04-24 18:03:57 +00004104 tcg_cpu_exec();
aliguorid6dc3d42009-04-24 18:04:07 +00004105#endif
aliguori43b96852009-04-24 18:03:33 +00004106#ifdef CONFIG_PROFILER
4107 ti = profile_getclock();
4108#endif
4109 main_loop_wait(qemu_calculate_timeout());
4110#ifdef CONFIG_PROFILER
4111 dev_time += profile_getclock() - ti;
4112#endif
aliguorie5689022009-04-24 18:03:54 +00004113 } while (vm_can_run());
aliguori43b96852009-04-24 18:03:33 +00004114
aliguorie5689022009-04-24 18:03:54 +00004115 if (qemu_debug_requested())
aliguori43b96852009-04-24 18:03:33 +00004116 vm_stop(EXCP_DEBUG);
aliguori43b96852009-04-24 18:03:33 +00004117 if (qemu_shutdown_requested()) {
4118 if (no_shutdown) {
4119 vm_stop(0);
4120 no_shutdown = 0;
4121 } else
4122 break;
4123 }
aliguorid6dc3d42009-04-24 18:04:07 +00004124 if (qemu_reset_requested()) {
4125 pause_all_vcpus();
aliguori43b96852009-04-24 18:03:33 +00004126 qemu_system_reset();
aliguorid6dc3d42009-04-24 18:04:07 +00004127 resume_all_vcpus();
4128 }
Blue Swirld9c32312009-08-09 08:42:19 +00004129 if (qemu_powerdown_requested()) {
4130 qemu_irq_raise(qemu_system_powerdown);
4131 }
aliguori6e29f5d2009-04-24 18:04:02 +00004132 if ((r = qemu_vmstop_requested()))
4133 vm_stop(r);
aliguori43b96852009-04-24 18:03:33 +00004134 }
aliguorid6dc3d42009-04-24 18:04:07 +00004135 pause_all_vcpus();
bellardb4608c02003-06-27 17:34:32 +00004136}
4137
pbrook9bd7e6d2009-04-07 22:58:45 +00004138static void version(void)
4139{
pbrook4a19f1e2009-04-07 23:17:49 +00004140 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
pbrook9bd7e6d2009-04-07 22:58:45 +00004141}
4142
ths15f82202007-06-29 23:26:08 +00004143static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00004144{
pbrook9bd7e6d2009-04-07 22:58:45 +00004145 version();
4146 printf("usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00004147 "\n"
bellarda20dd502003-09-30 21:07:02 +00004148 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00004149 "\n"
blueswir15824d652009-03-28 06:44:27 +00004150#define DEF(option, opt_arg, opt_enum, opt_help) \
4151 opt_help
4152#define DEFHEADING(text) stringify(text) "\n"
4153#include "qemu-options.h"
4154#undef DEF
4155#undef DEFHEADING
4156#undef GEN_DOCS
bellard0824d6f2003-06-24 13:42:40 +00004157 "\n"
bellard82c643f2004-07-14 17:28:13 +00004158 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00004159 "ctrl-alt-f toggle full screen\n"
4160 "ctrl-alt-n switch to virtual console 'n'\n"
4161 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00004162 "\n"
4163 "When using -nographic, press 'ctrl-a h' to get some help.\n"
4164 ,
bellard0db63472003-10-27 21:37:46 +00004165 "qemu",
bellarda00bad72004-05-22 21:39:06 +00004166 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00004167#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00004168 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00004169 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00004170#endif
bellard6e44ba72004-01-18 21:56:49 +00004171 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00004172 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00004173 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00004174}
4175
bellardcd6f1162004-05-13 22:02:20 +00004176#define HAS_ARG 0x0001
4177
4178enum {
blueswir15824d652009-03-28 06:44:27 +00004179#define DEF(option, opt_arg, opt_enum, opt_help) \
4180 opt_enum,
4181#define DEFHEADING(text)
4182#include "qemu-options.h"
4183#undef DEF
4184#undef DEFHEADING
4185#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004186};
4187
4188typedef struct QEMUOption {
4189 const char *name;
4190 int flags;
4191 int index;
4192} QEMUOption;
4193
blueswir1dbed7e42008-10-01 19:38:09 +00004194static const QEMUOption qemu_options[] = {
bellardcd6f1162004-05-13 22:02:20 +00004195 { "h", 0, QEMU_OPTION_h },
blueswir15824d652009-03-28 06:44:27 +00004196#define DEF(option, opt_arg, opt_enum, opt_help) \
4197 { option, opt_arg, opt_enum },
4198#define DEFHEADING(text)
4199#include "qemu-options.h"
4200#undef DEF
4201#undef DEFHEADING
4202#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004203 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00004204};
4205
bellard1d14ffa2005-10-30 18:58:22 +00004206#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00004207struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00004208#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00004209#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00004210 {
4211 "pcspk",
4212 "PC speaker",
4213 0,
4214 1,
4215 { .init_isa = pcspk_audio_init }
4216 },
4217#endif
malc4c9b53e2009-01-09 10:46:34 +00004218
4219#ifdef CONFIG_SB16
bellard6a36d842005-12-18 20:34:32 +00004220 {
4221 "sb16",
4222 "Creative Sound Blaster 16",
4223 0,
4224 1,
4225 { .init_isa = SB16_init }
4226 },
malc4c9b53e2009-01-09 10:46:34 +00004227#endif
bellard6a36d842005-12-18 20:34:32 +00004228
malccc53d262008-06-13 10:48:22 +00004229#ifdef CONFIG_CS4231A
4230 {
4231 "cs4231a",
4232 "CS4231A",
4233 0,
4234 1,
4235 { .init_isa = cs4231a_init }
4236 },
4237#endif
4238
bellard6a36d842005-12-18 20:34:32 +00004239#ifdef CONFIG_ADLIB
4240 {
4241 "adlib",
4242#ifdef HAS_YMF262
4243 "Yamaha YMF262 (OPL3)",
4244#else
4245 "Yamaha YM3812 (OPL2)",
4246#endif
4247 0,
4248 1,
4249 { .init_isa = Adlib_init }
4250 },
4251#endif
4252
4253#ifdef CONFIG_GUS
4254 {
4255 "gus",
4256 "Gravis Ultrasound GF1",
4257 0,
4258 1,
4259 { .init_isa = GUS_init }
4260 },
4261#endif
4262
malc4c9b53e2009-01-09 10:46:34 +00004263#ifdef CONFIG_AC97
balroge5c9a132008-01-14 04:27:55 +00004264 {
4265 "ac97",
4266 "Intel 82801AA AC97 Audio",
4267 0,
4268 0,
4269 { .init_pci = ac97_init }
4270 },
malc4c9b53e2009-01-09 10:46:34 +00004271#endif
balroge5c9a132008-01-14 04:27:55 +00004272
malc4c9b53e2009-01-09 10:46:34 +00004273#ifdef CONFIG_ES1370
bellard6a36d842005-12-18 20:34:32 +00004274 {
4275 "es1370",
4276 "ENSONIQ AudioPCI ES1370",
4277 0,
4278 0,
4279 { .init_pci = es1370_init }
4280 },
balrogb00052e2007-04-30 02:22:06 +00004281#endif
bellard6a36d842005-12-18 20:34:32 +00004282
malc4c9b53e2009-01-09 10:46:34 +00004283#endif /* HAS_AUDIO_CHOICE */
4284
bellard6a36d842005-12-18 20:34:32 +00004285 { NULL, NULL, 0, 0, { NULL } }
4286};
4287
bellard1d14ffa2005-10-30 18:58:22 +00004288static void select_soundhw (const char *optarg)
4289{
bellard6a36d842005-12-18 20:34:32 +00004290 struct soundhw *c;
4291
bellard1d14ffa2005-10-30 18:58:22 +00004292 if (*optarg == '?') {
4293 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00004294
bellard1d14ffa2005-10-30 18:58:22 +00004295 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00004296 for (c = soundhw; c->name; ++c) {
4297 printf ("%-11s %s\n", c->name, c->descr);
4298 }
4299 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00004300 exit (*optarg != '?');
4301 }
4302 else {
bellard6a36d842005-12-18 20:34:32 +00004303 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00004304 const char *p;
4305 char *e;
4306 int bad_card = 0;
4307
bellard6a36d842005-12-18 20:34:32 +00004308 if (!strcmp (optarg, "all")) {
4309 for (c = soundhw; c->name; ++c) {
4310 c->enabled = 1;
4311 }
4312 return;
4313 }
bellard1d14ffa2005-10-30 18:58:22 +00004314
bellard6a36d842005-12-18 20:34:32 +00004315 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00004316 while (*p) {
4317 e = strchr (p, ',');
4318 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00004319
4320 for (c = soundhw; c->name; ++c) {
malcb3d6fb42009-09-06 06:49:03 +04004321 if (!strncmp (c->name, p, l) && !c->name[l]) {
bellard6a36d842005-12-18 20:34:32 +00004322 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00004323 break;
4324 }
4325 }
bellard6a36d842005-12-18 20:34:32 +00004326
4327 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00004328 if (l > 80) {
4329 fprintf (stderr,
4330 "Unknown sound card name (too big to show)\n");
4331 }
4332 else {
4333 fprintf (stderr, "Unknown sound card name `%.*s'\n",
4334 (int) l, p);
4335 }
4336 bad_card = 1;
4337 }
4338 p += l + (e != NULL);
4339 }
4340
4341 if (bad_card)
4342 goto show_valid_cards;
4343 }
4344}
4345#endif
4346
malc3893c122008-09-28 00:42:05 +00004347static void select_vgahw (const char *p)
4348{
4349 const char *opts;
4350
Zachary Amsden86176752009-07-30 00:15:02 -10004351 vga_interface_type = VGA_NONE;
malc3893c122008-09-28 00:42:05 +00004352 if (strstart(p, "std", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004353 vga_interface_type = VGA_STD;
malc3893c122008-09-28 00:42:05 +00004354 } else if (strstart(p, "cirrus", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004355 vga_interface_type = VGA_CIRRUS;
malc3893c122008-09-28 00:42:05 +00004356 } else if (strstart(p, "vmware", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004357 vga_interface_type = VGA_VMWARE;
aliguori94909d92009-04-22 15:19:53 +00004358 } else if (strstart(p, "xenfb", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004359 vga_interface_type = VGA_XENFB;
aliguori28b85ed2009-04-22 15:19:48 +00004360 } else if (!strstart(p, "none", &opts)) {
malc3893c122008-09-28 00:42:05 +00004361 invalid_vga:
4362 fprintf(stderr, "Unknown vga type: %s\n", p);
4363 exit(1);
4364 }
malccb5a7aa2008-09-28 00:42:12 +00004365 while (*opts) {
4366 const char *nextopt;
4367
4368 if (strstart(opts, ",retrace=", &nextopt)) {
4369 opts = nextopt;
4370 if (strstart(opts, "dumb", &nextopt))
4371 vga_retrace_method = VGA_RETRACE_DUMB;
4372 else if (strstart(opts, "precise", &nextopt))
4373 vga_retrace_method = VGA_RETRACE_PRECISE;
4374 else goto invalid_vga;
4375 } else goto invalid_vga;
4376 opts = nextopt;
4377 }
malc3893c122008-09-28 00:42:05 +00004378}
4379
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004380#ifdef TARGET_I386
4381static int balloon_parse(const char *arg)
4382{
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004383 QemuOpts *opts;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004384
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004385 if (strcmp(arg, "none") == 0) {
4386 return 0;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004387 }
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004388
4389 if (!strncmp(arg, "virtio", 6)) {
4390 if (arg[6] == ',') {
4391 /* have params -> parse them */
4392 opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL);
4393 if (!opts)
4394 return -1;
4395 } else {
4396 /* create empty opts */
4397 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
4398 }
4399 qemu_opt_set(opts, "driver", "virtio-balloon-pci");
4400 return 0;
4401 }
4402
4403 return -1;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004404}
4405#endif
4406
bellard3587d7e2006-06-26 20:03:44 +00004407#ifdef _WIN32
4408static BOOL WINAPI qemu_ctrl_handler(DWORD type)
4409{
4410 exit(STATUS_CONTROL_C_EXIT);
4411 return TRUE;
4412}
4413#endif
4414
aliguoric4be29f2009-04-17 18:58:14 +00004415int qemu_uuid_parse(const char *str, uint8_t *uuid)
blueswir18fcb1b92008-09-18 18:29:08 +00004416{
4417 int ret;
4418
4419 if(strlen(str) != 36)
4420 return -1;
4421
4422 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
4423 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
4424 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
4425
4426 if(ret != 16)
4427 return -1;
4428
aliguorib6f6e3d2009-04-17 18:59:56 +00004429#ifdef TARGET_I386
4430 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
4431#endif
4432
blueswir18fcb1b92008-09-18 18:29:08 +00004433 return 0;
4434}
4435
aliguori5b08fc12008-08-21 20:08:03 +00004436#ifndef _WIN32
4437
4438static void termsig_handler(int signal)
4439{
4440 qemu_system_shutdown_request();
4441}
4442
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004443static void sigchld_handler(int signal)
4444{
4445 waitpid(-1, NULL, WNOHANG);
4446}
4447
4448static void sighandler_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00004449{
4450 struct sigaction act;
4451
4452 memset(&act, 0, sizeof(act));
4453 act.sa_handler = termsig_handler;
4454 sigaction(SIGINT, &act, NULL);
4455 sigaction(SIGHUP, &act, NULL);
4456 sigaction(SIGTERM, &act, NULL);
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004457
4458 act.sa_handler = sigchld_handler;
4459 act.sa_flags = SA_NOCLDSTOP;
4460 sigaction(SIGCHLD, &act, NULL);
aliguori5b08fc12008-08-21 20:08:03 +00004461}
4462
4463#endif
4464
Paul Brook5cea8592009-05-30 00:52:44 +01004465#ifdef _WIN32
4466/* Look for support files in the same directory as the executable. */
4467static char *find_datadir(const char *argv0)
4468{
4469 char *p;
4470 char buf[MAX_PATH];
4471 DWORD len;
4472
4473 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
4474 if (len == 0) {
Blue Swirlc5947802009-06-09 20:51:21 +03004475 return NULL;
Paul Brook5cea8592009-05-30 00:52:44 +01004476 }
4477
4478 buf[len] = 0;
4479 p = buf + len - 1;
4480 while (p != buf && *p != '\\')
4481 p--;
4482 *p = 0;
4483 if (access(buf, R_OK) == 0) {
4484 return qemu_strdup(buf);
4485 }
4486 return NULL;
4487}
4488#else /* !_WIN32 */
4489
4490/* Find a likely location for support files using the location of the binary.
4491 For installed binaries this will be "$bindir/../share/qemu". When
4492 running from the build tree this will be "$bindir/../pc-bios". */
4493#define SHARE_SUFFIX "/share/qemu"
4494#define BUILD_SUFFIX "/pc-bios"
4495static char *find_datadir(const char *argv0)
4496{
4497 char *dir;
4498 char *p = NULL;
4499 char *res;
Paul Brook5cea8592009-05-30 00:52:44 +01004500 char buf[PATH_MAX];
Blue Swirl3a417592009-06-09 19:12:21 +00004501 size_t max_len;
Paul Brook5cea8592009-05-30 00:52:44 +01004502
4503#if defined(__linux__)
4504 {
4505 int len;
4506 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
4507 if (len > 0) {
4508 buf[len] = 0;
4509 p = buf;
4510 }
4511 }
4512#elif defined(__FreeBSD__)
4513 {
4514 int len;
4515 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
4516 if (len > 0) {
4517 buf[len] = 0;
4518 p = buf;
4519 }
4520 }
4521#endif
4522 /* If we don't have any way of figuring out the actual executable
4523 location then try argv[0]. */
4524 if (!p) {
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004525 p = realpath(argv0, buf);
Paul Brook5cea8592009-05-30 00:52:44 +01004526 if (!p) {
4527 return NULL;
4528 }
4529 }
4530 dir = dirname(p);
4531 dir = dirname(dir);
4532
Blue Swirl3a417592009-06-09 19:12:21 +00004533 max_len = strlen(dir) +
4534 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
4535 res = qemu_mallocz(max_len);
4536 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004537 if (access(res, R_OK)) {
Blue Swirl3a417592009-06-09 19:12:21 +00004538 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004539 if (access(res, R_OK)) {
4540 qemu_free(res);
4541 res = NULL;
4542 }
4543 }
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004544
Paul Brook5cea8592009-05-30 00:52:44 +01004545 return res;
4546}
4547#undef SHARE_SUFFIX
4548#undef BUILD_SUFFIX
4549#endif
4550
4551char *qemu_find_file(int type, const char *name)
4552{
4553 int len;
4554 const char *subdir;
4555 char *buf;
4556
4557 /* If name contains path separators then try it as a straight path. */
4558 if ((strchr(name, '/') || strchr(name, '\\'))
4559 && access(name, R_OK) == 0) {
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +02004560 return qemu_strdup(name);
Paul Brook5cea8592009-05-30 00:52:44 +01004561 }
4562 switch (type) {
4563 case QEMU_FILE_TYPE_BIOS:
4564 subdir = "";
4565 break;
4566 case QEMU_FILE_TYPE_KEYMAP:
4567 subdir = "keymaps/";
4568 break;
4569 default:
4570 abort();
4571 }
4572 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
4573 buf = qemu_mallocz(len);
Blue Swirl3a417592009-06-09 19:12:21 +00004574 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
Paul Brook5cea8592009-05-30 00:52:44 +01004575 if (access(buf, R_OK)) {
4576 qemu_free(buf);
4577 return NULL;
4578 }
4579 return buf;
4580}
4581
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004582static int device_init_func(QemuOpts *opts, void *opaque)
4583{
4584 DeviceState *dev;
4585
4586 dev = qdev_device_add(opts);
4587 if (!dev)
4588 return -1;
4589 return 0;
4590}
4591
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004592struct device_config {
4593 enum {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004594 DEV_USB, /* -usbdevice */
4595 DEV_BT, /* -bt */
4596 } type;
4597 const char *cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004598 QTAILQ_ENTRY(device_config) next;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004599};
Blue Swirl72cf2d42009-09-12 07:36:22 +00004600QTAILQ_HEAD(, device_config) device_configs = QTAILQ_HEAD_INITIALIZER(device_configs);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004601
4602static void add_device_config(int type, const char *cmdline)
4603{
4604 struct device_config *conf;
4605
4606 conf = qemu_mallocz(sizeof(*conf));
4607 conf->type = type;
4608 conf->cmdline = cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004609 QTAILQ_INSERT_TAIL(&device_configs, conf, next);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004610}
4611
4612static int foreach_device_config(int type, int (*func)(const char *cmdline))
4613{
4614 struct device_config *conf;
4615 int rc;
4616
Blue Swirl72cf2d42009-09-12 07:36:22 +00004617 QTAILQ_FOREACH(conf, &device_configs, next) {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004618 if (conf->type != type)
4619 continue;
4620 rc = func(conf->cmdline);
4621 if (0 != rc)
4622 return rc;
4623 }
4624 return 0;
4625}
4626
malc902b3d52008-12-10 19:18:40 +00004627int main(int argc, char **argv, char **envp)
bellard0824d6f2003-06-24 13:42:40 +00004628{
aliguori59030a82009-04-05 18:43:41 +00004629 const char *gdbstub_dev = NULL;
j_mayer28c5af52007-11-11 01:50:45 +00004630 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00004631 int i;
j_mayer28c5af52007-11-11 01:50:45 +00004632 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00004633 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00004634 const char *kernel_filename, *kernel_cmdline;
Jan Kiszkaef3adf62009-07-02 00:19:02 +02004635 char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
aliguori3023f332009-01-16 19:04:14 +00004636 DisplayState *ds;
aliguori7d957bd2009-01-15 22:14:11 +00004637 DisplayChangeListener *dcl;
bellard46d47672004-11-16 01:45:27 +00004638 int cyls, heads, secs, translation;
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004639 QemuOpts *hda_opts = NULL, *opts;
bellardcd6f1162004-05-13 22:02:20 +00004640 int optind;
4641 const char *r, *optarg;
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02004642 CharDriverState *monitor_hds[MAX_MONITOR_DEVICES];
4643 const char *monitor_devices[MAX_MONITOR_DEVICES];
4644 int monitor_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00004645 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00004646 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00004647 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00004648 int parallel_device_index;
aliguori9ede2fd2009-01-15 20:05:25 +00004649 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
4650 int virtio_console_index;
bellardd63d3072004-10-03 13:29:03 +00004651 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00004652 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00004653 const char *cpu_model;
blueswir1b9e82a52009-04-05 18:03:31 +00004654#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00004655 int fds[2];
blueswir1b9e82a52009-04-05 18:03:31 +00004656#endif
bellard26a5f132008-05-28 12:30:31 +00004657 int tb_size;
ths93815bc2007-03-19 15:58:31 +00004658 const char *pid_file = NULL;
aliguori5bb79102008-10-13 03:12:02 +00004659 const char *incoming = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004660#ifndef _WIN32
aliguori54042bc2009-02-27 22:16:47 +00004661 int fd = 0;
4662 struct passwd *pwd = NULL;
aliguori08585322009-02-27 22:09:45 +00004663 const char *chroot_dir = NULL;
4664 const char *run_as = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004665#endif
aliguori268a3622009-04-21 22:30:27 +00004666 CPUState *env;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004667 int show_vnc_port = 0;
bellard0bd48852005-11-11 00:00:47 +00004668
Jan Kiszka68752042009-09-15 13:36:04 +02004669 init_clocks();
4670
Gerd Hoffmannac7531e2009-08-14 10:36:06 +02004671 qemu_errors_to_file(stderr);
malc902b3d52008-12-10 19:18:40 +00004672 qemu_cache_utils_init(envp);
4673
Blue Swirl72cf2d42009-09-12 07:36:22 +00004674 QLIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00004675#ifndef _WIN32
4676 {
4677 struct sigaction act;
4678 sigfillset(&act.sa_mask);
4679 act.sa_flags = 0;
4680 act.sa_handler = SIG_IGN;
4681 sigaction(SIGPIPE, &act, NULL);
4682 }
bellard3587d7e2006-06-26 20:03:44 +00004683#else
4684 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00004685 /* Note: cpu_interrupt() is currently not SMP safe, so we force
4686 QEMU to run on a single CPU */
4687 {
4688 HANDLE h;
4689 DWORD mask, smask;
4690 int i;
4691 h = GetCurrentProcess();
4692 if (GetProcessAffinityMask(h, &mask, &smask)) {
4693 for(i = 0; i < 32; i++) {
4694 if (mask & (1 << i))
4695 break;
4696 }
4697 if (i != 32) {
4698 mask = 1 << i;
4699 SetProcessAffinityMask(h, mask);
4700 }
4701 }
4702 }
bellard67b915a2004-03-31 23:37:16 +00004703#endif
bellardbe995c22006-06-25 16:25:21 +00004704
Anthony Liguorif80f9ec2009-05-20 18:38:09 -05004705 module_call_init(MODULE_INIT_MACHINE);
Anthony Liguori0c257432009-05-21 20:41:01 -05004706 machine = find_default_machine();
j_mayer94fc95c2007-03-05 19:44:02 +00004707 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00004708 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00004709 ram_size = 0;
bellard33e39632003-07-06 17:15:21 +00004710 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00004711 kernel_filename = NULL;
4712 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00004713 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00004714 translation = BIOS_ATA_TRANSLATION_AUTO;
bellardc4b1fcc2004-03-14 21:44:30 +00004715
aurel32c75a8232008-05-04 00:50:34 +00004716 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00004717 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004718 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00004719 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004720
aliguori8290edd2009-02-27 20:14:29 +00004721 parallel_devices[0] = "vc:80Cx24C";
bellard6508fe52005-01-15 12:02:56 +00004722 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004723 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00004724 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004725
aliguori1b8fc812009-02-27 20:01:39 +00004726 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
aliguori9ede2fd2009-01-15 20:05:25 +00004727 virtio_consoles[i] = NULL;
4728 virtio_console_index = 0;
4729
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02004730 monitor_devices[0] = "vc:80Cx24C";
4731 for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
4732 monitor_devices[i] = NULL;
4733 }
4734 monitor_device_index = 0;
4735
aliguori268a3622009-04-21 22:30:27 +00004736 for (i = 0; i < MAX_NODES; i++) {
4737 node_mem[i] = 0;
4738 node_cpumask[i] = 0;
4739 }
4740
aliguori268a3622009-04-21 22:30:27 +00004741 nb_numa_nodes = 0;
bellard7c9d8e02005-11-15 22:16:05 +00004742 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00004743
bellard26a5f132008-05-28 12:30:31 +00004744 tb_size = 0;
blueswir141bd6392008-10-05 09:56:21 +00004745 autostart= 1;
4746
bellardcd6f1162004-05-13 22:02:20 +00004747 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00004748 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00004749 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00004750 break;
bellardcd6f1162004-05-13 22:02:20 +00004751 r = argv[optind];
4752 if (r[0] != '-') {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004753 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00004754 } else {
4755 const QEMUOption *popt;
4756
4757 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00004758 /* Treat --foo the same as -foo. */
4759 if (r[1] == '-')
4760 r++;
bellardcd6f1162004-05-13 22:02:20 +00004761 popt = qemu_options;
4762 for(;;) {
4763 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00004764 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00004765 argv[0], r);
4766 exit(1);
4767 }
4768 if (!strcmp(popt->name, r + 1))
4769 break;
4770 popt++;
4771 }
4772 if (popt->flags & HAS_ARG) {
4773 if (optind >= argc) {
4774 fprintf(stderr, "%s: option '%s' requires an argument\n",
4775 argv[0], r);
4776 exit(1);
4777 }
4778 optarg = argv[optind++];
4779 } else {
4780 optarg = NULL;
4781 }
4782
4783 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00004784 case QEMU_OPTION_M:
4785 machine = find_machine(optarg);
4786 if (!machine) {
4787 QEMUMachine *m;
4788 printf("Supported machines are:\n");
4789 for(m = first_machine; m != NULL; m = m->next) {
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01004790 if (m->alias)
4791 printf("%-10s %s (alias of %s)\n",
4792 m->alias, m->desc, m->name);
bellardcc1daa42005-06-05 14:49:17 +00004793 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00004794 m->name, m->desc,
Anthony Liguori0c257432009-05-21 20:41:01 -05004795 m->is_default ? " (default)" : "");
bellardcc1daa42005-06-05 14:49:17 +00004796 }
ths15f82202007-06-29 23:26:08 +00004797 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00004798 }
4799 break;
j_mayer94fc95c2007-03-05 19:44:02 +00004800 case QEMU_OPTION_cpu:
4801 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00004802 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00004803/* XXX: implement xxx_cpu_list for targets that still miss it */
4804#if defined(cpu_list)
4805 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00004806#endif
ths15f82202007-06-29 23:26:08 +00004807 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00004808 } else {
4809 cpu_model = optarg;
4810 }
4811 break;
bellardcd6f1162004-05-13 22:02:20 +00004812 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00004813 initrd_filename = optarg;
4814 break;
bellardcd6f1162004-05-13 22:02:20 +00004815 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00004816 if (cyls == 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004817 hda_opts = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00004818 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004819 hda_opts = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00004820 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00004821 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00004822 translation == BIOS_ATA_TRANSLATION_LBA ?
4823 ",trans=lba" :
4824 translation == BIOS_ATA_TRANSLATION_NONE ?
4825 ",trans=none" : "");
4826 break;
bellardcd6f1162004-05-13 22:02:20 +00004827 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00004828 case QEMU_OPTION_hdc:
4829 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00004830 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00004831 break;
thse4bcb142007-12-02 04:51:10 +00004832 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00004833 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00004834 break;
Gerd Hoffmannd058fe02009-07-31 12:25:36 +02004835 case QEMU_OPTION_set:
4836 if (qemu_set_option(optarg) != 0)
4837 exit(1);
4838 break;
balrog3e3d5812007-04-30 02:09:25 +00004839 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00004840 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00004841 break;
pbrooka1bb27b2007-04-06 16:49:48 +00004842 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00004843 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00004844 break;
j_mayer86f55662007-04-24 06:52:59 +00004845 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00004846 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00004847 break;
bellardcd6f1162004-05-13 22:02:20 +00004848 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00004849 snapshot = 1;
4850 break;
bellardcd6f1162004-05-13 22:02:20 +00004851 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00004852 {
bellard330d0412003-07-26 18:11:40 +00004853 const char *p;
4854 p = optarg;
4855 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004856 if (cyls < 1 || cyls > 16383)
4857 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004858 if (*p != ',')
4859 goto chs_fail;
4860 p++;
4861 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004862 if (heads < 1 || heads > 16)
4863 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004864 if (*p != ',')
4865 goto chs_fail;
4866 p++;
4867 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004868 if (secs < 1 || secs > 63)
4869 goto chs_fail;
4870 if (*p == ',') {
4871 p++;
4872 if (!strcmp(p, "none"))
4873 translation = BIOS_ATA_TRANSLATION_NONE;
4874 else if (!strcmp(p, "lba"))
4875 translation = BIOS_ATA_TRANSLATION_LBA;
4876 else if (!strcmp(p, "auto"))
4877 translation = BIOS_ATA_TRANSLATION_AUTO;
4878 else
4879 goto chs_fail;
4880 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00004881 chs_fail:
bellard46d47672004-11-16 01:45:27 +00004882 fprintf(stderr, "qemu: invalid physical CHS format\n");
4883 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00004884 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004885 if (hda_opts != NULL) {
4886 char num[16];
4887 snprintf(num, sizeof(num), "%d", cyls);
4888 qemu_opt_set(hda_opts, "cyls", num);
4889 snprintf(num, sizeof(num), "%d", heads);
4890 qemu_opt_set(hda_opts, "heads", num);
4891 snprintf(num, sizeof(num), "%d", secs);
4892 qemu_opt_set(hda_opts, "secs", num);
4893 if (translation == BIOS_ATA_TRANSLATION_LBA)
4894 qemu_opt_set(hda_opts, "trans", "lba");
4895 if (translation == BIOS_ATA_TRANSLATION_NONE)
4896 qemu_opt_set(hda_opts, "trans", "none");
4897 }
bellard330d0412003-07-26 18:11:40 +00004898 }
4899 break;
aliguori268a3622009-04-21 22:30:27 +00004900 case QEMU_OPTION_numa:
4901 if (nb_numa_nodes >= MAX_NODES) {
4902 fprintf(stderr, "qemu: too many NUMA nodes\n");
4903 exit(1);
4904 }
4905 numa_add(optarg);
4906 break;
bellardcd6f1162004-05-13 22:02:20 +00004907 case QEMU_OPTION_nographic:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004908 display_type = DT_NOGRAPHIC;
bellarda20dd502003-09-30 21:07:02 +00004909 break;
balrog4d3b6f62008-02-10 16:33:14 +00004910#ifdef CONFIG_CURSES
4911 case QEMU_OPTION_curses:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004912 display_type = DT_CURSES;
balrog4d3b6f62008-02-10 16:33:14 +00004913 break;
4914#endif
balroga171fe32007-04-30 01:48:07 +00004915 case QEMU_OPTION_portrait:
4916 graphic_rotate = 1;
4917 break;
bellardcd6f1162004-05-13 22:02:20 +00004918 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00004919 kernel_filename = optarg;
4920 break;
bellardcd6f1162004-05-13 22:02:20 +00004921 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00004922 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00004923 break;
bellardcd6f1162004-05-13 22:02:20 +00004924 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00004925 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00004926 break;
bellardcd6f1162004-05-13 22:02:20 +00004927 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00004928 {
Jan Kiszkaef3adf62009-07-02 00:19:02 +02004929 static const char * const params[] = {
Jan Kiszka95387492009-07-02 00:19:02 +02004930 "order", "once", "menu", NULL
Jan Kiszkaef3adf62009-07-02 00:19:02 +02004931 };
4932 char buf[sizeof(boot_devices)];
Jan Kiszkae0f084b2009-07-02 00:19:02 +02004933 char *standard_boot_devices;
Jan Kiszkaef3adf62009-07-02 00:19:02 +02004934 int legacy = 0;
4935
4936 if (!strchr(optarg, '=')) {
4937 legacy = 1;
4938 pstrcpy(buf, sizeof(buf), optarg);
4939 } else if (check_params(buf, sizeof(buf), params, optarg) < 0) {
4940 fprintf(stderr,
4941 "qemu: unknown boot parameter '%s' in '%s'\n",
4942 buf, optarg);
4943 exit(1);
4944 }
4945
4946 if (legacy ||
4947 get_param_value(buf, sizeof(buf), "order", optarg)) {
4948 boot_devices_bitmap = parse_bootdevices(buf);
4949 pstrcpy(boot_devices, sizeof(boot_devices), buf);
j_mayer28c5af52007-11-11 01:50:45 +00004950 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02004951 if (!legacy) {
4952 if (get_param_value(buf, sizeof(buf),
4953 "once", optarg)) {
4954 boot_devices_bitmap |= parse_bootdevices(buf);
4955 standard_boot_devices = qemu_strdup(boot_devices);
4956 pstrcpy(boot_devices, sizeof(boot_devices), buf);
4957 qemu_register_reset(restore_boot_devices,
4958 standard_boot_devices);
4959 }
Jan Kiszka95387492009-07-02 00:19:02 +02004960 if (get_param_value(buf, sizeof(buf),
4961 "menu", optarg)) {
4962 if (!strcmp(buf, "on")) {
4963 boot_menu = 1;
4964 } else if (!strcmp(buf, "off")) {
4965 boot_menu = 0;
4966 } else {
4967 fprintf(stderr,
4968 "qemu: invalid option value '%s'\n",
4969 buf);
4970 exit(1);
4971 }
4972 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02004973 }
bellard36b486b2003-11-11 13:36:08 +00004974 }
4975 break;
bellardcd6f1162004-05-13 22:02:20 +00004976 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00004977 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00004978 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00004979 break;
bellard52ca8d62006-06-14 16:03:05 +00004980#ifdef TARGET_I386
4981 case QEMU_OPTION_no_fd_bootchk:
4982 fd_bootchk = 0;
4983 break;
4984#endif
Mark McLoughlina1ea4582009-10-08 19:58:26 +01004985 case QEMU_OPTION_netdev:
4986 if (net_client_parse(&qemu_netdev_opts, optarg) == -1) {
4987 exit(1);
4988 }
4989 break;
bellard7c9d8e02005-11-15 22:16:05 +00004990 case QEMU_OPTION_net:
Mark McLoughlin7f161aa2009-10-08 19:58:25 +01004991 if (net_client_parse(&qemu_net_opts, optarg) == -1) {
bellardc4b1fcc2004-03-14 21:44:30 +00004992 exit(1);
4993 }
bellard702c6512004-04-02 21:21:32 +00004994 break;
bellardc7f74642004-08-24 21:57:12 +00004995#ifdef CONFIG_SLIRP
4996 case QEMU_OPTION_tftp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02004997 legacy_tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00004998 break;
ths47d5d012007-02-20 00:05:08 +00004999 case QEMU_OPTION_bootp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005000 legacy_bootp_filename = optarg;
ths47d5d012007-02-20 00:05:08 +00005001 break;
bellardc94c8d62004-09-13 21:37:34 +00005002#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00005003 case QEMU_OPTION_smb:
Markus Armbruster07527062009-10-06 12:16:57 +01005004 if (net_slirp_smb(optarg) < 0)
5005 exit(1);
bellard9d728e82004-09-05 23:09:03 +00005006 break;
bellardc94c8d62004-09-13 21:37:34 +00005007#endif
bellard9bf05442004-08-25 22:12:49 +00005008 case QEMU_OPTION_redir:
Markus Armbruster07527062009-10-06 12:16:57 +01005009 if (net_slirp_redir(optarg) < 0)
5010 exit(1);
bellard9bf05442004-08-25 22:12:49 +00005011 break;
bellardc7f74642004-08-24 21:57:12 +00005012#endif
balrogdc72ac12008-11-09 00:04:26 +00005013 case QEMU_OPTION_bt:
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005014 add_device_config(DEV_BT, optarg);
balrogdc72ac12008-11-09 00:04:26 +00005015 break;
bellard1d14ffa2005-10-30 18:58:22 +00005016#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00005017 case QEMU_OPTION_audio_help:
5018 AUD_help ();
5019 exit (0);
5020 break;
5021 case QEMU_OPTION_soundhw:
5022 select_soundhw (optarg);
5023 break;
5024#endif
bellardcd6f1162004-05-13 22:02:20 +00005025 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00005026 help(0);
bellardcd6f1162004-05-13 22:02:20 +00005027 break;
pbrook9bd7e6d2009-04-07 22:58:45 +00005028 case QEMU_OPTION_version:
5029 version();
5030 exit(0);
5031 break;
aurel3200f82b82008-04-27 21:12:55 +00005032 case QEMU_OPTION_m: {
5033 uint64_t value;
5034 char *ptr;
5035
5036 value = strtoul(optarg, &ptr, 10);
5037 switch (*ptr) {
5038 case 0: case 'M': case 'm':
5039 value <<= 20;
5040 break;
5041 case 'G': case 'g':
5042 value <<= 30;
5043 break;
5044 default:
5045 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00005046 exit(1);
5047 }
aurel3200f82b82008-04-27 21:12:55 +00005048
5049 /* On 32-bit hosts, QEMU is limited by virtual address space */
Anthony Liguori4a1418e2009-08-10 17:07:24 -05005050 if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
aurel3200f82b82008-04-27 21:12:55 +00005051 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
5052 exit(1);
5053 }
Anthony Liguoric227f092009-10-01 16:12:16 -05005054 if (value != (uint64_t)(ram_addr_t)value) {
aurel3200f82b82008-04-27 21:12:55 +00005055 fprintf(stderr, "qemu: ram size too large\n");
5056 exit(1);
5057 }
5058 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00005059 break;
aurel3200f82b82008-04-27 21:12:55 +00005060 }
bellardcd6f1162004-05-13 22:02:20 +00005061 case QEMU_OPTION_d:
5062 {
5063 int mask;
blueswir1c7cd6a32008-10-02 18:27:46 +00005064 const CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00005065
bellardcd6f1162004-05-13 22:02:20 +00005066 mask = cpu_str_to_log_mask(optarg);
5067 if (!mask) {
5068 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00005069 for(item = cpu_log_items; item->mask != 0; item++) {
5070 printf("%-10s %s\n", item->name, item->help);
5071 }
5072 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00005073 }
5074 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00005075 }
bellardcd6f1162004-05-13 22:02:20 +00005076 break;
bellardcd6f1162004-05-13 22:02:20 +00005077 case QEMU_OPTION_s:
aliguori59030a82009-04-05 18:43:41 +00005078 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
bellardcd6f1162004-05-13 22:02:20 +00005079 break;
aliguori59030a82009-04-05 18:43:41 +00005080 case QEMU_OPTION_gdb:
5081 gdbstub_dev = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005082 break;
bellardcd6f1162004-05-13 22:02:20 +00005083 case QEMU_OPTION_L:
Paul Brook5cea8592009-05-30 00:52:44 +01005084 data_dir = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005085 break;
j_mayer1192dad2007-10-05 13:08:35 +00005086 case QEMU_OPTION_bios:
5087 bios_name = optarg;
5088 break;
aurel321b530a62009-04-05 20:08:59 +00005089 case QEMU_OPTION_singlestep:
5090 singlestep = 1;
5091 break;
bellardcd6f1162004-05-13 22:02:20 +00005092 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00005093 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00005094 break;
blueswir15824d652009-03-28 06:44:27 +00005095#ifndef _WIN32
bellard3d11d0e2004-12-12 16:56:30 +00005096 case QEMU_OPTION_k:
5097 keyboard_layout = optarg;
5098 break;
blueswir15824d652009-03-28 06:44:27 +00005099#endif
bellardee22c2f2004-06-03 12:49:50 +00005100 case QEMU_OPTION_localtime:
5101 rtc_utc = 0;
5102 break;
malc3893c122008-09-28 00:42:05 +00005103 case QEMU_OPTION_vga:
5104 select_vgahw (optarg);
bellard1bfe8562004-07-08 21:17:50 +00005105 break;
blueswir15824d652009-03-28 06:44:27 +00005106#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00005107 case QEMU_OPTION_g:
5108 {
5109 const char *p;
5110 int w, h, depth;
5111 p = optarg;
5112 w = strtol(p, (char **)&p, 10);
5113 if (w <= 0) {
5114 graphic_error:
5115 fprintf(stderr, "qemu: invalid resolution or depth\n");
5116 exit(1);
5117 }
5118 if (*p != 'x')
5119 goto graphic_error;
5120 p++;
5121 h = strtol(p, (char **)&p, 10);
5122 if (h <= 0)
5123 goto graphic_error;
5124 if (*p == 'x') {
5125 p++;
5126 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00005127 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00005128 depth != 24 && depth != 32)
5129 goto graphic_error;
5130 } else if (*p == '\0') {
5131 depth = graphic_depth;
5132 } else {
5133 goto graphic_error;
5134 }
ths3b46e622007-09-17 08:09:54 +00005135
bellarde9b137c2004-06-21 16:46:10 +00005136 graphic_width = w;
5137 graphic_height = h;
5138 graphic_depth = depth;
5139 }
5140 break;
blueswir15824d652009-03-28 06:44:27 +00005141#endif
ths20d8a3e2007-02-18 17:04:49 +00005142 case QEMU_OPTION_echr:
5143 {
5144 char *r;
5145 term_escape_char = strtol(optarg, &r, 0);
5146 if (r == optarg)
5147 printf("Bad argument to echr\n");
5148 break;
5149 }
bellard82c643f2004-07-14 17:28:13 +00005150 case QEMU_OPTION_monitor:
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005151 if (monitor_device_index >= MAX_MONITOR_DEVICES) {
5152 fprintf(stderr, "qemu: too many monitor devices\n");
5153 exit(1);
5154 }
5155 monitor_devices[monitor_device_index] = optarg;
5156 monitor_device_index++;
bellard82c643f2004-07-14 17:28:13 +00005157 break;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005158 case QEMU_OPTION_chardev:
5159 opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
5160 if (!opts) {
5161 fprintf(stderr, "parse error: %s\n", optarg);
5162 exit(1);
5163 }
Mark McLoughlin3df04ac2009-09-23 11:24:05 +01005164 if (qemu_chr_open_opts(opts, NULL) == NULL) {
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005165 exit(1);
5166 }
5167 break;
bellard82c643f2004-07-14 17:28:13 +00005168 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00005169 if (serial_device_index >= MAX_SERIAL_PORTS) {
5170 fprintf(stderr, "qemu: too many serial ports\n");
5171 exit(1);
5172 }
pbrookfd5f3932008-03-26 20:55:43 +00005173 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00005174 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00005175 break;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005176 case QEMU_OPTION_watchdog:
Markus Armbruster09aaa162009-08-21 10:31:34 +02005177 if (watchdog) {
5178 fprintf(stderr,
5179 "qemu: only one watchdog option may be given\n");
5180 return 1;
5181 }
5182 watchdog = optarg;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005183 break;
5184 case QEMU_OPTION_watchdog_action:
5185 if (select_watchdog_action(optarg) == -1) {
5186 fprintf(stderr, "Unknown -watchdog-action parameter\n");
5187 exit(1);
5188 }
5189 break;
aliguori51ecf132009-01-15 20:06:40 +00005190 case QEMU_OPTION_virtiocon:
5191 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
5192 fprintf(stderr, "qemu: too many virtio consoles\n");
5193 exit(1);
5194 }
5195 virtio_consoles[virtio_console_index] = optarg;
5196 virtio_console_index++;
5197 break;
bellard6508fe52005-01-15 12:02:56 +00005198 case QEMU_OPTION_parallel:
5199 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
5200 fprintf(stderr, "qemu: too many parallel ports\n");
5201 exit(1);
5202 }
pbrookfd5f3932008-03-26 20:55:43 +00005203 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00005204 parallel_device_index++;
5205 break;
bellardd63d3072004-10-03 13:29:03 +00005206 case QEMU_OPTION_loadvm:
5207 loadvm = optarg;
5208 break;
5209 case QEMU_OPTION_full_screen:
5210 full_screen = 1;
5211 break;
ths667acca2006-12-11 02:08:05 +00005212#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00005213 case QEMU_OPTION_no_frame:
5214 no_frame = 1;
5215 break;
ths3780e192007-06-21 21:08:02 +00005216 case QEMU_OPTION_alt_grab:
5217 alt_grab = 1;
5218 break;
Dustin Kirkland0ca9f8a2009-09-17 15:48:04 -05005219 case QEMU_OPTION_ctrl_grab:
5220 ctrl_grab = 1;
5221 break;
ths667acca2006-12-11 02:08:05 +00005222 case QEMU_OPTION_no_quit:
5223 no_quit = 1;
5224 break;
aliguori7d957bd2009-01-15 22:14:11 +00005225 case QEMU_OPTION_sdl:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005226 display_type = DT_SDL;
aliguori7d957bd2009-01-15 22:14:11 +00005227 break;
ths667acca2006-12-11 02:08:05 +00005228#endif
bellardf7cce892004-12-08 22:21:25 +00005229 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00005230 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00005231 break;
bellarda09db212005-04-30 16:10:35 +00005232#ifdef TARGET_I386
5233 case QEMU_OPTION_win2k_hack:
5234 win2k_install_hack = 1;
5235 break;
aliguori73822ec2009-01-15 20:11:34 +00005236 case QEMU_OPTION_rtc_td_hack:
5237 rtc_td_hack = 1;
5238 break;
aliguori8a92ea22009-02-27 20:12:36 +00005239 case QEMU_OPTION_acpitable:
5240 if(acpi_table_add(optarg) < 0) {
5241 fprintf(stderr, "Wrong acpi table provided\n");
5242 exit(1);
5243 }
5244 break;
aliguorib6f6e3d2009-04-17 18:59:56 +00005245 case QEMU_OPTION_smbios:
5246 if(smbios_entry_add(optarg) < 0) {
5247 fprintf(stderr, "Wrong smbios provided\n");
5248 exit(1);
5249 }
5250 break;
bellarda09db212005-04-30 16:10:35 +00005251#endif
aliguori7ba1e612008-11-05 16:04:33 +00005252#ifdef CONFIG_KVM
5253 case QEMU_OPTION_enable_kvm:
5254 kvm_allowed = 1;
aliguori7ba1e612008-11-05 16:04:33 +00005255 break;
5256#endif
bellardbb36d472005-11-05 14:22:28 +00005257 case QEMU_OPTION_usb:
5258 usb_enabled = 1;
5259 break;
bellarda594cfb2005-11-06 16:13:29 +00005260 case QEMU_OPTION_usbdevice:
5261 usb_enabled = 1;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005262 add_device_config(DEV_USB, optarg);
5263 break;
5264 case QEMU_OPTION_device:
Mark McLoughlinb386bec2009-10-06 12:17:01 +01005265 if (!qemu_opts_parse(&qemu_device_opts, optarg, "driver")) {
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005266 exit(1);
5267 }
bellarda594cfb2005-11-06 16:13:29 +00005268 break;
bellard6a00d602005-11-21 23:25:50 +00005269 case QEMU_OPTION_smp:
Andre Przywaradc6b1c02009-08-19 15:42:40 +02005270 smp_parse(optarg);
aliguorib2097002008-10-07 20:39:39 +00005271 if (smp_cpus < 1) {
bellard6a00d602005-11-21 23:25:50 +00005272 fprintf(stderr, "Invalid number of CPUs\n");
5273 exit(1);
5274 }
Jes Sorensen6be68d72009-07-23 17:03:42 +02005275 if (max_cpus < smp_cpus) {
5276 fprintf(stderr, "maxcpus must be equal to or greater than "
5277 "smp\n");
5278 exit(1);
5279 }
5280 if (max_cpus > 255) {
5281 fprintf(stderr, "Unsupported number of maxcpus\n");
5282 exit(1);
5283 }
bellard6a00d602005-11-21 23:25:50 +00005284 break;
bellard24236862006-04-30 21:28:36 +00005285 case QEMU_OPTION_vnc:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005286 display_type = DT_VNC;
ths73fc9742006-12-22 02:09:07 +00005287 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00005288 break;
blueswir15824d652009-03-28 06:44:27 +00005289#ifdef TARGET_I386
bellard6515b202006-05-03 22:02:44 +00005290 case QEMU_OPTION_no_acpi:
5291 acpi_enabled = 0;
5292 break;
aliguori16b29ae2008-12-17 23:28:44 +00005293 case QEMU_OPTION_no_hpet:
5294 no_hpet = 1;
5295 break;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02005296 case QEMU_OPTION_balloon:
5297 if (balloon_parse(optarg) < 0) {
5298 fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
5299 exit(1);
5300 }
Eduardo Habkostdf97b922009-06-10 16:34:08 -03005301 break;
blueswir15824d652009-03-28 06:44:27 +00005302#endif
bellardd1beab82006-10-02 19:44:22 +00005303 case QEMU_OPTION_no_reboot:
5304 no_reboot = 1;
5305 break;
aurel32b2f76162008-04-11 21:35:52 +00005306 case QEMU_OPTION_no_shutdown:
5307 no_shutdown = 1;
5308 break;
balrog9467cd42007-05-01 01:34:14 +00005309 case QEMU_OPTION_show_cursor:
5310 cursor_hide = 0;
5311 break;
blueswir18fcb1b92008-09-18 18:29:08 +00005312 case QEMU_OPTION_uuid:
5313 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
5314 fprintf(stderr, "Fail to parse UUID string."
5315 " Wrong format.\n");
5316 exit(1);
5317 }
5318 break;
blueswir15824d652009-03-28 06:44:27 +00005319#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005320 case QEMU_OPTION_daemonize:
5321 daemonize = 1;
5322 break;
blueswir15824d652009-03-28 06:44:27 +00005323#endif
ths9ae02552007-01-05 17:39:04 +00005324 case QEMU_OPTION_option_rom:
5325 if (nb_option_roms >= MAX_OPTION_ROMS) {
5326 fprintf(stderr, "Too many option ROMs\n");
5327 exit(1);
5328 }
5329 option_rom[nb_option_roms] = optarg;
5330 nb_option_roms++;
5331 break;
blueswir15824d652009-03-28 06:44:27 +00005332#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00005333 case QEMU_OPTION_semihosting:
5334 semihosting_enabled = 1;
5335 break;
blueswir15824d652009-03-28 06:44:27 +00005336#endif
thsc35734b2007-03-19 15:17:08 +00005337 case QEMU_OPTION_name:
Andi Kleen18894652009-07-02 09:34:17 +02005338 qemu_name = qemu_strdup(optarg);
5339 {
5340 char *p = strchr(qemu_name, ',');
5341 if (p != NULL) {
5342 *p++ = 0;
5343 if (strncmp(p, "process=", 8)) {
5344 fprintf(stderr, "Unknown subargument %s to -name", p);
5345 exit(1);
5346 }
5347 p += 8;
5348 set_proc_name(p);
5349 }
5350 }
thsc35734b2007-03-19 15:17:08 +00005351 break;
blueswir195efd112008-12-24 20:26:14 +00005352#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +00005353 case QEMU_OPTION_prom_env:
5354 if (nb_prom_envs >= MAX_PROM_ENVS) {
5355 fprintf(stderr, "Too many prom variables\n");
5356 exit(1);
5357 }
5358 prom_envs[nb_prom_envs] = optarg;
5359 nb_prom_envs++;
5360 break;
5361#endif
balrog2b8f2d42007-07-27 22:08:46 +00005362#ifdef TARGET_ARM
5363 case QEMU_OPTION_old_param:
5364 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00005365 break;
balrog2b8f2d42007-07-27 22:08:46 +00005366#endif
thsf3dcfad2007-08-24 01:26:02 +00005367 case QEMU_OPTION_clock:
5368 configure_alarms(optarg);
5369 break;
bellard7e0af5d02007-11-07 16:24:33 +00005370 case QEMU_OPTION_startdate:
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005371 configure_rtc_date_offset(optarg, 1);
5372 break;
5373 case QEMU_OPTION_rtc:
5374 opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
5375 if (!opts) {
5376 fprintf(stderr, "parse error: %s\n", optarg);
5377 exit(1);
bellard7e0af5d02007-11-07 16:24:33 +00005378 }
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005379 configure_rtc(opts);
bellard7e0af5d02007-11-07 16:24:33 +00005380 break;
bellard26a5f132008-05-28 12:30:31 +00005381 case QEMU_OPTION_tb_size:
5382 tb_size = strtol(optarg, NULL, 0);
5383 if (tb_size < 0)
5384 tb_size = 0;
5385 break;
pbrook2e70f6e2008-06-29 01:03:05 +00005386 case QEMU_OPTION_icount:
5387 use_icount = 1;
5388 if (strcmp(optarg, "auto") == 0) {
5389 icount_time_shift = -1;
5390 } else {
5391 icount_time_shift = strtol(optarg, NULL, 0);
5392 }
5393 break;
aliguori5bb79102008-10-13 03:12:02 +00005394 case QEMU_OPTION_incoming:
5395 incoming = optarg;
5396 break;
blueswir15824d652009-03-28 06:44:27 +00005397#ifndef _WIN32
aliguori08585322009-02-27 22:09:45 +00005398 case QEMU_OPTION_chroot:
5399 chroot_dir = optarg;
5400 break;
5401 case QEMU_OPTION_runas:
5402 run_as = optarg;
5403 break;
blueswir15824d652009-03-28 06:44:27 +00005404#endif
aliguorie37630c2009-04-22 15:19:10 +00005405#ifdef CONFIG_XEN
5406 case QEMU_OPTION_xen_domid:
5407 xen_domid = atoi(optarg);
5408 break;
5409 case QEMU_OPTION_xen_create:
5410 xen_mode = XEN_CREATE;
5411 break;
5412 case QEMU_OPTION_xen_attach:
5413 xen_mode = XEN_ATTACH;
5414 break;
5415#endif
bellardcd6f1162004-05-13 22:02:20 +00005416 }
bellard0824d6f2003-06-24 13:42:40 +00005417 }
5418 }
bellard330d0412003-07-26 18:11:40 +00005419
Paul Brook5cea8592009-05-30 00:52:44 +01005420 /* If no data_dir is specified then try to find it relative to the
5421 executable path. */
5422 if (!data_dir) {
5423 data_dir = find_datadir(argv[0]);
5424 }
5425 /* If all else fails use the install patch specified when building. */
5426 if (!data_dir) {
5427 data_dir = CONFIG_QEMU_SHAREDIR;
5428 }
5429
Jes Sorensen6be68d72009-07-23 17:03:42 +02005430 /*
5431 * Default to max_cpus = smp_cpus, in case the user doesn't
5432 * specify a max_cpus value.
5433 */
5434 if (!max_cpus)
5435 max_cpus = smp_cpus;
5436
balrog3d878ca2008-10-28 10:59:59 +00005437 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
aliguorib2097002008-10-07 20:39:39 +00005438 if (smp_cpus > machine->max_cpus) {
5439 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
5440 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
5441 machine->max_cpus);
5442 exit(1);
5443 }
5444
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005445 if (display_type == DT_NOGRAPHIC) {
aliguoribc0129d2008-08-01 15:12:34 +00005446 if (serial_device_index == 0)
5447 serial_devices[0] = "stdio";
5448 if (parallel_device_index == 0)
5449 parallel_devices[0] = "null";
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005450 if (strncmp(monitor_devices[0], "vc", 2) == 0) {
5451 monitor_devices[0] = "stdio";
5452 }
aliguoribc0129d2008-08-01 15:12:34 +00005453 }
5454
ths71e3ceb2006-12-22 02:11:31 +00005455#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005456 if (daemonize) {
5457 pid_t pid;
5458
5459 if (pipe(fds) == -1)
5460 exit(1);
5461
5462 pid = fork();
5463 if (pid > 0) {
5464 uint8_t status;
5465 ssize_t len;
5466
5467 close(fds[1]);
5468
5469 again:
ths93815bc2007-03-19 15:58:31 +00005470 len = read(fds[0], &status, 1);
5471 if (len == -1 && (errno == EINTR))
5472 goto again;
5473
5474 if (len != 1)
5475 exit(1);
5476 else if (status == 1) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005477 fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
ths93815bc2007-03-19 15:58:31 +00005478 exit(1);
5479 } else
5480 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00005481 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00005482 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00005483
5484 setsid();
5485
5486 pid = fork();
5487 if (pid > 0)
5488 exit(0);
5489 else if (pid < 0)
5490 exit(1);
5491
5492 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00005493
5494 signal(SIGTSTP, SIG_IGN);
5495 signal(SIGTTOU, SIG_IGN);
5496 signal(SIGTTIN, SIG_IGN);
5497 }
ths71e3ceb2006-12-22 02:11:31 +00005498
thsaa26bb22007-03-25 21:33:06 +00005499 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00005500 if (daemonize) {
5501 uint8_t status = 1;
5502 write(fds[1], &status, 1);
5503 } else
Justin M. Forbes850810d2009-10-01 09:42:56 -05005504 fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
ths93815bc2007-03-19 15:58:31 +00005505 exit(1);
5506 }
blueswir1b9e82a52009-04-05 18:03:31 +00005507#endif
ths93815bc2007-03-19 15:58:31 +00005508
Marcelo Tosatti214910a2009-09-18 02:41:23 -03005509 if (kvm_enabled()) {
5510 int ret;
5511
5512 ret = kvm_init(smp_cpus);
5513 if (ret < 0) {
5514 fprintf(stderr, "failed to initialize KVM\n");
5515 exit(1);
5516 }
5517 }
5518
aliguori3fcf7b62009-04-24 18:03:25 +00005519 if (qemu_init_main_loop()) {
5520 fprintf(stderr, "qemu_init_main_loop failed\n");
5521 exit(1);
5522 }
bellarda20dd502003-09-30 21:07:02 +00005523 linux_boot = (kernel_filename != NULL);
balrog6c41b272007-11-17 12:12:29 +00005524
thsf8d39c02008-07-03 10:01:15 +00005525 if (!linux_boot && *kernel_cmdline != '\0') {
5526 fprintf(stderr, "-append only allowed with -kernel option\n");
5527 exit(1);
5528 }
5529
5530 if (!linux_boot && initrd_filename != NULL) {
5531 fprintf(stderr, "-initrd only allowed with -kernel option\n");
5532 exit(1);
5533 }
5534
Filip Navarabf65f532009-07-27 10:02:04 -05005535#ifndef _WIN32
5536 /* Win32 doesn't support line-buffering and requires size >= 2 */
bellardb118d612003-06-30 23:36:21 +00005537 setvbuf(stdout, NULL, _IOLBF, 0);
Filip Navarabf65f532009-07-27 10:02:04 -05005538#endif
ths3b46e622007-09-17 08:09:54 +00005539
aliguori7183b4b2008-11-05 20:40:18 +00005540 if (init_timer_alarm() < 0) {
5541 fprintf(stderr, "could not initialize alarm timer\n");
5542 exit(1);
5543 }
pbrook2e70f6e2008-06-29 01:03:05 +00005544 if (use_icount && icount_time_shift < 0) {
5545 use_icount = 2;
5546 /* 125MIPS seems a reasonable initial guess at the guest speed.
5547 It will be corrected fairly quickly anyway. */
5548 icount_time_shift = 3;
5549 init_icount_adjust();
5550 }
pbrook634fce92006-07-15 17:40:09 +00005551
bellardfd1dff42006-02-01 21:29:26 +00005552#ifdef _WIN32
5553 socket_init();
5554#endif
5555
Mark McLoughlindc1c9fe2009-10-06 12:17:16 +01005556 if (net_init_clients() < 0) {
5557 exit(1);
bellard702c6512004-04-02 21:21:32 +00005558 }
bellardf1510b22003-06-25 00:07:40 +00005559
Glauber Costa406c8df2009-06-17 09:05:30 -04005560 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
5561 net_set_boot_mask(net_boot);
5562
balrogdc72ac12008-11-09 00:04:26 +00005563 /* init the bluetooth world */
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005564 if (foreach_device_config(DEV_BT, bt_parse))
5565 exit(1);
balrogdc72ac12008-11-09 00:04:26 +00005566
bellard0824d6f2003-06-24 13:42:40 +00005567 /* init the memory */
pbrook94a6b542009-04-11 17:15:54 +00005568 if (ram_size == 0)
5569 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
balrog7fb4fdc2008-04-24 17:59:27 +00005570
bellard26a5f132008-05-28 12:30:31 +00005571 /* init the dynamic translator */
5572 cpu_exec_init_all(tb_size * 1024 * 1024);
5573
bellard5905b2e2004-08-01 21:53:26 +00005574 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00005575
5576 /* we always create the cdrom drive, even if no disk is there */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005577 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00005578
balrog9d413d12007-12-04 00:10:34 +00005579 /* we always create at least one floppy */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005580 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00005581
balrog9d413d12007-12-04 00:10:34 +00005582 /* we always create one sd slot, even if no card is in it */
Gerd Hoffmann3b0ba922009-07-22 16:42:59 +02005583 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00005584
ths96d30e42007-01-07 20:42:14 +00005585 /* open the virtual block devices */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005586 if (snapshot)
Gerd Hoffmann7282a032009-07-31 12:25:35 +02005587 qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0);
5588 if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005589 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00005590
Juan Quintela2faf58c2009-09-10 03:04:28 +02005591 vmstate_register(0, &vmstate_timers ,&timers_state);
aliguori475e4272008-10-06 20:21:51 +00005592 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00005593
aliguori3023f332009-01-16 19:04:14 +00005594 /* Maintain compatibility with multiple stdio monitors */
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005595 if (!strcmp(monitor_devices[0],"stdio")) {
aliguori3023f332009-01-16 19:04:14 +00005596 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
5597 const char *devname = serial_devices[i];
5598 if (devname && !strcmp(devname,"mon:stdio")) {
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005599 monitor_devices[0] = NULL;
aliguori3023f332009-01-16 19:04:14 +00005600 break;
5601 } else if (devname && !strcmp(devname,"stdio")) {
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005602 monitor_devices[0] = NULL;
aliguori3023f332009-01-16 19:04:14 +00005603 serial_devices[i] = "mon:stdio";
5604 break;
5605 }
5606 }
5607 }
5608
aliguori268a3622009-04-21 22:30:27 +00005609 if (nb_numa_nodes > 0) {
5610 int i;
5611
5612 if (nb_numa_nodes > smp_cpus) {
5613 nb_numa_nodes = smp_cpus;
5614 }
5615
5616 /* If no memory size if given for any node, assume the default case
5617 * and distribute the available memory equally across all nodes
5618 */
5619 for (i = 0; i < nb_numa_nodes; i++) {
5620 if (node_mem[i] != 0)
5621 break;
5622 }
5623 if (i == nb_numa_nodes) {
5624 uint64_t usedmem = 0;
5625
5626 /* On Linux, the each node's border has to be 8MB aligned,
5627 * the final node gets the rest.
5628 */
5629 for (i = 0; i < nb_numa_nodes - 1; i++) {
5630 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
5631 usedmem += node_mem[i];
5632 }
5633 node_mem[i] = ram_size - usedmem;
5634 }
5635
5636 for (i = 0; i < nb_numa_nodes; i++) {
5637 if (node_cpumask[i] != 0)
5638 break;
5639 }
5640 /* assigning the VCPUs round-robin is easier to implement, guest OSes
5641 * must cope with this anyway, because there are BIOSes out there in
5642 * real machines which also use this scheme.
5643 */
5644 if (i == nb_numa_nodes) {
5645 for (i = 0; i < smp_cpus; i++) {
5646 node_cpumask[i % nb_numa_nodes] |= 1 << i;
5647 }
5648 }
5649 }
5650
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005651 for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
5652 const char *devname = monitor_devices[i];
5653 if (devname && strcmp(devname, "none")) {
5654 char label[32];
5655 if (i == 0) {
5656 snprintf(label, sizeof(label), "monitor");
5657 } else {
5658 snprintf(label, sizeof(label), "monitor%d", i);
5659 }
5660 monitor_hds[i] = qemu_chr_open(label, devname, NULL);
5661 if (!monitor_hds[i]) {
5662 fprintf(stderr, "qemu: could not open monitor device '%s'\n",
5663 devname);
5664 exit(1);
5665 }
aliguori4c621802009-01-16 21:48:20 +00005666 }
5667 }
5668
aliguori2796dae2009-01-16 20:23:27 +00005669 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5670 const char *devname = serial_devices[i];
5671 if (devname && strcmp(devname, "none")) {
Aurelien Jarno324a8022009-09-14 23:49:43 +02005672 char label[32];
5673 snprintf(label, sizeof(label), "serial%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005674 serial_hds[i] = qemu_chr_open(label, devname, NULL);
Aurelien Jarno324a8022009-09-14 23:49:43 +02005675 if (!serial_hds[i]) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005676 fprintf(stderr, "qemu: could not open serial device '%s': %s\n",
5677 devname, strerror(errno));
Aurelien Jarno324a8022009-09-14 23:49:43 +02005678 exit(1);
5679 }
aliguori2796dae2009-01-16 20:23:27 +00005680 }
5681 }
5682
5683 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5684 const char *devname = parallel_devices[i];
5685 if (devname && strcmp(devname, "none")) {
5686 char label[32];
5687 snprintf(label, sizeof(label), "parallel%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005688 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
aliguori2796dae2009-01-16 20:23:27 +00005689 if (!parallel_hds[i]) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005690 fprintf(stderr, "qemu: could not open parallel device '%s': %s\n",
5691 devname, strerror(errno));
aliguori2796dae2009-01-16 20:23:27 +00005692 exit(1);
5693 }
5694 }
5695 }
5696
5697 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5698 const char *devname = virtio_consoles[i];
5699 if (devname && strcmp(devname, "none")) {
5700 char label[32];
5701 snprintf(label, sizeof(label), "virtcon%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005702 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
aliguori2796dae2009-01-16 20:23:27 +00005703 if (!virtcon_hds[i]) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005704 fprintf(stderr, "qemu: could not open virtio console '%s': %s\n",
5705 devname, strerror(errno));
aliguori2796dae2009-01-16 20:23:27 +00005706 exit(1);
5707 }
5708 }
5709 }
5710
Paul Brookaae94602009-05-14 22:35:06 +01005711 module_call_init(MODULE_INIT_DEVICE);
5712
Markus Armbruster09aaa162009-08-21 10:31:34 +02005713 if (watchdog) {
5714 i = select_watchdog(watchdog);
5715 if (i > 0)
5716 exit (i == 1 ? 1 : 0);
5717 }
5718
Gerd Hoffmannb6b61142009-07-15 13:48:21 +02005719 if (machine->compat_props) {
5720 qdev_prop_register_compat(machine->compat_props);
5721 }
Paul Brookfbe1b592009-05-13 17:56:25 +01005722 machine->init(ram_size, boot_devices,
aliguori3023f332009-01-16 19:04:14 +00005723 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
5724
aliguori268a3622009-04-21 22:30:27 +00005725
Juan Quintela67b3b712009-08-28 19:25:15 +02005726#ifndef _WIN32
5727 /* must be after terminal init, SDL library changes signal handlers */
5728 sighandler_setup();
5729#endif
5730
aliguori268a3622009-04-21 22:30:27 +00005731 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5732 for (i = 0; i < nb_numa_nodes; i++) {
5733 if (node_cpumask[i] & (1 << env->cpu_index)) {
5734 env->numa_node = i;
5735 }
5736 }
5737 }
5738
aliguori6f338c32009-02-11 15:21:54 +00005739 current_machine = machine;
5740
aliguori3023f332009-01-16 19:04:14 +00005741 /* init USB devices */
5742 if (usb_enabled) {
Markus Armbruster07527062009-10-06 12:16:57 +01005743 if (foreach_device_config(DEV_USB, usb_parse) < 0)
5744 exit(1);
aliguori3023f332009-01-16 19:04:14 +00005745 }
5746
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005747 /* init generic devices */
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005748 if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0)
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005749 exit(1);
5750
aliguori8f391ab2009-01-19 16:34:10 +00005751 if (!display_state)
5752 dumb_display_init();
aliguori3023f332009-01-16 19:04:14 +00005753 /* just use the first displaystate for the moment */
5754 ds = display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005755
5756 if (display_type == DT_DEFAULT) {
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005757#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005758 display_type = DT_SDL;
5759#else
5760 display_type = DT_VNC;
5761 vnc_display = "localhost:0,to=99";
5762 show_vnc_port = 1;
5763#endif
5764 }
5765
5766
5767 switch (display_type) {
5768 case DT_NOGRAPHIC:
5769 break;
5770#if defined(CONFIG_CURSES)
5771 case DT_CURSES:
5772 curses_display_init(ds, full_screen);
5773 break;
5774#endif
bellard5b0753e2005-03-01 21:37:28 +00005775#if defined(CONFIG_SDL)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005776 case DT_SDL:
5777 sdl_display_init(ds, full_screen, no_frame);
5778 break;
bellard5b0753e2005-03-01 21:37:28 +00005779#elif defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005780 case DT_SDL:
5781 cocoa_display_init(ds, full_screen);
5782 break;
bellard313aa562003-08-10 21:52:11 +00005783#endif
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005784 case DT_VNC:
5785 vnc_display_init(ds);
5786 if (vnc_display_open(ds, vnc_display) < 0)
5787 exit(1);
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005788
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005789 if (show_vnc_port) {
5790 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005791 }
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005792 break;
5793 default:
5794 break;
bellard313aa562003-08-10 21:52:11 +00005795 }
aliguori7d957bd2009-01-15 22:14:11 +00005796 dpy_resize(ds);
aliguori5b08fc12008-08-21 20:08:03 +00005797
aliguori3023f332009-01-16 19:04:14 +00005798 dcl = ds->listeners;
5799 while (dcl != NULL) {
5800 if (dcl->dpy_refresh != NULL) {
5801 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5802 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
ths20d8a3e2007-02-18 17:04:49 +00005803 }
aliguori3023f332009-01-16 19:04:14 +00005804 dcl = dcl->next;
bellard82c643f2004-07-14 17:28:13 +00005805 }
aliguori3023f332009-01-16 19:04:14 +00005806
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005807 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
blueswir19043b622009-01-21 19:28:13 +00005808 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5809 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5810 }
5811
aliguori2796dae2009-01-16 20:23:27 +00005812 text_consoles_set_display(display_state);
aliguori2970a6c2009-03-05 22:59:58 +00005813 qemu_chr_initial_reset();
aliguori2796dae2009-01-16 20:23:27 +00005814
Jan Kiszkaddd9bbd2009-08-27 19:51:16 +02005815 for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
5816 if (monitor_devices[i] && monitor_hds[i]) {
5817 monitor_init(monitor_hds[i],
5818 MONITOR_USE_READLINE |
5819 ((i == 0) ? MONITOR_IS_DEFAULT : 0));
5820 }
5821 }
bellard82c643f2004-07-14 17:28:13 +00005822
bellard8d11df92004-08-24 21:13:40 +00005823 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005824 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005825 if (devname && strcmp(devname, "none")) {
thsaf3a9032007-07-11 23:14:59 +00005826 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005827 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00005828 }
bellard82c643f2004-07-14 17:28:13 +00005829 }
bellard82c643f2004-07-14 17:28:13 +00005830
bellard6508fe52005-01-15 12:02:56 +00005831 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005832 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005833 if (devname && strcmp(devname, "none")) {
thsaf3a9032007-07-11 23:14:59 +00005834 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005835 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00005836 }
5837 }
5838
aliguori9ede2fd2009-01-15 20:05:25 +00005839 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5840 const char *devname = virtio_consoles[i];
aliguori2796dae2009-01-16 20:23:27 +00005841 if (virtcon_hds[i] && devname) {
aliguori9ede2fd2009-01-15 20:05:25 +00005842 if (strstart(devname, "vc", 0))
5843 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
5844 }
5845 }
5846
aliguori59030a82009-04-05 18:43:41 +00005847 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
5848 fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
5849 gdbstub_dev);
5850 exit(1);
balrog45669e02007-07-02 13:20:17 +00005851 }
balrog45669e02007-07-02 13:20:17 +00005852
Gerd Hoffmann3418bd22009-09-25 21:42:41 +02005853 qdev_machine_creation_done();
5854
Gerd Hoffmann45a50b12009-10-01 16:42:33 +02005855 rom_load_all();
5856
Juan Quintela05f24012009-08-20 19:42:22 +02005857 if (loadvm) {
5858 if (load_vmstate(cur_mon, loadvm) < 0) {
5859 autostart = 0;
5860 }
5861 }
bellardd63d3072004-10-03 13:29:03 +00005862
Glauber Costa2bb8c102009-07-24 16:20:23 -04005863 if (incoming) {
aliguori5bb79102008-10-13 03:12:02 +00005864 qemu_start_incoming_migration(incoming);
Avi Kivity6b99dad2009-08-09 14:39:20 +03005865 } else if (autostart) {
aliguoric0f4ce72009-03-05 23:01:01 +00005866 vm_start();
Avi Kivity6b99dad2009-08-09 14:39:20 +03005867 }
thsffd843b2006-12-21 19:46:43 +00005868
blueswir1b9e82a52009-04-05 18:03:31 +00005869#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005870 if (daemonize) {
5871 uint8_t status = 0;
5872 ssize_t len;
ths71e3ceb2006-12-22 02:11:31 +00005873
5874 again1:
5875 len = write(fds[1], &status, 1);
5876 if (len == -1 && (errno == EINTR))
5877 goto again1;
5878
5879 if (len != 1)
5880 exit(1);
5881
aliguoribd54b862008-07-23 00:58:33 +00005882 chdir("/");
balrogaeb30be2007-07-02 15:03:13 +00005883 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00005884 if (fd == -1)
5885 exit(1);
aliguori08585322009-02-27 22:09:45 +00005886 }
ths71e3ceb2006-12-22 02:11:31 +00005887
aliguori08585322009-02-27 22:09:45 +00005888 if (run_as) {
5889 pwd = getpwnam(run_as);
5890 if (!pwd) {
5891 fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
5892 exit(1);
5893 }
5894 }
ths71e3ceb2006-12-22 02:11:31 +00005895
aliguori08585322009-02-27 22:09:45 +00005896 if (chroot_dir) {
5897 if (chroot(chroot_dir) < 0) {
5898 fprintf(stderr, "chroot failed\n");
5899 exit(1);
5900 }
5901 chdir("/");
5902 }
5903
5904 if (run_as) {
5905 if (setgid(pwd->pw_gid) < 0) {
5906 fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
5907 exit(1);
5908 }
5909 if (setuid(pwd->pw_uid) < 0) {
5910 fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
5911 exit(1);
5912 }
5913 if (setuid(0) != -1) {
5914 fprintf(stderr, "Dropping privileges failed\n");
5915 exit(1);
5916 }
5917 }
aliguori08585322009-02-27 22:09:45 +00005918
5919 if (daemonize) {
5920 dup2(fd, 0);
5921 dup2(fd, 1);
5922 dup2(fd, 2);
5923
5924 close(fd);
ths71e3ceb2006-12-22 02:11:31 +00005925 }
blueswir1b9e82a52009-04-05 18:03:31 +00005926#endif
ths71e3ceb2006-12-22 02:11:31 +00005927
bellard8a7ddc32004-03-31 19:00:16 +00005928 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00005929 quit_timers();
aliguori63a01ef2008-10-31 19:10:00 +00005930 net_cleanup();
thsb46a8902007-10-21 23:20:45 +00005931
bellard0824d6f2003-06-24 13:42:40 +00005932 return 0;
5933}