blob: ab77c35e16bea3ba7da167bd608e70037936ecde [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>
Aurelien Jarnoa167ba52009-11-29 18:00:41 +010053#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || 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
Aurelien Jarnobbe813a2009-11-30 15:42:59 +010058#else
blueswir1223f0d72008-09-30 18:12:18 +000059#ifdef __linux__
bellard7d3505c2004-05-12 19:32:15 +000060#include <pty.h>
61#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000062#include <linux/rtc.h>
Andi Kleen18894652009-07-02 09:34:17 +020063#include <sys/prctl.h>
thsbd494f42007-09-16 20:03:23 +000064
65/* For the benefit of older linux systems which don't supply it,
66 we use a local copy of hpet.h. */
67/* #include <linux/hpet.h> */
68#include "hpet.h"
69
bellarde57a8c02005-11-10 23:58:52 +000070#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000071#include <linux/parport.h>
blueswir1223f0d72008-09-30 18:12:18 +000072#endif
73#ifdef __sun__
thsd5d10bc2007-02-17 22:54:49 +000074#include <sys/stat.h>
75#include <sys/ethernet.h>
76#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000077#include <netinet/arp.h>
78#include <netinet/in.h>
79#include <netinet/in_systm.h>
80#include <netinet/ip.h>
81#include <netinet/ip_icmp.h> // must come after ip.h
82#include <netinet/udp.h>
83#include <netinet/tcp.h>
84#include <net/if.h>
85#include <syslog.h>
86#include <stropts.h>
Blue Swirl8d32cf02009-10-02 19:32:12 +000087/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
88 discussion about Solaris header problems */
89extern int madvise(caddr_t, size_t, int);
bellard67b915a2004-03-31 23:37:16 +000090#endif
bellard7d3505c2004-05-12 19:32:15 +000091#endif
bellardec530c82006-04-25 22:36:06 +000092#endif
bellard67b915a2004-03-31 23:37:16 +000093
blueswir19892fbf2008-08-24 10:34:20 +000094#if defined(__OpenBSD__)
95#include <util.h>
96#endif
97
ths8a16d272008-07-19 09:56:24 +000098#if defined(CONFIG_VDE)
99#include <libvdeplug.h>
100#endif
101
bellard67b915a2004-03-31 23:37:16 +0000102#ifdef _WIN32
aliguori49dc7682009-03-08 16:26:59 +0000103#include <windows.h>
ths4fddf622007-12-17 04:42:29 +0000104#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000105#endif
106
bellard73332e52004-04-04 20:22:28 +0000107#ifdef CONFIG_SDL
Stefan Weil59a36a22009-06-18 20:11:03 +0200108#if defined(__APPLE__) || defined(main)
Stefan Weil66936652009-06-13 13:19:11 +0200109#include <SDL.h>
malc880fec52009-02-15 20:18:41 +0000110int qemu_main(int argc, char **argv, char **envp);
111int main(int argc, char **argv)
112{
Stefan Weil59a36a22009-06-18 20:11:03 +0200113 return qemu_main(argc, argv, NULL);
malc880fec52009-02-15 20:18:41 +0000114}
115#undef main
116#define main qemu_main
bellard96bcd4f2004-07-10 16:26:15 +0000117#endif
bellard73332e52004-04-04 20:22:28 +0000118#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000119
bellard5b0753e2005-03-01 21:37:28 +0000120#ifdef CONFIG_COCOA
121#undef main
122#define main qemu_main
123#endif /* CONFIG_COCOA */
124
blueswir1511d2b12009-03-07 15:32:56 +0000125#include "hw/hw.h"
126#include "hw/boards.h"
127#include "hw/usb.h"
128#include "hw/pcmcia.h"
129#include "hw/pc.h"
130#include "hw/audiodev.h"
131#include "hw/isa.h"
132#include "hw/baum.h"
133#include "hw/bt.h"
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +0100134#include "hw/watchdog.h"
aliguorib6f6e3d2009-04-17 18:59:56 +0000135#include "hw/smbios.h"
aliguorie37630c2009-04-22 15:19:10 +0000136#include "hw/xen.h"
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +0200137#include "hw/qdev.h"
Gerd Hoffmann45a50b12009-10-01 16:42:33 +0200138#include "hw/loader.h"
aurel325ef4efa2009-03-10 21:43:35 +0000139#include "bt-host.h"
blueswir1511d2b12009-03-07 15:32:56 +0000140#include "net.h"
Mark McLoughlin68ac40d2009-11-25 18:48:54 +0000141#include "net/slirp.h"
blueswir1511d2b12009-03-07 15:32:56 +0000142#include "monitor.h"
143#include "console.h"
144#include "sysemu.h"
145#include "gdbstub.h"
146#include "qemu-timer.h"
147#include "qemu-char.h"
148#include "cache-utils.h"
149#include "block.h"
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +0200150#include "block_int.h"
151#include "block-migration.h"
blueswir1a718ace2009-03-28 08:24:44 +0000152#include "dma.h"
blueswir1511d2b12009-03-07 15:32:56 +0000153#include "audio/audio.h"
154#include "migration.h"
155#include "kvm.h"
156#include "balloon.h"
Kevin Wolfd3f24362009-05-18 16:42:09 +0200157#include "qemu-option.h"
Gerd Hoffmann7282a032009-07-31 12:25:35 +0200158#include "qemu-config.h"
blueswir1511d2b12009-03-07 15:32:56 +0000159
bellard0824d6f2003-06-24 13:42:40 +0000160#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000161
bellard8a7ddc32004-03-31 19:00:16 +0000162#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000163
blueswir1511d2b12009-03-07 15:32:56 +0000164#include "qemu_socket.h"
165
Jan Kiszkad918f232009-06-24 14:42:30 +0200166#include "slirp/libslirp.h"
blueswir1511d2b12009-03-07 15:32:56 +0000167
Blue Swirl72cf2d42009-09-12 07:36:22 +0000168#include "qemu-queue.h"
169
blueswir19dc63a12008-10-04 07:25:46 +0000170//#define DEBUG_NET
171//#define DEBUG_SLIRP
bellard330d0412003-07-26 18:11:40 +0000172
bellard1bfe8562004-07-08 21:17:50 +0000173#define DEFAULT_RAM_SIZE 128
bellard313aa562003-08-10 21:52:11 +0000174
Paul Brook5cea8592009-05-30 00:52:44 +0100175static const char *data_dir;
j_mayer1192dad2007-10-05 13:08:35 +0000176const char *bios_name = NULL;
thse4bcb142007-12-02 04:51:10 +0000177/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000178 to store the VM snapshots */
Blue Swirl72cf2d42009-09-12 07:36:22 +0000179struct drivelist drives = QTAILQ_HEAD_INITIALIZER(drives);
180struct driveoptlist driveopts = QTAILQ_HEAD_INITIALIZER(driveopts);
malccb5a7aa2008-09-28 00:42:12 +0000181enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
aliguori3023f332009-01-16 19:04:14 +0000182static DisplayState *display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -0500183DisplayType display_type = DT_DEFAULT;
bellard3d11d0e2004-12-12 16:56:30 +0000184const char* keyboard_layout = NULL;
Anthony Liguoric227f092009-10-01 16:12:16 -0500185ram_addr_t ram_size;
bellardc4b1fcc2004-03-14 21:44:30 +0000186int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000187NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000188int vm_running;
Paolo Bonzinid399f672009-07-27 23:17:51 +0200189int autostart;
balrogf6503052008-02-17 11:42:19 +0000190static int rtc_utc = 1;
191static int rtc_date_offset = -1; /* -1 means no change */
Jan Kiszka68752042009-09-15 13:36:04 +0200192QEMUClock *rtc_clock;
Gerd Hoffmann64465292009-12-08 13:11:45 +0100193int vga_interface_type = VGA_NONE;
bellardd8272202005-04-06 20:32:23 +0000194#ifdef TARGET_SPARC
195int graphic_width = 1024;
196int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000197int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000198#else
bellard1bfe8562004-07-08 21:17:50 +0000199int graphic_width = 800;
200int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000201int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000202#endif
blueswir1dbed7e42008-10-01 19:38:09 +0000203static int full_screen = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000204#ifdef CONFIG_SDL
blueswir1dbed7e42008-10-01 19:38:09 +0000205static int no_frame = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000206#endif
ths667acca2006-12-11 02:08:05 +0000207int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000208CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000209CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
aliguori9ede2fd2009-01-15 20:05:25 +0000210CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
bellarda09db212005-04-30 16:10:35 +0000211#ifdef TARGET_I386
212int win2k_install_hack = 0;
aliguori73822ec2009-01-15 20:11:34 +0000213int rtc_td_hack = 0;
bellarda09db212005-04-30 16:10:35 +0000214#endif
bellardbb36d472005-11-05 14:22:28 +0000215int usb_enabled = 0;
aurel321b530a62009-04-05 20:08:59 +0000216int singlestep = 0;
bellard6a00d602005-11-21 23:25:50 +0000217int smp_cpus = 1;
Jes Sorensen6be68d72009-07-23 17:03:42 +0200218int max_cpus = 0;
Andre Przywaradc6b1c02009-08-19 15:42:40 +0200219int smp_cores = 1;
220int smp_threads = 1;
ths73fc9742006-12-22 02:09:07 +0000221const char *vnc_display;
bellard6515b202006-05-03 22:02:44 +0000222int acpi_enabled = 1;
aliguori16b29ae2008-12-17 23:28:44 +0000223int no_hpet = 0;
bellard52ca8d62006-06-14 16:03:05 +0000224int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000225int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000226int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000227int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000228int graphic_rotate = 0;
Jes Sorensen6b35e7b2009-08-06 16:25:50 +0200229uint8_t irq0override = 1;
blueswir1b9e82a52009-04-05 18:03:31 +0000230#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +0000231int daemonize = 0;
blueswir1b9e82a52009-04-05 18:03:31 +0000232#endif
Markus Armbruster09aaa162009-08-21 10:31:34 +0200233const char *watchdog;
ths9ae02552007-01-05 17:39:04 +0000234const char *option_rom[MAX_OPTION_ROMS];
235int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000236int semihosting_enabled = 0;
balrog2b8f2d42007-07-27 22:08:46 +0000237#ifdef TARGET_ARM
238int old_param = 0;
239#endif
thsc35734b2007-03-19 15:17:08 +0000240const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000241int alt_grab = 0;
Dustin Kirkland0ca9f8a2009-09-17 15:48:04 -0500242int ctrl_grab = 0;
blueswir195efd112008-12-24 20:26:14 +0000243#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +0000244unsigned int nb_prom_envs = 0;
245const char *prom_envs[MAX_PROM_ENVS];
246#endif
Jan Kiszka95387492009-07-02 00:19:02 +0200247int boot_menu;
bellard0824d6f2003-06-24 13:42:40 +0000248
aliguori268a3622009-04-21 22:30:27 +0000249int nb_numa_nodes;
250uint64_t node_mem[MAX_NODES];
251uint64_t node_cpumask[MAX_NODES];
252
balrogee5605e2007-12-03 03:01:40 +0000253static CPUState *cur_cpu;
254static CPUState *next_cpu;
aliguori43b96852009-04-24 18:03:33 +0000255static int timer_alarm_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000256/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000257static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000258/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000259#define MAX_ICOUNT_SHIFT 10
260/* Compensate for varying guest execution speed. */
261static int64_t qemu_icount_bias;
blueswir1dbed7e42008-10-01 19:38:09 +0000262static QEMUTimer *icount_rt_timer;
263static QEMUTimer *icount_vm_timer;
blueswir19043b622009-01-21 19:28:13 +0000264static QEMUTimer *nographic_timer;
balrogee5605e2007-12-03 03:01:40 +0000265
blueswir18fcb1b92008-09-18 18:29:08 +0000266uint8_t qemu_uuid[16];
267
Jan Kiszka76e30d02009-07-02 00:19:02 +0200268static QEMUBootSetHandler *boot_set_handler;
269static void *boot_set_opaque;
270
Gerd Hoffmann998bbd72009-12-08 13:11:41 +0100271static int default_serial = 1;
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +0100272static int default_parallel = 1;
Gerd Hoffmannabdeed02009-12-08 13:11:43 +0100273static int default_monitor = 1;
Gerd Hoffmann64465292009-12-08 13:11:45 +0100274static int default_vga = 1;
Gerd Hoffmannaa40fc92009-12-08 13:11:48 +0100275static int default_drive = 1;
Gerd Hoffmann998bbd72009-12-08 13:11:41 +0100276
277static struct {
278 const char *driver;
279 int *flag;
280} default_list[] = {
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +0100281 { .driver = "isa-serial", .flag = &default_serial },
282 { .driver = "isa-parallel", .flag = &default_parallel },
Gerd Hoffmann64465292009-12-08 13:11:45 +0100283 { .driver = "VGA", .flag = &default_vga },
284 { .driver = "Cirrus VGA", .flag = &default_vga },
285 { .driver = "QEMUware SVGA", .flag = &default_vga },
Gerd Hoffmann998bbd72009-12-08 13:11:41 +0100286};
287
288static int default_driver_check(QemuOpts *opts, void *opaque)
289{
290 const char *driver = qemu_opt_get(opts, "driver");
291 int i;
292
293 if (!driver)
294 return 0;
295 for (i = 0; i < ARRAY_SIZE(default_list); i++) {
296 if (strcmp(default_list[i].driver, driver) != 0)
297 continue;
298 *(default_list[i].flag) = 0;
299 }
300 return 0;
301}
302
bellard0824d6f2003-06-24 13:42:40 +0000303/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000304/* x86 ISA bus support */
305
Anthony Liguoric227f092009-10-01 16:12:16 -0500306target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000307PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000308
bellard0824d6f2003-06-24 13:42:40 +0000309/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000310void hw_error(const char *fmt, ...)
311{
312 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000313 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000314
315 va_start(ap, fmt);
316 fprintf(stderr, "qemu: hardware error: ");
317 vfprintf(stderr, fmt, ap);
318 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000319 for(env = first_cpu; env != NULL; env = env->next_cpu) {
320 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000321#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000322 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000323#else
bellard6a00d602005-11-21 23:25:50 +0000324 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000325#endif
bellard6a00d602005-11-21 23:25:50 +0000326 }
bellard0824d6f2003-06-24 13:42:40 +0000327 va_end(ap);
328 abort();
329}
Andi Kleen18894652009-07-02 09:34:17 +0200330
331static void set_proc_name(const char *s)
332{
Nathan Froyd6ca8d0f2009-08-03 07:32:12 -0700333#if defined(__linux__) && defined(PR_SET_NAME)
Andi Kleen18894652009-07-02 09:34:17 +0200334 char name[16];
335 if (!s)
336 return;
337 name[sizeof(name) - 1] = 0;
338 strncpy(name, s, sizeof(name));
339 /* Could rewrite argv[0] too, but that's a bit more complicated.
340 This simple way is enough for `top'. */
341 prctl(PR_SET_NAME, name);
342#endif
343}
aliguoridf751fa2008-12-04 20:19:35 +0000344
345/***************/
346/* ballooning */
347
348static QEMUBalloonEvent *qemu_balloon_event;
349void *qemu_balloon_event_opaque;
350
351void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
352{
353 qemu_balloon_event = func;
354 qemu_balloon_event_opaque = opaque;
355}
356
Anthony Liguoric227f092009-10-01 16:12:16 -0500357void qemu_balloon(ram_addr_t target)
aliguoridf751fa2008-12-04 20:19:35 +0000358{
359 if (qemu_balloon_event)
360 qemu_balloon_event(qemu_balloon_event_opaque, target);
361}
362
Anthony Liguoric227f092009-10-01 16:12:16 -0500363ram_addr_t qemu_balloon_status(void)
aliguoridf751fa2008-12-04 20:19:35 +0000364{
365 if (qemu_balloon_event)
366 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
367 return 0;
368}
bellard0824d6f2003-06-24 13:42:40 +0000369
bellard8a7ddc32004-03-31 19:00:16 +0000370/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000371/* keyboard/mouse */
372
373static QEMUPutKBDEvent *qemu_put_kbd_event;
374static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000375static QEMUPutMouseEntry *qemu_put_mouse_event_head;
376static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000377
378void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
379{
380 qemu_put_kbd_event_opaque = opaque;
381 qemu_put_kbd_event = func;
382}
383
ths455204e2007-01-05 16:42:13 +0000384QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
385 void *opaque, int absolute,
386 const char *name)
bellard63066f42004-06-03 18:45:02 +0000387{
ths455204e2007-01-05 16:42:13 +0000388 QEMUPutMouseEntry *s, *cursor;
389
390 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
ths455204e2007-01-05 16:42:13 +0000391
392 s->qemu_put_mouse_event = func;
393 s->qemu_put_mouse_event_opaque = opaque;
394 s->qemu_put_mouse_event_absolute = absolute;
395 s->qemu_put_mouse_event_name = qemu_strdup(name);
396 s->next = NULL;
397
398 if (!qemu_put_mouse_event_head) {
399 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
400 return s;
401 }
402
403 cursor = qemu_put_mouse_event_head;
404 while (cursor->next != NULL)
405 cursor = cursor->next;
406
407 cursor->next = s;
408 qemu_put_mouse_event_current = s;
409
410 return s;
411}
412
413void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
414{
415 QEMUPutMouseEntry *prev = NULL, *cursor;
416
417 if (!qemu_put_mouse_event_head || entry == NULL)
418 return;
419
420 cursor = qemu_put_mouse_event_head;
421 while (cursor != NULL && cursor != entry) {
422 prev = cursor;
423 cursor = cursor->next;
424 }
425
426 if (cursor == NULL) // does not exist or list empty
427 return;
428 else if (prev == NULL) { // entry is head
429 qemu_put_mouse_event_head = cursor->next;
430 if (qemu_put_mouse_event_current == entry)
431 qemu_put_mouse_event_current = cursor->next;
432 qemu_free(entry->qemu_put_mouse_event_name);
433 qemu_free(entry);
434 return;
435 }
436
437 prev->next = entry->next;
438
439 if (qemu_put_mouse_event_current == entry)
440 qemu_put_mouse_event_current = prev;
441
442 qemu_free(entry->qemu_put_mouse_event_name);
443 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000444}
445
446void kbd_put_keycode(int keycode)
447{
448 if (qemu_put_kbd_event) {
449 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
450 }
451}
452
453void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
454{
ths455204e2007-01-05 16:42:13 +0000455 QEMUPutMouseEvent *mouse_event;
456 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000457 int width;
ths455204e2007-01-05 16:42:13 +0000458
459 if (!qemu_put_mouse_event_current) {
460 return;
461 }
462
463 mouse_event =
464 qemu_put_mouse_event_current->qemu_put_mouse_event;
465 mouse_event_opaque =
466 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
467
468 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000469 if (graphic_rotate) {
470 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
471 width = 0x7fff;
472 else
aurel32b94ed572008-03-10 19:34:27 +0000473 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000474 mouse_event(mouse_event_opaque,
475 width - dy, dx, dz, buttons_state);
476 } else
477 mouse_event(mouse_event_opaque,
478 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000479 }
480}
481
bellard09b26c52006-04-12 21:09:08 +0000482int kbd_mouse_is_absolute(void)
483{
ths455204e2007-01-05 16:42:13 +0000484 if (!qemu_put_mouse_event_current)
485 return 0;
486
487 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
488}
489
aliguori376253e2009-03-05 23:01:23 +0000490void do_info_mice(Monitor *mon)
ths455204e2007-01-05 16:42:13 +0000491{
492 QEMUPutMouseEntry *cursor;
493 int index = 0;
494
495 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000496 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000497 return;
498 }
499
aliguori376253e2009-03-05 23:01:23 +0000500 monitor_printf(mon, "Mouse devices available:\n");
ths455204e2007-01-05 16:42:13 +0000501 cursor = qemu_put_mouse_event_head;
502 while (cursor != NULL) {
aliguori376253e2009-03-05 23:01:23 +0000503 monitor_printf(mon, "%c Mouse #%d: %s\n",
504 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
505 index, cursor->qemu_put_mouse_event_name);
ths455204e2007-01-05 16:42:13 +0000506 index++;
507 cursor = cursor->next;
508 }
509}
510
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300511void do_mouse_set(Monitor *mon, const QDict *qdict)
ths455204e2007-01-05 16:42:13 +0000512{
513 QEMUPutMouseEntry *cursor;
514 int i = 0;
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300515 int index = qdict_get_int(qdict, "index");
ths455204e2007-01-05 16:42:13 +0000516
517 if (!qemu_put_mouse_event_head) {
aliguori376253e2009-03-05 23:01:23 +0000518 monitor_printf(mon, "No mouse devices connected\n");
ths455204e2007-01-05 16:42:13 +0000519 return;
520 }
521
522 cursor = qemu_put_mouse_event_head;
523 while (cursor != NULL && index != i) {
524 i++;
525 cursor = cursor->next;
526 }
527
528 if (cursor != NULL)
529 qemu_put_mouse_event_current = cursor;
530 else
aliguori376253e2009-03-05 23:01:23 +0000531 monitor_printf(mon, "Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000532}
533
bellard87858c82003-06-27 12:01:39 +0000534/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000535uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000536{
537 union {
538 uint64_t ll;
539 struct {
Juan Quintelae2542fe2009-07-27 16:13:06 +0200540#ifdef HOST_WORDS_BIGENDIAN
bellard87858c82003-06-27 12:01:39 +0000541 uint32_t high, low;
542#else
543 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000544#endif
bellard87858c82003-06-27 12:01:39 +0000545 } l;
546 } u, res;
547 uint64_t rl, rh;
548
549 u.ll = a;
550 rl = (uint64_t)u.l.low * (uint64_t)b;
551 rh = (uint64_t)u.l.high * (uint64_t)b;
552 rh += (rl >> 32);
553 res.l.high = rh / c;
554 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
555 return res.ll;
556}
557
bellard1dce7c32006-07-13 23:20:22 +0000558/***********************************************************/
559/* real time host monotonic timer */
560
Jan Kiszka21d5d122009-09-15 13:36:04 +0200561static int64_t get_clock_realtime(void)
562{
563 struct timeval tv;
564
565 gettimeofday(&tv, NULL);
566 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
567}
568
bellard1dce7c32006-07-13 23:20:22 +0000569#ifdef WIN32
570
571static int64_t clock_freq;
572
573static void init_get_clock(void)
574{
bellarda8e5ac32006-07-14 09:36:13 +0000575 LARGE_INTEGER freq;
576 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000577 ret = QueryPerformanceFrequency(&freq);
578 if (ret == 0) {
579 fprintf(stderr, "Could not calibrate ticks\n");
580 exit(1);
581 }
582 clock_freq = freq.QuadPart;
583}
584
585static int64_t get_clock(void)
586{
587 LARGE_INTEGER ti;
588 QueryPerformanceCounter(&ti);
Anthony Liguori274dfed2009-09-11 10:28:26 -0500589 return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
bellard1dce7c32006-07-13 23:20:22 +0000590}
591
592#else
593
594static int use_rt_clock;
595
596static void init_get_clock(void)
597{
598 use_rt_clock = 0;
blueswir1c5e97232009-03-07 20:06:23 +0000599#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
Aurelien Jarnoa167ba52009-11-29 18:00:41 +0100600 || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
bellard1dce7c32006-07-13 23:20:22 +0000601 {
602 struct timespec ts;
603 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
604 use_rt_clock = 1;
605 }
606 }
607#endif
608}
609
610static int64_t get_clock(void)
611{
blueswir1c5e97232009-03-07 20:06:23 +0000612#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
Aurelien Jarnoa167ba52009-11-29 18:00:41 +0100613 || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
bellard1dce7c32006-07-13 23:20:22 +0000614 if (use_rt_clock) {
615 struct timespec ts;
616 clock_gettime(CLOCK_MONOTONIC, &ts);
617 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000618 } else
bellard1dce7c32006-07-13 23:20:22 +0000619#endif
620 {
621 /* XXX: using gettimeofday leads to problems if the date
622 changes, so it should be avoided. */
Jan Kiszka21d5d122009-09-15 13:36:04 +0200623 return get_clock_realtime();
bellard1dce7c32006-07-13 23:20:22 +0000624 }
625}
bellard1dce7c32006-07-13 23:20:22 +0000626#endif
627
pbrook2e70f6e2008-06-29 01:03:05 +0000628/* Return the virtual CPU time, based on the instruction counter. */
629static int64_t cpu_get_icount(void)
630{
631 int64_t icount;
632 CPUState *env = cpu_single_env;;
633 icount = qemu_icount;
634 if (env) {
635 if (!can_do_io(env))
636 fprintf(stderr, "Bad clock read\n");
637 icount -= (env->icount_decr.u16.low + env->icount_extra);
638 }
639 return qemu_icount_bias + (icount << icount_time_shift);
640}
641
bellard1dce7c32006-07-13 23:20:22 +0000642/***********************************************************/
643/* guest cycle counter */
644
Juan Quintela6f68e332009-09-10 03:04:27 +0200645typedef struct TimersState {
646 int64_t cpu_ticks_prev;
647 int64_t cpu_ticks_offset;
648 int64_t cpu_clock_offset;
649 int32_t cpu_ticks_enabled;
Anthony Liguori274dfed2009-09-11 10:28:26 -0500650 int64_t dummy;
Juan Quintela6f68e332009-09-10 03:04:27 +0200651} TimersState;
652
653TimersState timers_state;
bellard1dce7c32006-07-13 23:20:22 +0000654
655/* return the host CPU cycle counter and handle stop/restart */
656int64_t cpu_get_ticks(void)
657{
pbrook2e70f6e2008-06-29 01:03:05 +0000658 if (use_icount) {
659 return cpu_get_icount();
660 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200661 if (!timers_state.cpu_ticks_enabled) {
662 return timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000663 } else {
664 int64_t ticks;
665 ticks = cpu_get_real_ticks();
Juan Quintela6f68e332009-09-10 03:04:27 +0200666 if (timers_state.cpu_ticks_prev > ticks) {
bellard1dce7c32006-07-13 23:20:22 +0000667 /* Note: non increasing ticks may happen if the host uses
668 software suspend */
Juan Quintela6f68e332009-09-10 03:04:27 +0200669 timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
bellard1dce7c32006-07-13 23:20:22 +0000670 }
Juan Quintela6f68e332009-09-10 03:04:27 +0200671 timers_state.cpu_ticks_prev = ticks;
672 return ticks + timers_state.cpu_ticks_offset;
bellard1dce7c32006-07-13 23:20:22 +0000673 }
674}
675
676/* return the host CPU monotonic timer and handle stop/restart */
677static int64_t cpu_get_clock(void)
678{
679 int64_t ti;
Juan Quintela6f68e332009-09-10 03:04:27 +0200680 if (!timers_state.cpu_ticks_enabled) {
681 return timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000682 } else {
683 ti = get_clock();
Juan Quintela6f68e332009-09-10 03:04:27 +0200684 return ti + timers_state.cpu_clock_offset;
bellard1dce7c32006-07-13 23:20:22 +0000685 }
686}
687
688/* enable cpu_get_ticks() */
689void cpu_enable_ticks(void)
690{
Juan Quintela6f68e332009-09-10 03:04:27 +0200691 if (!timers_state.cpu_ticks_enabled) {
692 timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
693 timers_state.cpu_clock_offset -= get_clock();
694 timers_state.cpu_ticks_enabled = 1;
bellard1dce7c32006-07-13 23:20:22 +0000695 }
696}
697
698/* disable cpu_get_ticks() : the clock is stopped. You must not call
699 cpu_get_ticks() after that. */
700void cpu_disable_ticks(void)
701{
Juan Quintela6f68e332009-09-10 03:04:27 +0200702 if (timers_state.cpu_ticks_enabled) {
703 timers_state.cpu_ticks_offset = cpu_get_ticks();
704 timers_state.cpu_clock_offset = cpu_get_clock();
705 timers_state.cpu_ticks_enabled = 0;
bellard1dce7c32006-07-13 23:20:22 +0000706 }
707}
708
709/***********************************************************/
710/* timers */
ths5fafdf22007-09-16 21:08:06 +0000711
Jan Kiszka0fdddf82009-09-15 13:36:04 +0200712#define QEMU_CLOCK_REALTIME 0
713#define QEMU_CLOCK_VIRTUAL 1
Jan Kiszka21d5d122009-09-15 13:36:04 +0200714#define QEMU_CLOCK_HOST 2
bellard8a7ddc32004-03-31 19:00:16 +0000715
716struct QEMUClock {
717 int type;
718 /* XXX: add frequency */
719};
720
721struct QEMUTimer {
722 QEMUClock *clock;
723 int64_t expire_time;
724 QEMUTimerCB *cb;
725 void *opaque;
726 struct QEMUTimer *next;
727};
728
thsc8994012007-08-19 21:56:03 +0000729struct qemu_alarm_timer {
730 char const *name;
thsefe75412007-08-24 01:36:32 +0000731 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000732
733 int (*start)(struct qemu_alarm_timer *t);
734 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000735 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000736 void *priv;
737};
738
thsefe75412007-08-24 01:36:32 +0000739#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000740#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000741
742static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
743{
Jean-Christophe Duboise3323402009-05-17 18:38:39 +0200744 return t && (t->flags & ALARM_FLAG_DYNTICKS);
thsefe75412007-08-24 01:36:32 +0000745}
746
747static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
748{
749 if (!alarm_has_dynticks(t))
750 return;
751
752 t->rearm(t);
753}
754
755/* TODO: MIN_TIMER_REARM_US should be optimized */
756#define MIN_TIMER_REARM_US 250
757
thsc8994012007-08-19 21:56:03 +0000758static struct qemu_alarm_timer *alarm_timer;
759
760#ifdef _WIN32
761
762struct qemu_alarm_win32 {
763 MMRESULT timerId;
thsc8994012007-08-19 21:56:03 +0000764 unsigned int period;
Blue Swirlef28c4b2009-04-25 12:56:37 +0000765} alarm_win32_data = {0, -1};
thsc8994012007-08-19 21:56:03 +0000766
767static int win32_start_timer(struct qemu_alarm_timer *t);
768static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000769static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000770
771#else
772
773static int unix_start_timer(struct qemu_alarm_timer *t);
774static void unix_stop_timer(struct qemu_alarm_timer *t);
775
ths231c6582007-08-26 17:29:15 +0000776#ifdef __linux__
777
thsefe75412007-08-24 01:36:32 +0000778static int dynticks_start_timer(struct qemu_alarm_timer *t);
779static void dynticks_stop_timer(struct qemu_alarm_timer *t);
780static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
781
thsc40ec5a2007-08-19 22:09:40 +0000782static int hpet_start_timer(struct qemu_alarm_timer *t);
783static void hpet_stop_timer(struct qemu_alarm_timer *t);
784
thsc8994012007-08-19 21:56:03 +0000785static int rtc_start_timer(struct qemu_alarm_timer *t);
786static void rtc_stop_timer(struct qemu_alarm_timer *t);
787
thsefe75412007-08-24 01:36:32 +0000788#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000789
790#endif /* _WIN32 */
791
pbrook2e70f6e2008-06-29 01:03:05 +0000792/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000793 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000794 When the guest is idle real and virtual time will be aligned in
795 the IO wait loop. */
Anthony Liguori274dfed2009-09-11 10:28:26 -0500796#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
pbrook2e70f6e2008-06-29 01:03:05 +0000797
798static void icount_adjust(void)
799{
800 int64_t cur_time;
801 int64_t cur_icount;
802 int64_t delta;
803 static int64_t last_delta;
804 /* If the VM is not running, then do nothing. */
805 if (!vm_running)
806 return;
807
808 cur_time = cpu_get_clock();
809 cur_icount = qemu_get_clock(vm_clock);
810 delta = cur_icount - cur_time;
811 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
812 if (delta > 0
813 && last_delta + ICOUNT_WOBBLE < delta * 2
814 && icount_time_shift > 0) {
815 /* The guest is getting too far ahead. Slow time down. */
816 icount_time_shift--;
817 }
818 if (delta < 0
819 && last_delta - ICOUNT_WOBBLE > delta * 2
820 && icount_time_shift < MAX_ICOUNT_SHIFT) {
821 /* The guest is getting too far behind. Speed time up. */
822 icount_time_shift++;
823 }
824 last_delta = delta;
825 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
826}
827
828static void icount_adjust_rt(void * opaque)
829{
830 qemu_mod_timer(icount_rt_timer,
831 qemu_get_clock(rt_clock) + 1000);
832 icount_adjust();
833}
834
835static void icount_adjust_vm(void * opaque)
836{
837 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500838 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000839 icount_adjust();
840}
841
842static void init_icount_adjust(void)
843{
844 /* Have both realtime and virtual time triggers for speed adjustment.
845 The realtime trigger catches emulated time passing too slowly,
846 the virtual time trigger catches emulated time passing too fast.
847 Realtime triggers occur even when idle, so use them less frequently
848 than VM triggers. */
849 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
850 qemu_mod_timer(icount_rt_timer,
851 qemu_get_clock(rt_clock) + 1000);
852 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
853 qemu_mod_timer(icount_vm_timer,
Anthony Liguori274dfed2009-09-11 10:28:26 -0500854 qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
pbrook2e70f6e2008-06-29 01:03:05 +0000855}
856
thsc8994012007-08-19 21:56:03 +0000857static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000858#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000859#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000860 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
861 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000862 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +0000863 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000864 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +0000865 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000866#endif
thsefe75412007-08-24 01:36:32 +0000867 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000868#else
thsefe75412007-08-24 01:36:32 +0000869 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
870 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
871 {"win32", 0, win32_start_timer,
872 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +0000873#endif
874 {NULL, }
875};
876
blueswir13f47aa82008-03-09 06:59:01 +0000877static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +0000878{
879 int i;
880
881 printf("Available alarm timers, in order of precedence:\n");
882 for (i = 0; alarm_timers[i].name; i++)
883 printf("%s\n", alarm_timers[i].name);
884}
885
886static void configure_alarms(char const *opt)
887{
888 int i;
889 int cur = 0;
malcb1503cd2008-12-22 20:33:55 +0000890 int count = ARRAY_SIZE(alarm_timers) - 1;
thsf3dcfad2007-08-24 01:26:02 +0000891 char *arg;
892 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +0000893 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +0000894
aurel323adda042008-03-09 23:43:49 +0000895 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +0000896 show_available_alarms();
897 exit(0);
898 }
899
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200900 arg = qemu_strdup(opt);
thsf3dcfad2007-08-24 01:26:02 +0000901
902 /* Reorder the array */
903 name = strtok(arg, ",");
904 while (name) {
balroge2b577e2007-09-17 21:25:20 +0000905 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +0000906 if (!strcmp(alarm_timers[i].name, name))
907 break;
908 }
909
910 if (i == count) {
911 fprintf(stderr, "Unknown clock %s\n", name);
912 goto next;
913 }
914
915 if (i < cur)
916 /* Ignore */
917 goto next;
918
919 /* Swap */
920 tmp = alarm_timers[i];
921 alarm_timers[i] = alarm_timers[cur];
922 alarm_timers[cur] = tmp;
923
924 cur++;
925next:
926 name = strtok(NULL, ",");
927 }
928
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +0200929 qemu_free(arg);
thsf3dcfad2007-08-24 01:26:02 +0000930
931 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +0000932 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +0000933 for (i = cur; i < count; i++)
934 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +0000935 } else {
936 show_available_alarms();
937 exit(1);
thsf3dcfad2007-08-24 01:26:02 +0000938 }
thsf3dcfad2007-08-24 01:26:02 +0000939}
940
Jan Kiszka21d5d122009-09-15 13:36:04 +0200941#define QEMU_NUM_CLOCKS 3
942
bellard8a7ddc32004-03-31 19:00:16 +0000943QEMUClock *rt_clock;
944QEMUClock *vm_clock;
Jan Kiszka21d5d122009-09-15 13:36:04 +0200945QEMUClock *host_clock;
bellard8a7ddc32004-03-31 19:00:16 +0000946
Jan Kiszka21d5d122009-09-15 13:36:04 +0200947static QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
bellard8a7ddc32004-03-31 19:00:16 +0000948
pbrook9596ebb2007-11-18 01:44:38 +0000949static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +0000950{
951 QEMUClock *clock;
952 clock = qemu_mallocz(sizeof(QEMUClock));
bellard8a7ddc32004-03-31 19:00:16 +0000953 clock->type = type;
954 return clock;
955}
956
957QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
958{
959 QEMUTimer *ts;
960
961 ts = qemu_mallocz(sizeof(QEMUTimer));
962 ts->clock = clock;
963 ts->cb = cb;
964 ts->opaque = opaque;
965 return ts;
966}
967
968void qemu_free_timer(QEMUTimer *ts)
969{
970 qemu_free(ts);
971}
972
973/* stop a timer, but do not dealloc it */
974void qemu_del_timer(QEMUTimer *ts)
975{
976 QEMUTimer **pt, *t;
977
978 /* NOTE: this code must be signal safe because
979 qemu_timer_expired() can be called from a signal. */
980 pt = &active_timers[ts->clock->type];
981 for(;;) {
982 t = *pt;
983 if (!t)
984 break;
985 if (t == ts) {
986 *pt = t->next;
987 break;
988 }
989 pt = &t->next;
990 }
991}
992
993/* modify the current timer so that it will be fired when current_time
994 >= expire_time. The corresponding callback will be called. */
995void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
996{
997 QEMUTimer **pt, *t;
998
999 qemu_del_timer(ts);
1000
1001 /* add the timer in the sorted list */
1002 /* NOTE: this code must be signal safe because
1003 qemu_timer_expired() can be called from a signal. */
1004 pt = &active_timers[ts->clock->type];
1005 for(;;) {
1006 t = *pt;
1007 if (!t)
1008 break;
ths5fafdf22007-09-16 21:08:06 +00001009 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +00001010 break;
1011 pt = &t->next;
1012 }
1013 ts->expire_time = expire_time;
1014 ts->next = *pt;
1015 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +00001016
1017 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +00001018 if (pt == &active_timers[ts->clock->type]) {
1019 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
1020 qemu_rearm_alarm_timer(alarm_timer);
1021 }
1022 /* Interrupt execution to force deadline recalculation. */
aliguorid9f75a42009-04-24 18:03:11 +00001023 if (use_icount)
1024 qemu_notify_event();
pbrook2e70f6e2008-06-29 01:03:05 +00001025 }
bellard8a7ddc32004-03-31 19:00:16 +00001026}
1027
1028int qemu_timer_pending(QEMUTimer *ts)
1029{
1030 QEMUTimer *t;
1031 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1032 if (t == ts)
1033 return 1;
1034 }
1035 return 0;
1036}
1037
Stefano Stabellini2430ffe2009-08-03 10:56:01 +01001038int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001039{
1040 if (!timer_head)
1041 return 0;
1042 return (timer_head->expire_time <= current_time);
1043}
1044
1045static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1046{
1047 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001048
bellard8a7ddc32004-03-31 19:00:16 +00001049 for(;;) {
1050 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001051 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001052 break;
1053 /* remove timer from the list before calling the callback */
1054 *ptimer_head = ts->next;
1055 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001056
bellard8a7ddc32004-03-31 19:00:16 +00001057 /* run the callback (the timer list can be modified) */
1058 ts->cb(ts->opaque);
1059 }
1060}
1061
1062int64_t qemu_get_clock(QEMUClock *clock)
1063{
1064 switch(clock->type) {
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001065 case QEMU_CLOCK_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001066 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001067 default:
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001068 case QEMU_CLOCK_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001069 if (use_icount) {
1070 return cpu_get_icount();
1071 } else {
1072 return cpu_get_clock();
1073 }
Jan Kiszka21d5d122009-09-15 13:36:04 +02001074 case QEMU_CLOCK_HOST:
1075 return get_clock_realtime();
bellard8a7ddc32004-03-31 19:00:16 +00001076 }
1077}
1078
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001079static void init_clocks(void)
bellard1dce7c32006-07-13 23:20:22 +00001080{
1081 init_get_clock();
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001082 rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
1083 vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001084 host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
Jan Kiszka68752042009-09-15 13:36:04 +02001085
1086 rtc_clock = host_clock;
bellard1dce7c32006-07-13 23:20:22 +00001087}
1088
bellard8a7ddc32004-03-31 19:00:16 +00001089/* save a timer */
1090void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1091{
1092 uint64_t expire_time;
1093
1094 if (qemu_timer_pending(ts)) {
1095 expire_time = ts->expire_time;
1096 } else {
1097 expire_time = -1;
1098 }
1099 qemu_put_be64(f, expire_time);
1100}
1101
1102void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1103{
1104 uint64_t expire_time;
1105
1106 expire_time = qemu_get_be64(f);
1107 if (expire_time != -1) {
1108 qemu_mod_timer(ts, expire_time);
1109 } else {
1110 qemu_del_timer(ts);
1111 }
1112}
1113
Juan Quintela2faf58c2009-09-10 03:04:28 +02001114static const VMStateDescription vmstate_timers = {
1115 .name = "timer",
1116 .version_id = 2,
1117 .minimum_version_id = 1,
1118 .minimum_version_id_old = 1,
1119 .fields = (VMStateField []) {
1120 VMSTATE_INT64(cpu_ticks_offset, TimersState),
Anthony Liguori274dfed2009-09-11 10:28:26 -05001121 VMSTATE_INT64(dummy, TimersState),
Juan Quintela2faf58c2009-09-10 03:04:28 +02001122 VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
1123 VMSTATE_END_OF_LIST()
bellardc88676f2006-08-06 13:36:11 +00001124 }
Juan Quintela2faf58c2009-09-10 03:04:28 +02001125};
bellard8a7ddc32004-03-31 19:00:16 +00001126
aliguori50317c72009-04-24 18:03:29 +00001127static void qemu_event_increment(void);
1128
bellard67b915a2004-03-31 23:37:16 +00001129#ifdef _WIN32
blueswir1b9e82a52009-04-05 18:03:31 +00001130static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1131 DWORD_PTR dwUser, DWORD_PTR dw1,
1132 DWORD_PTR dw2)
bellard67b915a2004-03-31 23:37:16 +00001133#else
bellard8a7ddc32004-03-31 19:00:16 +00001134static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001135#endif
bellard8a7ddc32004-03-31 19:00:16 +00001136{
bellard02ba45c2004-06-25 14:46:23 +00001137#if 0
1138#define DISP_FREQ 1000
1139 {
1140 static int64_t delta_min = INT64_MAX;
1141 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1142 static int count;
1143 ti = qemu_get_clock(vm_clock);
1144 if (last_clock != 0) {
1145 delta = ti - last_clock;
1146 if (delta < delta_min)
1147 delta_min = delta;
1148 if (delta > delta_max)
1149 delta_max = delta;
1150 delta_cum += delta;
1151 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001152 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
Juan Quintela6ee093c2009-09-10 03:04:26 +02001153 muldiv64(delta_min, 1000000, get_ticks_per_sec()),
1154 muldiv64(delta_max, 1000000, get_ticks_per_sec()),
1155 muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
1156 (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
bellard02ba45c2004-06-25 14:46:23 +00001157 count = 0;
1158 delta_min = INT64_MAX;
1159 delta_max = 0;
1160 delta_cum = 0;
1161 }
1162 }
1163 last_clock = ti;
1164 }
1165#endif
thsefe75412007-08-24 01:36:32 +00001166 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001167 (!use_icount &&
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001168 qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
pbrook2e70f6e2008-06-29 01:03:05 +00001169 qemu_get_clock(vm_clock))) ||
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001170 qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
Jan Kiszka21d5d122009-09-15 13:36:04 +02001171 qemu_get_clock(rt_clock)) ||
1172 qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
1173 qemu_get_clock(host_clock))) {
aliguori50317c72009-04-24 18:03:29 +00001174 qemu_event_increment();
Jean-Christophe Duboise3323402009-05-17 18:38:39 +02001175 if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
balrogd5d08332008-01-05 19:41:47 +00001176
aliguorid6dc3d42009-04-24 18:04:07 +00001177#ifndef CONFIG_IOTHREAD
1178 if (next_cpu) {
balrog4f8eb8d2007-12-16 12:39:38 +00001179 /* stop the currently executing cpu because a timer occured */
aliguorid6dc3d42009-04-24 18:04:07 +00001180 cpu_exit(next_cpu);
balrog4f8eb8d2007-12-16 12:39:38 +00001181 }
aliguorid6dc3d42009-04-24 18:04:07 +00001182#endif
aliguori43b96852009-04-24 18:03:33 +00001183 timer_alarm_pending = 1;
aliguorid9f75a42009-04-24 18:03:11 +00001184 qemu_notify_event();
bellard8a7ddc32004-03-31 19:00:16 +00001185 }
1186}
1187
pbrook2e70f6e2008-06-29 01:03:05 +00001188static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001189{
Jan Kiszka21d5d122009-09-15 13:36:04 +02001190 /* To avoid problems with overflow limit this to 2^32. */
1191 int64_t delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001192
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001193 if (active_timers[QEMU_CLOCK_VIRTUAL]) {
1194 delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001195 qemu_get_clock(vm_clock);
Jan Kiszka21d5d122009-09-15 13:36:04 +02001196 }
1197 if (active_timers[QEMU_CLOCK_HOST]) {
1198 int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
1199 qemu_get_clock(host_clock);
1200 if (hdelta < delta)
1201 delta = hdelta;
thsefe75412007-08-24 01:36:32 +00001202 }
1203
pbrook2e70f6e2008-06-29 01:03:05 +00001204 if (delta < 0)
1205 delta = 0;
thsefe75412007-08-24 01:36:32 +00001206
pbrook2e70f6e2008-06-29 01:03:05 +00001207 return delta;
1208}
1209
Jan Kiszkaf64382b2009-09-15 13:36:04 +02001210#if defined(__linux__)
pbrook2e70f6e2008-06-29 01:03:05 +00001211static uint64_t qemu_next_deadline_dyntick(void)
1212{
1213 int64_t delta;
1214 int64_t rtdelta;
1215
1216 if (use_icount)
1217 delta = INT32_MAX;
1218 else
1219 delta = (qemu_next_deadline() + 999) / 1000;
1220
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001221 if (active_timers[QEMU_CLOCK_REALTIME]) {
1222 rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
pbrook2e70f6e2008-06-29 01:03:05 +00001223 qemu_get_clock(rt_clock))*1000;
1224 if (rtdelta < delta)
1225 delta = rtdelta;
1226 }
1227
1228 if (delta < MIN_TIMER_REARM_US)
1229 delta = MIN_TIMER_REARM_US;
1230
1231 return delta;
thsefe75412007-08-24 01:36:32 +00001232}
blueswir18632fb92008-09-14 13:59:34 +00001233#endif
thsefe75412007-08-24 01:36:32 +00001234
bellardfd872592004-05-12 19:11:15 +00001235#ifndef _WIN32
1236
aliguori7183b4b2008-11-05 20:40:18 +00001237/* Sets a specific flag */
1238static int fcntl_setfl(int fd, int flag)
1239{
1240 int flags;
1241
1242 flags = fcntl(fd, F_GETFL);
1243 if (flags == -1)
1244 return -errno;
1245
1246 if (fcntl(fd, F_SETFL, flags | flag) == -1)
1247 return -errno;
1248
1249 return 0;
1250}
1251
bellard829309c2004-05-20 13:20:12 +00001252#if defined(__linux__)
1253
bellardfd872592004-05-12 19:11:15 +00001254#define RTC_FREQ 1024
1255
aurel32de9a95f2008-11-11 13:41:01 +00001256static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001257{
thsc8994012007-08-19 21:56:03 +00001258 struct sigaction act;
1259
1260 /* timer signal */
1261 sigfillset(&act.sa_mask);
1262 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001263 act.sa_handler = host_alarm_handler;
1264
1265 sigaction(SIGIO, &act, NULL);
aliguori7183b4b2008-11-05 20:40:18 +00001266 fcntl_setfl(fd, O_ASYNC);
thsc8994012007-08-19 21:56:03 +00001267 fcntl(fd, F_SETOWN, getpid());
1268}
1269
thsc40ec5a2007-08-19 22:09:40 +00001270static int hpet_start_timer(struct qemu_alarm_timer *t)
1271{
1272 struct hpet_info info;
1273 int r, fd;
1274
Kevin Wolf40ff6d72009-12-02 12:24:42 +01001275 fd = qemu_open("/dev/hpet", O_RDONLY);
thsc40ec5a2007-08-19 22:09:40 +00001276 if (fd < 0)
1277 return -1;
1278
1279 /* Set frequency */
1280 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1281 if (r < 0) {
1282 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1283 "error, but for better emulation accuracy type:\n"
1284 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1285 goto fail;
1286 }
1287
1288 /* Check capabilities */
1289 r = ioctl(fd, HPET_INFO, &info);
1290 if (r < 0)
1291 goto fail;
1292
1293 /* Enable periodic mode */
1294 r = ioctl(fd, HPET_EPI, 0);
1295 if (info.hi_flags && (r < 0))
1296 goto fail;
1297
1298 /* Enable interrupt */
1299 r = ioctl(fd, HPET_IE_ON, 0);
1300 if (r < 0)
1301 goto fail;
1302
1303 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001304 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001305
1306 return 0;
1307fail:
1308 close(fd);
1309 return -1;
1310}
1311
1312static void hpet_stop_timer(struct qemu_alarm_timer *t)
1313{
pbrookfcdc2122007-08-23 20:22:22 +00001314 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001315
1316 close(fd);
1317}
1318
thsc8994012007-08-19 21:56:03 +00001319static int rtc_start_timer(struct qemu_alarm_timer *t)
1320{
1321 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001322 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001323
Kevin Wolf40ff6d72009-12-02 12:24:42 +01001324 TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001325 if (rtc_fd < 0)
1326 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001327 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1328 if (current_rtc_freq != RTC_FREQ &&
1329 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001330 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1331 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1332 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1333 goto fail;
1334 }
1335 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1336 fail:
1337 close(rtc_fd);
1338 return -1;
1339 }
thsc8994012007-08-19 21:56:03 +00001340
1341 enable_sigio_timer(rtc_fd);
1342
pbrookfcdc2122007-08-23 20:22:22 +00001343 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001344
bellardfd872592004-05-12 19:11:15 +00001345 return 0;
1346}
1347
thsc8994012007-08-19 21:56:03 +00001348static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001349{
pbrookfcdc2122007-08-23 20:22:22 +00001350 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001351
1352 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001353}
1354
thsefe75412007-08-24 01:36:32 +00001355static int dynticks_start_timer(struct qemu_alarm_timer *t)
1356{
1357 struct sigevent ev;
1358 timer_t host_timer;
1359 struct sigaction act;
1360
1361 sigfillset(&act.sa_mask);
1362 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001363 act.sa_handler = host_alarm_handler;
1364
1365 sigaction(SIGALRM, &act, NULL);
1366
Jean-Christophe Dubois9ed415b2009-05-17 18:41:16 +02001367 /*
1368 * Initialize ev struct to 0 to avoid valgrind complaining
1369 * about uninitialized data in timer_create call
1370 */
1371 memset(&ev, 0, sizeof(ev));
thsefe75412007-08-24 01:36:32 +00001372 ev.sigev_value.sival_int = 0;
1373 ev.sigev_notify = SIGEV_SIGNAL;
1374 ev.sigev_signo = SIGALRM;
1375
1376 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1377 perror("timer_create");
1378
1379 /* disable dynticks */
1380 fprintf(stderr, "Dynamic Ticks disabled\n");
1381
1382 return -1;
1383 }
1384
blueswir10399bfe2008-11-16 11:37:18 +00001385 t->priv = (void *)(long)host_timer;
thsefe75412007-08-24 01:36:32 +00001386
1387 return 0;
1388}
1389
1390static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1391{
blueswir10399bfe2008-11-16 11:37:18 +00001392 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001393
1394 timer_delete(host_timer);
1395}
1396
1397static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1398{
blueswir10399bfe2008-11-16 11:37:18 +00001399 timer_t host_timer = (timer_t)(long)t->priv;
thsefe75412007-08-24 01:36:32 +00001400 struct itimerspec timeout;
1401 int64_t nearest_delta_us = INT64_MAX;
1402 int64_t current_us;
1403
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001404 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001405 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1406 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001407 return;
thsefe75412007-08-24 01:36:32 +00001408
pbrook2e70f6e2008-06-29 01:03:05 +00001409 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001410
1411 /* check whether a timer is already running */
1412 if (timer_gettime(host_timer, &timeout)) {
1413 perror("gettime");
1414 fprintf(stderr, "Internal timer error: aborting\n");
1415 exit(1);
1416 }
1417 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1418 if (current_us && current_us <= nearest_delta_us)
1419 return;
1420
1421 timeout.it_interval.tv_sec = 0;
1422 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1423 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1424 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1425 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1426 perror("settime");
1427 fprintf(stderr, "Internal timer error: aborting\n");
1428 exit(1);
1429 }
1430}
1431
ths70744b32007-08-26 17:31:30 +00001432#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001433
thsc8994012007-08-19 21:56:03 +00001434static int unix_start_timer(struct qemu_alarm_timer *t)
1435{
1436 struct sigaction act;
1437 struct itimerval itv;
1438 int err;
1439
1440 /* timer signal */
1441 sigfillset(&act.sa_mask);
1442 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001443 act.sa_handler = host_alarm_handler;
1444
1445 sigaction(SIGALRM, &act, NULL);
1446
1447 itv.it_interval.tv_sec = 0;
1448 /* for i386 kernel 2.6 to get 1 ms */
1449 itv.it_interval.tv_usec = 999;
1450 itv.it_value.tv_sec = 0;
1451 itv.it_value.tv_usec = 10 * 1000;
1452
1453 err = setitimer(ITIMER_REAL, &itv, NULL);
1454 if (err)
1455 return -1;
1456
1457 return 0;
1458}
1459
1460static void unix_stop_timer(struct qemu_alarm_timer *t)
1461{
1462 struct itimerval itv;
1463
1464 memset(&itv, 0, sizeof(itv));
1465 setitimer(ITIMER_REAL, &itv, NULL);
1466}
1467
bellard829309c2004-05-20 13:20:12 +00001468#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001469
aliguorif49e58d2008-11-05 21:22:34 +00001470
thsc8994012007-08-19 21:56:03 +00001471#ifdef _WIN32
1472
1473static int win32_start_timer(struct qemu_alarm_timer *t)
1474{
1475 TIMECAPS tc;
1476 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001477 UINT flags;
thsc8994012007-08-19 21:56:03 +00001478
thsc8994012007-08-19 21:56:03 +00001479 memset(&tc, 0, sizeof(tc));
1480 timeGetDevCaps(&tc, sizeof(tc));
1481
1482 if (data->period < tc.wPeriodMin)
1483 data->period = tc.wPeriodMin;
1484
1485 timeBeginPeriod(data->period);
1486
thsefe75412007-08-24 01:36:32 +00001487 flags = TIME_CALLBACK_FUNCTION;
1488 if (alarm_has_dynticks(t))
1489 flags |= TIME_ONESHOT;
1490 else
1491 flags |= TIME_PERIODIC;
1492
thsc8994012007-08-19 21:56:03 +00001493 data->timerId = timeSetEvent(1, // interval (ms)
1494 data->period, // resolution
1495 host_alarm_handler, // function
1496 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001497 flags);
thsc8994012007-08-19 21:56:03 +00001498
1499 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001500 fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
malc705e83f2009-09-27 14:30:33 +04001501 GetLastError());
thsc8994012007-08-19 21:56:03 +00001502 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001503 return -1;
1504 }
1505
thsc8994012007-08-19 21:56:03 +00001506 return 0;
1507}
1508
1509static void win32_stop_timer(struct qemu_alarm_timer *t)
1510{
1511 struct qemu_alarm_win32 *data = t->priv;
1512
1513 timeKillEvent(data->timerId);
1514 timeEndPeriod(data->period);
thsc8994012007-08-19 21:56:03 +00001515}
1516
thsefe75412007-08-24 01:36:32 +00001517static void win32_rearm_timer(struct qemu_alarm_timer *t)
1518{
1519 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001520
Jan Kiszka0fdddf82009-09-15 13:36:04 +02001521 if (!active_timers[QEMU_CLOCK_REALTIME] &&
Jan Kiszka21d5d122009-09-15 13:36:04 +02001522 !active_timers[QEMU_CLOCK_VIRTUAL] &&
1523 !active_timers[QEMU_CLOCK_HOST])
balrogd5d08332008-01-05 19:41:47 +00001524 return;
thsefe75412007-08-24 01:36:32 +00001525
thsefe75412007-08-24 01:36:32 +00001526 timeKillEvent(data->timerId);
1527
1528 data->timerId = timeSetEvent(1,
1529 data->period,
1530 host_alarm_handler,
1531 (DWORD)t,
1532 TIME_ONESHOT | TIME_PERIODIC);
1533
1534 if (!data->timerId) {
Blue Swirl20889d42009-09-27 20:03:56 +00001535 fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
malc705e83f2009-09-27 14:30:33 +04001536 GetLastError());
thsefe75412007-08-24 01:36:32 +00001537
1538 timeEndPeriod(data->period);
thsefe75412007-08-24 01:36:32 +00001539 exit(1);
1540 }
1541}
1542
thsc8994012007-08-19 21:56:03 +00001543#endif /* _WIN32 */
1544
aliguori7183b4b2008-11-05 20:40:18 +00001545static int init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001546{
blueswir1223f0d72008-09-30 18:12:18 +00001547 struct qemu_alarm_timer *t = NULL;
thsc8994012007-08-19 21:56:03 +00001548 int i, err = -1;
aliguorif49e58d2008-11-05 21:22:34 +00001549
thsc8994012007-08-19 21:56:03 +00001550 for (i = 0; alarm_timers[i].name; i++) {
1551 t = &alarm_timers[i];
1552
thsc8994012007-08-19 21:56:03 +00001553 err = t->start(t);
1554 if (!err)
1555 break;
bellard67b915a2004-03-31 23:37:16 +00001556 }
bellardfd872592004-05-12 19:11:15 +00001557
thsc8994012007-08-19 21:56:03 +00001558 if (err) {
aliguori7183b4b2008-11-05 20:40:18 +00001559 err = -ENOENT;
1560 goto fail;
bellard67b915a2004-03-31 23:37:16 +00001561 }
thsc8994012007-08-19 21:56:03 +00001562
1563 alarm_timer = t;
aliguori7183b4b2008-11-05 20:40:18 +00001564
aliguori6abfbd72008-11-05 20:49:37 +00001565 return 0;
aliguori7183b4b2008-11-05 20:40:18 +00001566
1567fail:
aliguori7183b4b2008-11-05 20:40:18 +00001568 return err;
bellard8a7ddc32004-03-31 19:00:16 +00001569}
1570
pbrook9596ebb2007-11-18 01:44:38 +00001571static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001572{
thsc8994012007-08-19 21:56:03 +00001573 alarm_timer->stop(alarm_timer);
1574 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001575}
1576
bellardc4b1fcc2004-03-14 21:44:30 +00001577/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001578/* host time/date access */
1579void qemu_get_timedate(struct tm *tm, int offset)
1580{
1581 time_t ti;
1582 struct tm *ret;
1583
1584 time(&ti);
1585 ti += offset;
1586 if (rtc_date_offset == -1) {
1587 if (rtc_utc)
1588 ret = gmtime(&ti);
1589 else
1590 ret = localtime(&ti);
1591 } else {
1592 ti -= rtc_date_offset;
1593 ret = gmtime(&ti);
1594 }
1595
1596 memcpy(tm, ret, sizeof(struct tm));
1597}
1598
1599int qemu_timedate_diff(struct tm *tm)
1600{
1601 time_t seconds;
1602
1603 if (rtc_date_offset == -1)
1604 if (rtc_utc)
1605 seconds = mktimegm(tm);
1606 else
1607 seconds = mktime(tm);
1608 else
1609 seconds = mktimegm(tm) + rtc_date_offset;
1610
1611 return seconds - time(NULL);
1612}
1613
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02001614static void configure_rtc_date_offset(const char *startdate, int legacy)
1615{
1616 time_t rtc_start_date;
1617 struct tm tm;
1618
1619 if (!strcmp(startdate, "now") && legacy) {
1620 rtc_date_offset = -1;
1621 } else {
1622 if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
1623 &tm.tm_year,
1624 &tm.tm_mon,
1625 &tm.tm_mday,
1626 &tm.tm_hour,
1627 &tm.tm_min,
1628 &tm.tm_sec) == 6) {
1629 /* OK */
1630 } else if (sscanf(startdate, "%d-%d-%d",
1631 &tm.tm_year,
1632 &tm.tm_mon,
1633 &tm.tm_mday) == 3) {
1634 tm.tm_hour = 0;
1635 tm.tm_min = 0;
1636 tm.tm_sec = 0;
1637 } else {
1638 goto date_fail;
1639 }
1640 tm.tm_year -= 1900;
1641 tm.tm_mon--;
1642 rtc_start_date = mktimegm(&tm);
1643 if (rtc_start_date == -1) {
1644 date_fail:
1645 fprintf(stderr, "Invalid date format. Valid formats are:\n"
1646 "'2006-06-17T16:01:21' or '2006-06-17'\n");
1647 exit(1);
1648 }
1649 rtc_date_offset = time(NULL) - rtc_start_date;
1650 }
1651}
1652
1653static void configure_rtc(QemuOpts *opts)
1654{
1655 const char *value;
1656
1657 value = qemu_opt_get(opts, "base");
1658 if (value) {
1659 if (!strcmp(value, "utc")) {
1660 rtc_utc = 1;
1661 } else if (!strcmp(value, "localtime")) {
1662 rtc_utc = 0;
1663 } else {
1664 configure_rtc_date_offset(value, 0);
1665 }
1666 }
Jan Kiszka68752042009-09-15 13:36:04 +02001667 value = qemu_opt_get(opts, "clock");
1668 if (value) {
1669 if (!strcmp(value, "host")) {
1670 rtc_clock = host_clock;
1671 } else if (!strcmp(value, "vm")) {
1672 rtc_clock = vm_clock;
1673 } else {
1674 fprintf(stderr, "qemu: invalid option value '%s'\n", value);
1675 exit(1);
1676 }
1677 }
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02001678#ifdef CONFIG_TARGET_I386
1679 value = qemu_opt_get(opts, "driftfix");
1680 if (value) {
1681 if (!strcmp(buf, "slew")) {
1682 rtc_td_hack = 1;
1683 } else if (!strcmp(buf, "none")) {
1684 rtc_td_hack = 0;
1685 } else {
1686 fprintf(stderr, "qemu: invalid option value '%s'\n", value);
1687 exit(1);
1688 }
1689 }
1690#endif
1691}
1692
bellardfd1dff42006-02-01 21:29:26 +00001693#ifdef _WIN32
bellardfd1dff42006-02-01 21:29:26 +00001694static void socket_cleanup(void)
1695{
1696 WSACleanup();
1697}
bellard82c643f2004-07-14 17:28:13 +00001698
bellardfd1dff42006-02-01 21:29:26 +00001699static int socket_init(void)
1700{
1701 WSADATA Data;
1702 int ret, err;
1703
1704 ret = WSAStartup(MAKEWORD(2,2), &Data);
1705 if (ret != 0) {
1706 err = WSAGetLastError();
1707 fprintf(stderr, "WSAStartup: %d\n", err);
1708 return -1;
1709 }
1710 atexit(socket_cleanup);
1711 return 0;
1712}
aurel3264b7b732008-05-05 10:05:31 +00001713#endif
1714
balrog1ae26a12008-09-28 23:19:47 +00001715/***********************************************************/
1716/* Bluetooth support */
1717static int nb_hcis;
1718static int cur_hci;
1719static struct HCIInfo *hci_table[MAX_NICS];
balrogdc72ac12008-11-09 00:04:26 +00001720
balrog1ae26a12008-09-28 23:19:47 +00001721static struct bt_vlan_s {
1722 struct bt_scatternet_s net;
1723 int id;
1724 struct bt_vlan_s *next;
1725} *first_bt_vlan;
1726
1727/* find or alloc a new bluetooth "VLAN" */
blueswir1674bb262008-09-30 18:18:27 +00001728static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
balrog1ae26a12008-09-28 23:19:47 +00001729{
1730 struct bt_vlan_s **pvlan, *vlan;
1731 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
1732 if (vlan->id == id)
1733 return &vlan->net;
1734 }
1735 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
1736 vlan->id = id;
1737 pvlan = &first_bt_vlan;
1738 while (*pvlan != NULL)
1739 pvlan = &(*pvlan)->next;
1740 *pvlan = vlan;
1741 return &vlan->net;
1742}
1743
1744static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
1745{
1746}
1747
1748static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
1749{
1750 return -ENOTSUP;
1751}
1752
1753static struct HCIInfo null_hci = {
1754 .cmd_send = null_hci_send,
1755 .sco_send = null_hci_send,
1756 .acl_send = null_hci_send,
1757 .bdaddr_set = null_hci_addr_set,
1758};
1759
1760struct HCIInfo *qemu_next_hci(void)
1761{
1762 if (cur_hci == nb_hcis)
1763 return &null_hci;
1764
1765 return hci_table[cur_hci++];
1766}
1767
balrogdc72ac12008-11-09 00:04:26 +00001768static struct HCIInfo *hci_init(const char *str)
1769{
1770 char *endp;
1771 struct bt_scatternet_s *vlan = 0;
1772
1773 if (!strcmp(str, "null"))
1774 /* null */
1775 return &null_hci;
1776 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
1777 /* host[:hciN] */
1778 return bt_host_hci(str[4] ? str + 5 : "hci0");
1779 else if (!strncmp(str, "hci", 3)) {
1780 /* hci[,vlan=n] */
1781 if (str[3]) {
1782 if (!strncmp(str + 3, ",vlan=", 6)) {
1783 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
1784 if (*endp)
1785 vlan = 0;
1786 }
1787 } else
1788 vlan = qemu_find_bt_vlan(0);
1789 if (vlan)
1790 return bt_new_hci(vlan);
1791 }
1792
1793 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
1794
1795 return 0;
1796}
1797
1798static int bt_hci_parse(const char *str)
1799{
1800 struct HCIInfo *hci;
Anthony Liguoric227f092009-10-01 16:12:16 -05001801 bdaddr_t bdaddr;
balrogdc72ac12008-11-09 00:04:26 +00001802
1803 if (nb_hcis >= MAX_NICS) {
1804 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
1805 return -1;
1806 }
1807
1808 hci = hci_init(str);
1809 if (!hci)
1810 return -1;
1811
1812 bdaddr.b[0] = 0x52;
1813 bdaddr.b[1] = 0x54;
1814 bdaddr.b[2] = 0x00;
1815 bdaddr.b[3] = 0x12;
1816 bdaddr.b[4] = 0x34;
1817 bdaddr.b[5] = 0x56 + nb_hcis;
1818 hci->bdaddr_set(hci, bdaddr.b);
1819
1820 hci_table[nb_hcis++] = hci;
1821
1822 return 0;
1823}
1824
1825static void bt_vhci_add(int vlan_id)
1826{
1827 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
1828
1829 if (!vlan->slave)
1830 fprintf(stderr, "qemu: warning: adding a VHCI to "
1831 "an empty scatternet %i\n", vlan_id);
1832
1833 bt_vhci_init(bt_new_hci(vlan));
1834}
1835
1836static struct bt_device_s *bt_device_add(const char *opt)
1837{
1838 struct bt_scatternet_s *vlan;
1839 int vlan_id = 0;
1840 char *endp = strstr(opt, ",vlan=");
1841 int len = (endp ? endp - opt : strlen(opt)) + 1;
1842 char devname[10];
1843
1844 pstrcpy(devname, MIN(sizeof(devname), len), opt);
1845
1846 if (endp) {
1847 vlan_id = strtol(endp + 6, &endp, 0);
1848 if (*endp) {
1849 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
1850 return 0;
1851 }
1852 }
1853
1854 vlan = qemu_find_bt_vlan(vlan_id);
1855
1856 if (!vlan->slave)
1857 fprintf(stderr, "qemu: warning: adding a slave device to "
1858 "an empty scatternet %i\n", vlan_id);
1859
1860 if (!strcmp(devname, "keyboard"))
1861 return bt_keyboard_init(vlan);
1862
1863 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
1864 return 0;
1865}
1866
1867static int bt_parse(const char *opt)
1868{
1869 const char *endp, *p;
1870 int vlan;
1871
1872 if (strstart(opt, "hci", &endp)) {
1873 if (!*endp || *endp == ',') {
1874 if (*endp)
1875 if (!strstart(endp, ",vlan=", 0))
1876 opt = endp + 1;
1877
1878 return bt_hci_parse(opt);
1879 }
1880 } else if (strstart(opt, "vhci", &endp)) {
1881 if (!*endp || *endp == ',') {
1882 if (*endp) {
1883 if (strstart(endp, ",vlan=", &p)) {
1884 vlan = strtol(p, (char **) &endp, 0);
1885 if (*endp) {
1886 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
1887 return 1;
1888 }
1889 } else {
1890 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
1891 return 1;
1892 }
1893 } else
1894 vlan = 0;
1895
1896 bt_vhci_add(vlan);
1897 return 0;
1898 }
1899 } else if (strstart(opt, "device:", &endp))
1900 return !bt_device_add(endp);
1901
1902 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
1903 return 1;
1904}
1905
balrog1ae26a12008-09-28 23:19:47 +00001906/***********************************************************/
1907/* QEMU Block devices */
1908
balrog609497a2008-01-14 02:56:53 +00001909#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00001910#define CDROM_ALIAS "index=2,media=cdrom"
thse4bcb142007-12-02 04:51:10 +00001911#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00001912#define PFLASH_ALIAS "if=pflash"
1913#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00001914#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00001915
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001916QemuOpts *drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00001917{
1918 va_list ap;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001919 char optstr[1024];
1920 QemuOpts *opts;
thse4bcb142007-12-02 04:51:10 +00001921
thse4bcb142007-12-02 04:51:10 +00001922 va_start(ap, fmt);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001923 vsnprintf(optstr, sizeof(optstr), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00001924 va_end(ap);
1925
Gerd Hoffmann7282a032009-07-31 12:25:35 +02001926 opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL);
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02001927 if (!opts) {
1928 fprintf(stderr, "%s: huh? duplicate? (%s)\n",
1929 __FUNCTION__, optstr);
1930 return NULL;
1931 }
1932 if (file)
1933 qemu_opt_set(opts, "file", file);
1934 return opts;
aliguorib01b1112009-02-11 15:20:20 +00001935}
1936
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001937DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00001938{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001939 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001940
1941 /* seek interface, bus and unit */
1942
Blue Swirl72cf2d42009-09-12 07:36:22 +00001943 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001944 if (dinfo->type == type &&
1945 dinfo->bus == bus &&
1946 dinfo->unit == unit)
1947 return dinfo;
1948 }
thse4bcb142007-12-02 04:51:10 +00001949
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001950 return NULL;
thse4bcb142007-12-02 04:51:10 +00001951}
1952
Gerd Hoffmann2e810b32009-07-31 12:25:38 +02001953DriveInfo *drive_get_by_id(const char *id)
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001954{
1955 DriveInfo *dinfo;
1956
Blue Swirl72cf2d42009-09-12 07:36:22 +00001957 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02001958 if (strcmp(id, dinfo->id))
1959 continue;
1960 return dinfo;
1961 }
1962 return NULL;
1963}
1964
thsf60d39b2007-12-17 03:55:57 +00001965int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00001966{
1967 int max_bus;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001968 DriveInfo *dinfo;
thse4bcb142007-12-02 04:51:10 +00001969
1970 max_bus = -1;
Blue Swirl72cf2d42009-09-12 07:36:22 +00001971 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001972 if(dinfo->type == type &&
1973 dinfo->bus > max_bus)
1974 max_bus = dinfo->bus;
thse4bcb142007-12-02 04:51:10 +00001975 }
1976 return max_bus;
1977}
1978
aliguorifa879c62009-01-07 17:32:33 +00001979const char *drive_get_serial(BlockDriverState *bdrv)
1980{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001981 DriveInfo *dinfo;
aliguorifa879c62009-01-07 17:32:33 +00001982
Blue Swirl72cf2d42009-09-12 07:36:22 +00001983 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001984 if (dinfo->bdrv == bdrv)
1985 return dinfo->serial;
1986 }
aliguorifa879c62009-01-07 17:32:33 +00001987
1988 return "\0";
1989}
1990
Kevin Wolff7850092009-11-27 13:25:36 +01001991BlockInterfaceErrorAction drive_get_on_error(
1992 BlockDriverState *bdrv, int is_read)
aliguori428c5702009-01-21 18:59:04 +00001993{
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02001994 DriveInfo *dinfo;
aliguori428c5702009-01-21 18:59:04 +00001995
Kevin Wolffc072ec2009-11-27 13:25:36 +01001996 if (is_read) {
1997 return BLOCK_ERR_REPORT;
1998 }
1999
Blue Swirl72cf2d42009-09-12 07:36:22 +00002000 QTAILQ_FOREACH(dinfo, &drives, next) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002001 if (dinfo->bdrv == bdrv)
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002002 return is_read ? dinfo->on_read_error : dinfo->on_write_error;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002003 }
aliguori428c5702009-01-21 18:59:04 +00002004
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002005 return is_read ? BLOCK_ERR_REPORT : BLOCK_ERR_STOP_ENOSPC;
aliguori428c5702009-01-21 18:59:04 +00002006}
2007
aurel32a1620fa2008-04-29 05:58:01 +00002008static void bdrv_format_print(void *opaque, const char *name)
2009{
2010 fprintf(stderr, " %s", name);
2011}
2012
Gerd Hoffmann56a14932009-09-25 21:42:46 +02002013void drive_uninit(DriveInfo *dinfo)
aliguorib01b1112009-02-11 15:20:20 +00002014{
Gerd Hoffmann56a14932009-09-25 21:42:46 +02002015 qemu_opts_del(dinfo->opts);
2016 bdrv_delete(dinfo->bdrv);
2017 QTAILQ_REMOVE(&drives, dinfo, next);
2018 qemu_free(dinfo);
aliguorib01b1112009-02-11 15:20:20 +00002019}
2020
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002021static int parse_block_error_action(const char *buf, int is_read)
2022{
2023 if (!strcmp(buf, "ignore")) {
2024 return BLOCK_ERR_IGNORE;
2025 } else if (!is_read && !strcmp(buf, "enospc")) {
2026 return BLOCK_ERR_STOP_ENOSPC;
2027 } else if (!strcmp(buf, "stop")) {
2028 return BLOCK_ERR_STOP_ANY;
2029 } else if (!strcmp(buf, "report")) {
2030 return BLOCK_ERR_REPORT;
2031 } else {
2032 fprintf(stderr, "qemu: '%s' invalid %s error action\n",
2033 buf, is_read ? "read" : "write");
2034 return -1;
2035 }
2036}
2037
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002038DriveInfo *drive_init(QemuOpts *opts, void *opaque,
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002039 int *fatal_error)
thse4bcb142007-12-02 04:51:10 +00002040{
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002041 const char *buf;
2042 const char *file = NULL;
balrogc8522bd2007-12-06 22:11:20 +00002043 char devname[128];
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002044 const char *serial;
balrogc8522bd2007-12-06 22:11:20 +00002045 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00002046 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00002047 enum { MEDIA_DISK, MEDIA_CDROM } media;
2048 int bus_id, unit_id;
2049 int cyls, heads, secs, translation;
aurel321e72d3b2008-04-28 20:26:45 +00002050 BlockDriver *drv = NULL;
aliguori4d73cd32009-02-11 15:20:46 +00002051 QEMUMachine *machine = opaque;
thse4bcb142007-12-02 04:51:10 +00002052 int max_devs;
2053 int index;
balrog33f00272007-12-24 14:33:24 +00002054 int cache;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002055 int aio = 0;
Naphtali Sprei59f26892009-10-26 16:25:16 +02002056 int ro = 0;
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002057 int bdrv_flags;
2058 int on_read_error, on_write_error;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002059 const char *devaddr;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002060 DriveInfo *dinfo;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002061 int snapshot = 0;
2062
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002063 *fatal_error = 1;
thse4bcb142007-12-02 04:51:10 +00002064
thse4bcb142007-12-02 04:51:10 +00002065 translation = BIOS_ATA_TRANSLATION_AUTO;
Kevin Wolf0aa217e2009-06-30 13:06:04 +02002066 cache = 1;
thse4bcb142007-12-02 04:51:10 +00002067
Gerd Hoffmann4d007812009-08-31 14:23:57 +02002068 if (machine && machine->use_scsi) {
thsf60d39b2007-12-17 03:55:57 +00002069 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002070 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002071 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00002072 } else {
thsf60d39b2007-12-17 03:55:57 +00002073 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002074 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002075 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00002076 }
2077 media = MEDIA_DISK;
2078
2079 /* extract parameters */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002080 bus_id = qemu_opt_get_number(opts, "bus", 0);
2081 unit_id = qemu_opt_get_number(opts, "unit", -1);
2082 index = qemu_opt_get_number(opts, "index", -1);
thse4bcb142007-12-02 04:51:10 +00002083
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002084 cyls = qemu_opt_get_number(opts, "cyls", 0);
2085 heads = qemu_opt_get_number(opts, "heads", 0);
2086 secs = qemu_opt_get_number(opts, "secs", 0);
thse4bcb142007-12-02 04:51:10 +00002087
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002088 snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
Naphtali Sprei59f26892009-10-26 16:25:16 +02002089 ro = qemu_opt_get_bool(opts, "readonly", 0);
thse4bcb142007-12-02 04:51:10 +00002090
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002091 file = qemu_opt_get(opts, "file");
2092 serial = qemu_opt_get(opts, "serial");
2093
2094 if ((buf = qemu_opt_get(opts, "if")) != NULL) {
bellardae45d362008-06-11 09:44:44 +00002095 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00002096 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00002097 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002098 max_devs = MAX_IDE_DEVS;
2099 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00002100 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002101 max_devs = MAX_SCSI_DEVS;
2102 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00002103 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00002104 max_devs = 0;
2105 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00002106 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00002107 max_devs = 0;
2108 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00002109 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00002110 max_devs = 0;
2111 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00002112 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00002113 max_devs = 0;
aliguori6e02c382008-12-04 19:52:44 +00002114 } else if (!strcmp(buf, "virtio")) {
2115 type = IF_VIRTIO;
2116 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002117 } else if (!strcmp(buf, "xen")) {
2118 type = IF_XEN;
2119 max_devs = 0;
Gerd Hoffmanna8659e92009-07-31 12:25:39 +02002120 } else if (!strcmp(buf, "none")) {
2121 type = IF_NONE;
2122 max_devs = 0;
aliguori62d23ef2009-04-22 15:19:30 +00002123 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002124 fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002125 return NULL;
thse4bcb142007-12-02 04:51:10 +00002126 }
2127 }
2128
thse4bcb142007-12-02 04:51:10 +00002129 if (cyls || heads || secs) {
Blue Swirl5afe3f02009-10-17 09:08:47 +00002130 if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002131 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002132 return NULL;
thse4bcb142007-12-02 04:51:10 +00002133 }
Blue Swirl5afe3f02009-10-17 09:08:47 +00002134 if (heads < 1 || (type == IF_IDE && heads > 16)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002135 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002136 return NULL;
thse4bcb142007-12-02 04:51:10 +00002137 }
Blue Swirl5afe3f02009-10-17 09:08:47 +00002138 if (secs < 1 || (type == IF_IDE && secs > 63)) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002139 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002140 return NULL;
thse4bcb142007-12-02 04:51:10 +00002141 }
2142 }
2143
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002144 if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002145 if (!cyls) {
2146 fprintf(stderr,
2147 "qemu: '%s' trans must be used with cyls,heads and secs\n",
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002148 buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002149 return NULL;
thse4bcb142007-12-02 04:51:10 +00002150 }
2151 if (!strcmp(buf, "none"))
2152 translation = BIOS_ATA_TRANSLATION_NONE;
2153 else if (!strcmp(buf, "lba"))
2154 translation = BIOS_ATA_TRANSLATION_LBA;
2155 else if (!strcmp(buf, "auto"))
2156 translation = BIOS_ATA_TRANSLATION_AUTO;
2157 else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002158 fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002159 return NULL;
thse4bcb142007-12-02 04:51:10 +00002160 }
2161 }
2162
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002163 if ((buf = qemu_opt_get(opts, "media")) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002164 if (!strcmp(buf, "disk")) {
2165 media = MEDIA_DISK;
2166 } else if (!strcmp(buf, "cdrom")) {
2167 if (cyls || secs || heads) {
2168 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002169 "qemu: '%s' invalid physical CHS format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002170 return NULL;
thse4bcb142007-12-02 04:51:10 +00002171 }
2172 media = MEDIA_CDROM;
2173 } else {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002174 fprintf(stderr, "qemu: '%s' invalid media\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002175 return NULL;
thse4bcb142007-12-02 04:51:10 +00002176 }
2177 }
2178
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002179 if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
aliguori9f7965c2008-10-14 14:42:54 +00002180 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
balrog33f00272007-12-24 14:33:24 +00002181 cache = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002182 else if (!strcmp(buf, "writethrough"))
balrog33f00272007-12-24 14:33:24 +00002183 cache = 1;
aliguori9f7965c2008-10-14 14:42:54 +00002184 else if (!strcmp(buf, "writeback"))
2185 cache = 2;
balrog33f00272007-12-24 14:33:24 +00002186 else {
2187 fprintf(stderr, "qemu: invalid cache option\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002188 return NULL;
balrog33f00272007-12-24 14:33:24 +00002189 }
2190 }
2191
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002192#ifdef CONFIG_LINUX_AIO
2193 if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
2194 if (!strcmp(buf, "threads"))
2195 aio = 0;
2196 else if (!strcmp(buf, "native"))
2197 aio = 1;
2198 else {
2199 fprintf(stderr, "qemu: invalid aio option\n");
2200 return NULL;
2201 }
2202 }
2203#endif
2204
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002205 if ((buf = qemu_opt_get(opts, "format")) != NULL) {
aurel32a1620fa2008-04-29 05:58:01 +00002206 if (strcmp(buf, "?") == 0) {
2207 fprintf(stderr, "qemu: Supported formats:");
2208 bdrv_iterate_format(bdrv_format_print, NULL);
2209 fprintf(stderr, "\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002210 return NULL;
aurel32a1620fa2008-04-29 05:58:01 +00002211 }
Markus Armbrustereb852012009-10-27 18:41:44 +01002212 drv = bdrv_find_whitelisted_format(buf);
aurel321e72d3b2008-04-28 20:26:45 +00002213 if (!drv) {
2214 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002215 return NULL;
aurel321e72d3b2008-04-28 20:26:45 +00002216 }
2217 }
2218
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002219 on_write_error = BLOCK_ERR_STOP_ENOSPC;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002220 if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
aliguori869a5c62009-01-22 19:52:25 +00002221 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
aliguoriea8a5d72009-01-22 19:52:21 +00002222 fprintf(stderr, "werror is no supported by this format\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002223 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002224 }
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002225
2226 on_write_error = parse_block_error_action(buf, 0);
2227 if (on_write_error < 0) {
2228 return NULL;
2229 }
2230 }
2231
2232 on_read_error = BLOCK_ERR_REPORT;
2233 if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
Kevin Wolff35d68f2009-11-27 13:25:39 +01002234 if (type != IF_IDE && type != IF_VIRTIO) {
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002235 fprintf(stderr, "rerror is no supported by this format\n");
2236 return NULL;
2237 }
2238
2239 on_read_error = parse_block_error_action(buf, 1);
2240 if (on_read_error < 0) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002241 return NULL;
aliguori428c5702009-01-21 18:59:04 +00002242 }
2243 }
2244
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002245 if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002246 if (type != IF_VIRTIO) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002247 fprintf(stderr, "addr is not supported\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002248 return NULL;
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002249 }
Markus Armbrusterc2cc47a2009-06-18 15:14:10 +02002250 }
2251
thse4bcb142007-12-02 04:51:10 +00002252 /* compute bus and unit according index */
2253
2254 if (index != -1) {
2255 if (bus_id != 0 || unit_id != -1) {
2256 fprintf(stderr,
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002257 "qemu: index cannot be used with bus and unit\n");
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002258 return NULL;
thse4bcb142007-12-02 04:51:10 +00002259 }
2260 if (max_devs == 0)
2261 {
2262 unit_id = index;
2263 bus_id = 0;
2264 } else {
2265 unit_id = index % max_devs;
2266 bus_id = index / max_devs;
2267 }
2268 }
2269
2270 /* if user doesn't specify a unit_id,
2271 * try to find the first free
2272 */
2273
2274 if (unit_id == -1) {
2275 unit_id = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002276 while (drive_get(type, bus_id, unit_id) != NULL) {
thse4bcb142007-12-02 04:51:10 +00002277 unit_id++;
2278 if (max_devs && unit_id >= max_devs) {
2279 unit_id -= max_devs;
2280 bus_id++;
2281 }
2282 }
2283 }
2284
2285 /* check unit id */
2286
2287 if (max_devs && unit_id >= max_devs) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002288 fprintf(stderr, "qemu: unit %d too big (max is %d)\n",
2289 unit_id, max_devs - 1);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002290 return NULL;
thse4bcb142007-12-02 04:51:10 +00002291 }
2292
2293 /*
2294 * ignore multiple definitions
2295 */
2296
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002297 if (drive_get(type, bus_id, unit_id) != NULL) {
2298 *fatal_error = 0;
2299 return NULL;
2300 }
thse4bcb142007-12-02 04:51:10 +00002301
2302 /* init */
2303
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002304 dinfo = qemu_mallocz(sizeof(*dinfo));
Gerd Hoffmanne23d9c42009-07-31 12:25:34 +02002305 if ((buf = qemu_opts_id(opts)) != NULL) {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002306 dinfo->id = qemu_strdup(buf);
2307 } else {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002308 /* no id supplied -> create one */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002309 dinfo->id = qemu_mallocz(32);
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002310 if (type == IF_IDE || type == IF_SCSI)
2311 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
2312 if (max_devs)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002313 snprintf(dinfo->id, 32, "%s%i%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002314 devname, bus_id, mediastr, unit_id);
2315 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002316 snprintf(dinfo->id, 32, "%s%s%i",
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002317 devname, mediastr, unit_id);
2318 }
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002319 dinfo->bdrv = bdrv_new(dinfo->id);
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002320 dinfo->devaddr = devaddr;
2321 dinfo->type = type;
2322 dinfo->bus = bus_id;
2323 dinfo->unit = unit_id;
Kevin Wolfe9b2e812009-11-27 13:25:37 +01002324 dinfo->on_read_error = on_read_error;
2325 dinfo->on_write_error = on_write_error;
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002326 dinfo->opts = opts;
2327 if (serial)
2328 strncpy(dinfo->serial, serial, sizeof(serial));
Blue Swirl72cf2d42009-09-12 07:36:22 +00002329 QTAILQ_INSERT_TAIL(&drives, dinfo, next);
thse4bcb142007-12-02 04:51:10 +00002330
thsf60d39b2007-12-17 03:55:57 +00002331 switch(type) {
thse4bcb142007-12-02 04:51:10 +00002332 case IF_IDE:
2333 case IF_SCSI:
aliguori62d23ef2009-04-22 15:19:30 +00002334 case IF_XEN:
Gerd Hoffmannc2193312009-09-15 19:23:28 +00002335 case IF_NONE:
thse4bcb142007-12-02 04:51:10 +00002336 switch(media) {
2337 case MEDIA_DISK:
2338 if (cyls != 0) {
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002339 bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
2340 bdrv_set_translation_hint(dinfo->bdrv, translation);
thse4bcb142007-12-02 04:51:10 +00002341 }
2342 break;
2343 case MEDIA_CDROM:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002344 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
thse4bcb142007-12-02 04:51:10 +00002345 break;
2346 }
2347 break;
2348 case IF_SD:
2349 /* FIXME: This isn't really a floppy, but it's a reasonable
2350 approximation. */
2351 case IF_FLOPPY:
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002352 bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
thse4bcb142007-12-02 04:51:10 +00002353 break;
2354 case IF_PFLASH:
2355 case IF_MTD:
2356 break;
Gerd Hoffmannd176c492009-07-31 12:25:41 +02002357 case IF_VIRTIO:
2358 /* add virtio block device */
2359 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
2360 qemu_opt_set(opts, "driver", "virtio-blk-pci");
2361 qemu_opt_set(opts, "drive", dinfo->id);
2362 if (devaddr)
2363 qemu_opt_set(opts, "addr", devaddr);
2364 break;
Paul Brookaae94602009-05-14 22:35:06 +01002365 case IF_COUNT:
2366 abort();
thse4bcb142007-12-02 04:51:10 +00002367 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002368 if (!file) {
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002369 *fatal_error = 0;
2370 return NULL;
2371 }
balrog33f00272007-12-24 14:33:24 +00002372 bdrv_flags = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002373 if (snapshot) {
balrog33f00272007-12-24 14:33:24 +00002374 bdrv_flags |= BDRV_O_SNAPSHOT;
aliguori9f7965c2008-10-14 14:42:54 +00002375 cache = 2; /* always use write-back with snapshot */
2376 }
2377 if (cache == 0) /* no caching */
2378 bdrv_flags |= BDRV_O_NOCACHE;
2379 else if (cache == 2) /* write-back */
2380 bdrv_flags |= BDRV_O_CACHE_WB;
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002381
2382 if (aio == 1) {
2383 bdrv_flags |= BDRV_O_NATIVE_AIO;
2384 } else {
2385 bdrv_flags &= ~BDRV_O_NATIVE_AIO;
2386 }
2387
Naphtali Sprei59f26892009-10-26 16:25:16 +02002388 if (ro == 1) {
2389 if (type == IF_IDE) {
2390 fprintf(stderr, "qemu: readonly flag not supported for drive with ide interface\n");
2391 return NULL;
2392 }
2393 (void)bdrv_set_read_only(dinfo->bdrv, 1);
2394 }
2395
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002396 if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05002397 fprintf(stderr, "qemu: could not open disk image %s: %s\n",
2398 file, strerror(errno));
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002399 return NULL;
thse4bcb142007-12-02 04:51:10 +00002400 }
Christoph Hellwig5c6c3a62009-08-20 16:58:35 +02002401
Gerd Hoffmann1dae12e2009-07-22 16:42:58 +02002402 if (bdrv_key_required(dinfo->bdrv))
aliguoric0f4ce72009-03-05 23:01:01 +00002403 autostart = 0;
Gerd Hoffmann751c6a12009-07-22 16:42:57 +02002404 *fatal_error = 0;
2405 return dinfo;
thse4bcb142007-12-02 04:51:10 +00002406}
2407
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02002408static int drive_init_func(QemuOpts *opts, void *opaque)
2409{
2410 QEMUMachine *machine = opaque;
2411 int fatal_error = 0;
2412
2413 if (drive_init(opts, machine, &fatal_error) == NULL) {
2414 if (fatal_error)
2415 return 1;
2416 }
2417 return 0;
2418}
2419
2420static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
2421{
2422 if (NULL == qemu_opt_get(opts, "snapshot")) {
2423 qemu_opt_set(opts, "snapshot", "on");
2424 }
2425 return 0;
2426}
2427
Jan Kiszka76e30d02009-07-02 00:19:02 +02002428void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
2429{
2430 boot_set_handler = func;
2431 boot_set_opaque = opaque;
2432}
2433
2434int qemu_boot_set(const char *boot_devices)
2435{
2436 if (!boot_set_handler) {
2437 return -EINVAL;
2438 }
2439 return boot_set_handler(boot_set_opaque, boot_devices);
2440}
2441
Jan Kiszkaef3adf62009-07-02 00:19:02 +02002442static int parse_bootdevices(char *devices)
2443{
2444 /* We just do some generic consistency checks */
2445 const char *p;
2446 int bitmap = 0;
2447
2448 for (p = devices; *p != '\0'; p++) {
2449 /* Allowed boot devices are:
2450 * a-b: floppy disk drives
2451 * c-f: IDE disk drives
2452 * g-m: machine implementation dependant drives
2453 * n-p: network devices
2454 * It's up to each machine implementation to check if the given boot
2455 * devices match the actual hardware implementation and firmware
2456 * features.
2457 */
2458 if (*p < 'a' || *p > 'p') {
2459 fprintf(stderr, "Invalid boot device '%c'\n", *p);
2460 exit(1);
2461 }
2462 if (bitmap & (1 << (*p - 'a'))) {
2463 fprintf(stderr, "Boot device '%c' was given twice\n", *p);
2464 exit(1);
2465 }
2466 bitmap |= 1 << (*p - 'a');
2467 }
2468 return bitmap;
2469}
2470
Jan Kiszkae0f084b2009-07-02 00:19:02 +02002471static void restore_boot_devices(void *opaque)
2472{
2473 char *standard_boot_devices = opaque;
2474
2475 qemu_boot_set(standard_boot_devices);
2476
2477 qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
2478 qemu_free(standard_boot_devices);
2479}
2480
aliguori268a3622009-04-21 22:30:27 +00002481static void numa_add(const char *optarg)
2482{
2483 char option[128];
2484 char *endptr;
2485 unsigned long long value, endvalue;
2486 int nodenr;
2487
2488 optarg = get_opt_name(option, 128, optarg, ',') + 1;
2489 if (!strcmp(option, "node")) {
2490 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
2491 nodenr = nb_numa_nodes;
2492 } else {
2493 nodenr = strtoull(option, NULL, 10);
2494 }
2495
2496 if (get_param_value(option, 128, "mem", optarg) == 0) {
2497 node_mem[nodenr] = 0;
2498 } else {
2499 value = strtoull(option, &endptr, 0);
2500 switch (*endptr) {
2501 case 0: case 'M': case 'm':
2502 value <<= 20;
2503 break;
2504 case 'G': case 'g':
2505 value <<= 30;
2506 break;
2507 }
2508 node_mem[nodenr] = value;
2509 }
2510 if (get_param_value(option, 128, "cpus", optarg) == 0) {
2511 node_cpumask[nodenr] = 0;
2512 } else {
2513 value = strtoull(option, &endptr, 10);
2514 if (value >= 64) {
2515 value = 63;
2516 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
2517 } else {
2518 if (*endptr == '-') {
2519 endvalue = strtoull(endptr+1, &endptr, 10);
2520 if (endvalue >= 63) {
2521 endvalue = 62;
2522 fprintf(stderr,
2523 "only 63 CPUs in NUMA mode supported.\n");
2524 }
2525 value = (1 << (endvalue + 1)) - (1 << value);
2526 } else {
2527 value = 1 << value;
2528 }
2529 }
2530 node_cpumask[nodenr] = value;
2531 }
2532 nb_numa_nodes++;
2533 }
2534 return;
2535}
2536
Andre Przywaradc6b1c02009-08-19 15:42:40 +02002537static void smp_parse(const char *optarg)
2538{
2539 int smp, sockets = 0, threads = 0, cores = 0;
2540 char *endptr;
2541 char option[128];
2542
2543 smp = strtoul(optarg, &endptr, 10);
2544 if (endptr != optarg) {
2545 if (*endptr == ',') {
2546 endptr++;
2547 }
2548 }
2549 if (get_param_value(option, 128, "sockets", endptr) != 0)
2550 sockets = strtoull(option, NULL, 10);
2551 if (get_param_value(option, 128, "cores", endptr) != 0)
2552 cores = strtoull(option, NULL, 10);
2553 if (get_param_value(option, 128, "threads", endptr) != 0)
2554 threads = strtoull(option, NULL, 10);
2555 if (get_param_value(option, 128, "maxcpus", endptr) != 0)
2556 max_cpus = strtoull(option, NULL, 10);
2557
2558 /* compute missing values, prefer sockets over cores over threads */
2559 if (smp == 0 || sockets == 0) {
2560 sockets = sockets > 0 ? sockets : 1;
2561 cores = cores > 0 ? cores : 1;
2562 threads = threads > 0 ? threads : 1;
2563 if (smp == 0) {
2564 smp = cores * threads * sockets;
2565 } else {
2566 sockets = smp / (cores * threads);
2567 }
2568 } else {
2569 if (cores == 0) {
2570 threads = threads > 0 ? threads : 1;
2571 cores = smp / (sockets * threads);
2572 } else {
2573 if (sockets == 0) {
2574 sockets = smp / (cores * threads);
2575 } else {
2576 threads = smp / (cores * sockets);
2577 }
2578 }
2579 }
2580 smp_cpus = smp;
2581 smp_cores = cores > 0 ? cores : 1;
2582 smp_threads = threads > 0 ? threads : 1;
2583 if (max_cpus == 0)
2584 max_cpus = smp_cpus;
2585}
2586
bellard330d0412003-07-26 18:11:40 +00002587/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00002588/* USB devices */
2589
aliguoric0f4ce72009-03-05 23:01:01 +00002590static int usb_device_add(const char *devname, int is_hotplug)
bellarda594cfb2005-11-06 16:13:29 +00002591{
2592 const char *p;
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002593 USBDevice *dev = NULL;
bellarda594cfb2005-11-06 16:13:29 +00002594
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002595 if (!usb_enabled)
bellarda594cfb2005-11-06 16:13:29 +00002596 return -1;
2597
Gerd Hoffmann0958b4c2009-10-26 15:56:45 +01002598 /* drivers with .usbdevice_name entry in USBDeviceInfo */
2599 dev = usbdevice_create(devname);
2600 if (dev)
2601 goto done;
2602
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002603 /* the other ones */
bellarda594cfb2005-11-06 16:13:29 +00002604 if (strstart(devname, "host:", &p)) {
2605 dev = usb_host_device_open(p);
balrog6c9f8862008-07-17 20:47:13 +00002606 } else if (strstart(devname, "net:", &p)) {
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002607 QemuOpts *opts;
2608 int idx;
balrog6c9f8862008-07-17 20:47:13 +00002609
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002610 opts = qemu_opts_parse(&qemu_net_opts, p, NULL);
2611 if (!opts) {
balrog6c9f8862008-07-17 20:47:13 +00002612 return -1;
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002613 }
2614
2615 qemu_opt_set(opts, "type", "nic");
2616 qemu_opt_set(opts, "model", "usb");
2617
Mark McLoughlinf6b134a2009-10-08 19:58:27 +01002618 idx = net_client_init(NULL, opts, 0);
Mark McLoughlin13cf8f22009-10-06 12:17:14 +01002619 if (idx == -1) {
2620 return -1;
2621 }
2622
2623 dev = usb_net_init(&nd_table[idx]);
balrogdc72ac12008-11-09 00:04:26 +00002624 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
2625 dev = usb_bt_init(devname[2] ? hci_init(p) :
2626 bt_new_hci(qemu_find_bt_vlan(0)));
bellarda594cfb2005-11-06 16:13:29 +00002627 } else {
2628 return -1;
2629 }
pbrook0d92ed32006-05-21 16:30:15 +00002630 if (!dev)
2631 return -1;
2632
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002633done:
bellarda594cfb2005-11-06 16:13:29 +00002634 return 0;
2635}
2636
aliguori1f3870a2008-08-21 19:27:48 +00002637static int usb_device_del(const char *devname)
2638{
2639 int bus_num, addr;
2640 const char *p;
2641
aliguori5d0c5752008-09-14 01:07:41 +00002642 if (strstart(devname, "host:", &p))
2643 return usb_host_device_close(p);
2644
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002645 if (!usb_enabled)
aliguori1f3870a2008-08-21 19:27:48 +00002646 return -1;
2647
2648 p = strchr(devname, '.');
2649 if (!p)
2650 return -1;
2651 bus_num = strtoul(devname, NULL, 0);
2652 addr = strtoul(p + 1, NULL, 0);
2653
Gerd Hoffmanna5d2f722009-08-31 14:24:00 +02002654 return usb_device_delete_addr(bus_num, addr);
aliguori1f3870a2008-08-21 19:27:48 +00002655}
2656
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02002657static int usb_parse(const char *cmdline)
2658{
2659 return usb_device_add(cmdline, 0);
2660}
2661
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002662void do_usb_add(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002663{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002664 usb_device_add(qdict_get_str(qdict, "devname"), 1);
bellarda594cfb2005-11-06 16:13:29 +00002665}
2666
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002667void do_usb_del(Monitor *mon, const QDict *qdict)
bellarda594cfb2005-11-06 16:13:29 +00002668{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002669 usb_device_del(qdict_get_str(qdict, "devname"));
bellarda594cfb2005-11-06 16:13:29 +00002670}
2671
bellardf7cce892004-12-08 22:21:25 +00002672/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00002673/* PCMCIA/Cardbus */
2674
2675static struct pcmcia_socket_entry_s {
Paul Brookbc24a222009-05-10 01:44:56 +01002676 PCMCIASocket *socket;
balrog201a51f2007-04-30 00:51:09 +00002677 struct pcmcia_socket_entry_s *next;
2678} *pcmcia_sockets = 0;
2679
Paul Brookbc24a222009-05-10 01:44:56 +01002680void pcmcia_socket_register(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002681{
2682 struct pcmcia_socket_entry_s *entry;
2683
2684 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
2685 entry->socket = socket;
2686 entry->next = pcmcia_sockets;
2687 pcmcia_sockets = entry;
2688}
2689
Paul Brookbc24a222009-05-10 01:44:56 +01002690void pcmcia_socket_unregister(PCMCIASocket *socket)
balrog201a51f2007-04-30 00:51:09 +00002691{
2692 struct pcmcia_socket_entry_s *entry, **ptr;
2693
2694 ptr = &pcmcia_sockets;
2695 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
2696 if (entry->socket == socket) {
2697 *ptr = entry->next;
2698 qemu_free(entry);
2699 }
2700}
2701
aliguori376253e2009-03-05 23:01:23 +00002702void pcmcia_info(Monitor *mon)
balrog201a51f2007-04-30 00:51:09 +00002703{
2704 struct pcmcia_socket_entry_s *iter;
aliguori376253e2009-03-05 23:01:23 +00002705
balrog201a51f2007-04-30 00:51:09 +00002706 if (!pcmcia_sockets)
aliguori376253e2009-03-05 23:01:23 +00002707 monitor_printf(mon, "No PCMCIA sockets\n");
balrog201a51f2007-04-30 00:51:09 +00002708
2709 for (iter = pcmcia_sockets; iter; iter = iter->next)
aliguori376253e2009-03-05 23:01:23 +00002710 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
2711 iter->socket->attached ? iter->socket->card_string :
2712 "Empty");
balrog201a51f2007-04-30 00:51:09 +00002713}
2714
2715/***********************************************************/
aliguori3023f332009-01-16 19:04:14 +00002716/* register display */
2717
aliguori7b5d76d2009-03-13 15:02:13 +00002718struct DisplayAllocator default_allocator = {
2719 defaultallocator_create_displaysurface,
2720 defaultallocator_resize_displaysurface,
2721 defaultallocator_free_displaysurface
2722};
2723
aliguori3023f332009-01-16 19:04:14 +00002724void register_displaystate(DisplayState *ds)
2725{
2726 DisplayState **s;
2727 s = &display_state;
2728 while (*s != NULL)
2729 s = &(*s)->next;
2730 ds->next = NULL;
2731 *s = ds;
2732}
2733
2734DisplayState *get_displaystate(void)
2735{
2736 return display_state;
2737}
2738
aliguori7b5d76d2009-03-13 15:02:13 +00002739DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
2740{
2741 if(ds->allocator == &default_allocator) ds->allocator = da;
2742 return ds->allocator;
2743}
2744
ths2ff89792007-06-21 23:34:19 +00002745/* dumb display */
2746
aliguori8f391ab2009-01-19 16:34:10 +00002747static void dumb_display_init(void)
ths2ff89792007-06-21 23:34:19 +00002748{
aliguori8f391ab2009-01-19 16:34:10 +00002749 DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
aliguori7b5d76d2009-03-13 15:02:13 +00002750 ds->allocator = &default_allocator;
2751 ds->surface = qemu_create_displaysurface(ds, 640, 480);
aliguori8f391ab2009-01-19 16:34:10 +00002752 register_displaystate(ds);
ths2ff89792007-06-21 23:34:19 +00002753}
2754
2755/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002756/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00002757
bellardc4b1fcc2004-03-14 21:44:30 +00002758typedef struct IOHandlerRecord {
2759 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00002760 IOCanRWHandler *fd_read_poll;
2761 IOHandler *fd_read;
2762 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00002763 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00002764 void *opaque;
2765 /* temporary data */
2766 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00002767 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00002768} IOHandlerRecord;
2769
bellard8a7ddc32004-03-31 19:00:16 +00002770static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00002771
bellard7c9d8e02005-11-15 22:16:05 +00002772/* XXX: fd_read_poll should be suppressed, but an API change is
2773 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00002774int qemu_set_fd_handler2(int fd,
2775 IOCanRWHandler *fd_read_poll,
2776 IOHandler *fd_read,
2777 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002778 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00002779{
bellard8a7ddc32004-03-31 19:00:16 +00002780 IOHandlerRecord **pioh, *ioh;
2781
bellard7c9d8e02005-11-15 22:16:05 +00002782 if (!fd_read && !fd_write) {
2783 pioh = &first_io_handler;
2784 for(;;) {
2785 ioh = *pioh;
2786 if (ioh == NULL)
2787 break;
2788 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00002789 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00002790 break;
2791 }
2792 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00002793 }
bellard7c9d8e02005-11-15 22:16:05 +00002794 } else {
2795 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2796 if (ioh->fd == fd)
2797 goto found;
2798 }
2799 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
bellard7c9d8e02005-11-15 22:16:05 +00002800 ioh->next = first_io_handler;
2801 first_io_handler = ioh;
2802 found:
2803 ioh->fd = fd;
2804 ioh->fd_read_poll = fd_read_poll;
2805 ioh->fd_read = fd_read;
2806 ioh->fd_write = fd_write;
2807 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00002808 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00002809 }
bellard7c9d8e02005-11-15 22:16:05 +00002810 return 0;
2811}
2812
ths5fafdf22007-09-16 21:08:06 +00002813int qemu_set_fd_handler(int fd,
2814 IOHandler *fd_read,
2815 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002816 void *opaque)
2817{
2818 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00002819}
2820
aliguori56f3a5d2008-10-31 18:07:17 +00002821#ifdef _WIN32
bellard8a7ddc32004-03-31 19:00:16 +00002822/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00002823/* Polling handling */
2824
2825typedef struct PollingEntry {
2826 PollingFunc *func;
2827 void *opaque;
2828 struct PollingEntry *next;
2829} PollingEntry;
2830
2831static PollingEntry *first_polling_entry;
2832
2833int qemu_add_polling_cb(PollingFunc *func, void *opaque)
2834{
2835 PollingEntry **ppe, *pe;
2836 pe = qemu_mallocz(sizeof(PollingEntry));
bellardf3311102006-04-12 20:21:17 +00002837 pe->func = func;
2838 pe->opaque = opaque;
2839 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
2840 *ppe = pe;
2841 return 0;
2842}
2843
2844void qemu_del_polling_cb(PollingFunc *func, void *opaque)
2845{
2846 PollingEntry **ppe, *pe;
2847 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
2848 pe = *ppe;
2849 if (pe->func == func && pe->opaque == opaque) {
2850 *ppe = pe->next;
2851 qemu_free(pe);
2852 break;
2853 }
2854 }
2855}
2856
bellarda18e5242006-06-25 17:18:27 +00002857/***********************************************************/
2858/* Wait objects support */
2859typedef struct WaitObjects {
2860 int num;
2861 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
2862 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
2863 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
2864} WaitObjects;
2865
2866static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00002867
bellarda18e5242006-06-25 17:18:27 +00002868int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2869{
2870 WaitObjects *w = &wait_objects;
2871
2872 if (w->num >= MAXIMUM_WAIT_OBJECTS)
2873 return -1;
2874 w->events[w->num] = handle;
2875 w->func[w->num] = func;
2876 w->opaque[w->num] = opaque;
2877 w->num++;
2878 return 0;
2879}
2880
2881void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2882{
2883 int i, found;
2884 WaitObjects *w = &wait_objects;
2885
2886 found = 0;
2887 for (i = 0; i < w->num; i++) {
2888 if (w->events[i] == handle)
2889 found = 1;
2890 if (found) {
2891 w->events[i] = w->events[i + 1];
2892 w->func[i] = w->func[i + 1];
2893 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00002894 }
bellarda18e5242006-06-25 17:18:27 +00002895 }
2896 if (found)
2897 w->num--;
2898}
2899#endif
2900
bellard8a7ddc32004-03-31 19:00:16 +00002901/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002902/* ram save/restore */
2903
Juan Quintela94fb0902009-09-10 03:04:23 +02002904#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
aliguori475e4272008-10-06 20:21:51 +00002905#define RAM_SAVE_FLAG_COMPRESS 0x02
2906#define RAM_SAVE_FLAG_MEM_SIZE 0x04
2907#define RAM_SAVE_FLAG_PAGE 0x08
2908#define RAM_SAVE_FLAG_EOS 0x10
2909
2910static int is_dup_page(uint8_t *page, uint8_t ch)
bellardc88676f2006-08-06 13:36:11 +00002911{
aliguori475e4272008-10-06 20:21:51 +00002912 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
2913 uint32_t *array = (uint32_t *)page;
2914 int i;
ths3b46e622007-09-17 08:09:54 +00002915
aliguori475e4272008-10-06 20:21:51 +00002916 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
2917 if (array[i] != val)
2918 return 0;
bellardc88676f2006-08-06 13:36:11 +00002919 }
aliguori475e4272008-10-06 20:21:51 +00002920
2921 return 1;
bellardc88676f2006-08-06 13:36:11 +00002922}
2923
aliguori475e4272008-10-06 20:21:51 +00002924static int ram_save_block(QEMUFile *f)
2925{
Anthony Liguoric227f092009-10-01 16:12:16 -05002926 static ram_addr_t current_addr = 0;
2927 ram_addr_t saved_addr = current_addr;
2928 ram_addr_t addr = 0;
aliguori475e4272008-10-06 20:21:51 +00002929 int found = 0;
2930
pbrook94a6b542009-04-11 17:15:54 +00002931 while (addr < last_ram_offset) {
aliguori475e4272008-10-06 20:21:51 +00002932 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
pbrook5579c7f2009-04-11 14:47:08 +00002933 uint8_t *p;
aliguori475e4272008-10-06 20:21:51 +00002934
2935 cpu_physical_memory_reset_dirty(current_addr,
2936 current_addr + TARGET_PAGE_SIZE,
2937 MIGRATION_DIRTY_FLAG);
2938
pbrook5579c7f2009-04-11 14:47:08 +00002939 p = qemu_get_ram_ptr(current_addr);
aliguori475e4272008-10-06 20:21:51 +00002940
pbrook5579c7f2009-04-11 14:47:08 +00002941 if (is_dup_page(p, *p)) {
aliguori475e4272008-10-06 20:21:51 +00002942 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
pbrook5579c7f2009-04-11 14:47:08 +00002943 qemu_put_byte(f, *p);
aliguori475e4272008-10-06 20:21:51 +00002944 } else {
2945 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
pbrook5579c7f2009-04-11 14:47:08 +00002946 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
aliguori475e4272008-10-06 20:21:51 +00002947 }
2948
2949 found = 1;
2950 break;
2951 }
2952 addr += TARGET_PAGE_SIZE;
pbrook94a6b542009-04-11 17:15:54 +00002953 current_addr = (saved_addr + addr) % last_ram_offset;
aliguori475e4272008-10-06 20:21:51 +00002954 }
2955
2956 return found;
2957}
2958
Jan Kiszka84307932009-12-02 11:29:38 +01002959static uint64_t bytes_transferred;
aliguori475e4272008-10-06 20:21:51 +00002960
Anthony Liguoric227f092009-10-01 16:12:16 -05002961static ram_addr_t ram_save_remaining(void)
aliguori475e4272008-10-06 20:21:51 +00002962{
Anthony Liguoric227f092009-10-01 16:12:16 -05002963 ram_addr_t addr;
2964 ram_addr_t count = 0;
aliguori475e4272008-10-06 20:21:51 +00002965
pbrook94a6b542009-04-11 17:15:54 +00002966 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00002967 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2968 count++;
2969 }
2970
2971 return count;
2972}
2973
Glauber Costa9f9e28c2009-05-21 17:38:01 -04002974uint64_t ram_bytes_remaining(void)
2975{
2976 return ram_save_remaining() * TARGET_PAGE_SIZE;
2977}
2978
2979uint64_t ram_bytes_transferred(void)
2980{
2981 return bytes_transferred;
2982}
2983
2984uint64_t ram_bytes_total(void)
2985{
2986 return last_ram_offset;
2987}
2988
Jan Kiszkaf327aa02009-11-30 18:21:21 +01002989static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
aliguori475e4272008-10-06 20:21:51 +00002990{
Anthony Liguoric227f092009-10-01 16:12:16 -05002991 ram_addr_t addr;
Glauber Costaa0a3fd62009-05-28 15:22:57 -04002992 uint64_t bytes_transferred_last;
2993 double bwidth = 0;
2994 uint64_t expected_time = 0;
aliguori475e4272008-10-06 20:21:51 +00002995
Jan Kiszka4ec7fcc2009-11-30 18:21:21 +01002996 if (stage < 0) {
2997 cpu_physical_memory_set_dirty_tracking(0);
2998 return 0;
2999 }
3000
Jan Kiszka9fa06382009-05-22 23:51:45 +02003001 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
Jan Kiszkab0a46a32009-05-02 00:22:51 +02003002 qemu_file_set_error(f);
3003 return 0;
3004 }
3005
aliguori475e4272008-10-06 20:21:51 +00003006 if (stage == 1) {
Jan Kiszka84307932009-12-02 11:29:38 +01003007 bytes_transferred = 0;
3008
aliguori475e4272008-10-06 20:21:51 +00003009 /* Make sure all dirty bits are set */
pbrook94a6b542009-04-11 17:15:54 +00003010 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
aliguori475e4272008-10-06 20:21:51 +00003011 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
3012 cpu_physical_memory_set_dirty(addr);
3013 }
Jan Kiszkab0a46a32009-05-02 00:22:51 +02003014
aliguori475e4272008-10-06 20:21:51 +00003015 /* Enable dirty memory tracking */
3016 cpu_physical_memory_set_dirty_tracking(1);
3017
pbrook94a6b542009-04-11 17:15:54 +00003018 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
aliguori475e4272008-10-06 20:21:51 +00003019 }
3020
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003021 bytes_transferred_last = bytes_transferred;
3022 bwidth = get_clock();
3023
aliguori475e4272008-10-06 20:21:51 +00003024 while (!qemu_file_rate_limit(f)) {
3025 int ret;
3026
3027 ret = ram_save_block(f);
Glauber Costa9f9e28c2009-05-21 17:38:01 -04003028 bytes_transferred += ret * TARGET_PAGE_SIZE;
aliguori475e4272008-10-06 20:21:51 +00003029 if (ret == 0) /* no more blocks */
3030 break;
3031 }
3032
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003033 bwidth = get_clock() - bwidth;
3034 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
3035
3036 /* if we haven't transferred anything this round, force expected_time to a
3037 * a very high value, but without crashing */
3038 if (bwidth == 0)
3039 bwidth = 0.000001;
3040
aliguori475e4272008-10-06 20:21:51 +00003041 /* try transferring iterative blocks of memory */
aliguori475e4272008-10-06 20:21:51 +00003042 if (stage == 3) {
aliguori475e4272008-10-06 20:21:51 +00003043 /* flush all remaining blocks regardless of rate limiting */
Glauber Costa9f9e28c2009-05-21 17:38:01 -04003044 while (ram_save_block(f) != 0) {
3045 bytes_transferred += TARGET_PAGE_SIZE;
3046 }
aliguori8215e912009-04-05 19:30:55 +00003047 cpu_physical_memory_set_dirty_tracking(0);
aliguori475e4272008-10-06 20:21:51 +00003048 }
3049
3050 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
3051
Glauber Costaa0a3fd62009-05-28 15:22:57 -04003052 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
3053
3054 return (stage == 2) && (expected_time <= migrate_max_downtime());
aliguori475e4272008-10-06 20:21:51 +00003055}
3056
aliguori475e4272008-10-06 20:21:51 +00003057static int ram_load(QEMUFile *f, void *opaque, int version_id)
3058{
Anthony Liguoric227f092009-10-01 16:12:16 -05003059 ram_addr_t addr;
aliguori475e4272008-10-06 20:21:51 +00003060 int flags;
3061
aliguori475e4272008-10-06 20:21:51 +00003062 if (version_id != 3)
3063 return -EINVAL;
3064
3065 do {
3066 addr = qemu_get_be64(f);
3067
3068 flags = addr & ~TARGET_PAGE_MASK;
3069 addr &= TARGET_PAGE_MASK;
3070
3071 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
pbrook94a6b542009-04-11 17:15:54 +00003072 if (addr != last_ram_offset)
aliguori475e4272008-10-06 20:21:51 +00003073 return -EINVAL;
3074 }
3075
aliguori475e4272008-10-06 20:21:51 +00003076 if (flags & RAM_SAVE_FLAG_COMPRESS) {
3077 uint8_t ch = qemu_get_byte(f);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003078 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
3079#ifndef _WIN32
Anthony Liguori30868442009-06-17 16:46:12 -05003080 if (ch == 0 &&
3081 (!kvm_enabled() || kvm_has_sync_mmu())) {
3082 madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED);
Anthony Liguori779c6be2009-06-22 12:39:00 -05003083 }
Anthony Liguori30868442009-06-17 16:46:12 -05003084#endif
Jan Kiszka9a743e52009-11-30 18:21:21 +01003085 } else if (flags & RAM_SAVE_FLAG_PAGE) {
pbrook5579c7f2009-04-11 14:47:08 +00003086 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
Jan Kiszka9a743e52009-11-30 18:21:21 +01003087 }
3088 if (qemu_file_has_error(f)) {
3089 return -EIO;
3090 }
aliguori475e4272008-10-06 20:21:51 +00003091 } while (!(flags & RAM_SAVE_FLAG_EOS));
3092
bellardc88676f2006-08-06 13:36:11 +00003093 return 0;
3094}
3095
aliguori9e472e12008-10-08 19:50:24 +00003096void qemu_service_io(void)
3097{
aliguorid9f75a42009-04-24 18:03:11 +00003098 qemu_notify_event();
aliguori9e472e12008-10-08 19:50:24 +00003099}
3100
bellard8a7ddc32004-03-31 19:00:16 +00003101/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00003102/* machine registration */
3103
blueswir1bdaf78e2008-10-04 07:24:27 +00003104static QEMUMachine *first_machine = NULL;
aliguori6f338c32009-02-11 15:21:54 +00003105QEMUMachine *current_machine = NULL;
bellardcc1daa42005-06-05 14:49:17 +00003106
3107int qemu_register_machine(QEMUMachine *m)
3108{
3109 QEMUMachine **pm;
3110 pm = &first_machine;
3111 while (*pm != NULL)
3112 pm = &(*pm)->next;
3113 m->next = NULL;
3114 *pm = m;
3115 return 0;
3116}
3117
pbrook9596ebb2007-11-18 01:44:38 +00003118static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00003119{
3120 QEMUMachine *m;
3121
3122 for(m = first_machine; m != NULL; m = m->next) {
3123 if (!strcmp(m->name, name))
3124 return m;
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01003125 if (m->alias && !strcmp(m->alias, name))
3126 return m;
bellardcc1daa42005-06-05 14:49:17 +00003127 }
3128 return NULL;
3129}
3130
Anthony Liguori0c257432009-05-21 20:41:01 -05003131static QEMUMachine *find_default_machine(void)
3132{
3133 QEMUMachine *m;
3134
3135 for(m = first_machine; m != NULL; m = m->next) {
3136 if (m->is_default) {
3137 return m;
3138 }
3139 }
3140 return NULL;
3141}
3142
bellardcc1daa42005-06-05 14:49:17 +00003143/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00003144/* main execution loop */
3145
pbrook9596ebb2007-11-18 01:44:38 +00003146static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00003147{
aliguori7d957bd2009-01-15 22:14:11 +00003148 uint64_t interval = GUI_REFRESH_INTERVAL;
ths740733b2007-06-08 01:57:56 +00003149 DisplayState *ds = opaque;
aliguori7d957bd2009-01-15 22:14:11 +00003150 DisplayChangeListener *dcl = ds->listeners;
3151
3152 dpy_refresh(ds);
3153
3154 while (dcl != NULL) {
3155 if (dcl->gui_timer_interval &&
3156 dcl->gui_timer_interval < interval)
3157 interval = dcl->gui_timer_interval;
3158 dcl = dcl->next;
3159 }
3160 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00003161}
3162
blueswir19043b622009-01-21 19:28:13 +00003163static void nographic_update(void *opaque)
3164{
3165 uint64_t interval = GUI_REFRESH_INTERVAL;
3166
3167 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
3168}
3169
bellard0bd48852005-11-11 00:00:47 +00003170struct vm_change_state_entry {
3171 VMChangeStateHandler *cb;
3172 void *opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003173 QLIST_ENTRY (vm_change_state_entry) entries;
bellard0bd48852005-11-11 00:00:47 +00003174};
3175
Blue Swirl72cf2d42009-09-12 07:36:22 +00003176static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
bellard0bd48852005-11-11 00:00:47 +00003177
3178VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
3179 void *opaque)
3180{
3181 VMChangeStateEntry *e;
3182
3183 e = qemu_mallocz(sizeof (*e));
bellard0bd48852005-11-11 00:00:47 +00003184
3185 e->cb = cb;
3186 e->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003187 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
bellard0bd48852005-11-11 00:00:47 +00003188 return e;
3189}
3190
3191void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
3192{
Blue Swirl72cf2d42009-09-12 07:36:22 +00003193 QLIST_REMOVE (e, entries);
bellard0bd48852005-11-11 00:00:47 +00003194 qemu_free (e);
3195}
3196
aliguori9781e042009-01-22 17:15:29 +00003197static void vm_state_notify(int running, int reason)
bellard0bd48852005-11-11 00:00:47 +00003198{
3199 VMChangeStateEntry *e;
3200
3201 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
aliguori9781e042009-01-22 17:15:29 +00003202 e->cb(e->opaque, running, reason);
bellard0bd48852005-11-11 00:00:47 +00003203 }
3204}
3205
aliguorid6dc3d42009-04-24 18:04:07 +00003206static void resume_all_vcpus(void);
3207static void pause_all_vcpus(void);
3208
bellard8a7ddc32004-03-31 19:00:16 +00003209void vm_start(void)
3210{
3211 if (!vm_running) {
3212 cpu_enable_ticks();
3213 vm_running = 1;
aliguori9781e042009-01-22 17:15:29 +00003214 vm_state_notify(1, 0);
thsefe75412007-08-24 01:36:32 +00003215 qemu_rearm_alarm_timer(alarm_timer);
aliguorid6dc3d42009-04-24 18:04:07 +00003216 resume_all_vcpus();
bellard8a7ddc32004-03-31 19:00:16 +00003217 }
3218}
3219
bellardbb0c6722004-06-20 12:37:32 +00003220/* reset/shutdown handler */
3221
3222typedef struct QEMUResetEntry {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003223 QTAILQ_ENTRY(QEMUResetEntry) entry;
bellardbb0c6722004-06-20 12:37:32 +00003224 QEMUResetHandler *func;
3225 void *opaque;
bellardbb0c6722004-06-20 12:37:32 +00003226} QEMUResetEntry;
3227
Blue Swirl72cf2d42009-09-12 07:36:22 +00003228static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
3229 QTAILQ_HEAD_INITIALIZER(reset_handlers);
bellardbb0c6722004-06-20 12:37:32 +00003230static int reset_requested;
3231static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00003232static int powerdown_requested;
aliguorie5689022009-04-24 18:03:54 +00003233static int debug_requested;
aliguori6e29f5d2009-04-24 18:04:02 +00003234static int vmstop_requested;
bellardbb0c6722004-06-20 12:37:32 +00003235
aurel32cf7a2fe2008-03-18 06:53:05 +00003236int qemu_shutdown_requested(void)
3237{
3238 int r = shutdown_requested;
3239 shutdown_requested = 0;
3240 return r;
3241}
3242
3243int qemu_reset_requested(void)
3244{
3245 int r = reset_requested;
3246 reset_requested = 0;
3247 return r;
3248}
3249
3250int qemu_powerdown_requested(void)
3251{
3252 int r = powerdown_requested;
3253 powerdown_requested = 0;
3254 return r;
3255}
3256
aliguorie5689022009-04-24 18:03:54 +00003257static int qemu_debug_requested(void)
3258{
3259 int r = debug_requested;
3260 debug_requested = 0;
3261 return r;
3262}
3263
aliguori6e29f5d2009-04-24 18:04:02 +00003264static int qemu_vmstop_requested(void)
3265{
3266 int r = vmstop_requested;
3267 vmstop_requested = 0;
3268 return r;
3269}
3270
3271static void do_vm_stop(int reason)
3272{
3273 if (vm_running) {
3274 cpu_disable_ticks();
3275 vm_running = 0;
aliguorid6dc3d42009-04-24 18:04:07 +00003276 pause_all_vcpus();
aliguori6e29f5d2009-04-24 18:04:02 +00003277 vm_state_notify(0, reason);
3278 }
3279}
3280
Jan Kiszkaa08d4362009-06-27 09:25:07 +02003281void qemu_register_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003282{
Jan Kiszka55ddfe82009-07-02 00:19:02 +02003283 QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
bellardbb0c6722004-06-20 12:37:32 +00003284
bellardbb0c6722004-06-20 12:37:32 +00003285 re->func = func;
3286 re->opaque = opaque;
Blue Swirl72cf2d42009-09-12 07:36:22 +00003287 QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
bellardbb0c6722004-06-20 12:37:32 +00003288}
3289
Jan Kiszkadda9b292009-07-02 00:19:02 +02003290void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
bellardbb0c6722004-06-20 12:37:32 +00003291{
3292 QEMUResetEntry *re;
3293
Blue Swirl72cf2d42009-09-12 07:36:22 +00003294 QTAILQ_FOREACH(re, &reset_handlers, entry) {
Jan Kiszkadda9b292009-07-02 00:19:02 +02003295 if (re->func == func && re->opaque == opaque) {
Blue Swirl72cf2d42009-09-12 07:36:22 +00003296 QTAILQ_REMOVE(&reset_handlers, re, entry);
Jan Kiszkadda9b292009-07-02 00:19:02 +02003297 qemu_free(re);
3298 return;
3299 }
3300 }
3301}
3302
3303void qemu_system_reset(void)
3304{
3305 QEMUResetEntry *re, *nre;
3306
3307 /* reset all devices */
Blue Swirl72cf2d42009-09-12 07:36:22 +00003308 QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
bellardbb0c6722004-06-20 12:37:32 +00003309 re->func(re->opaque);
3310 }
3311}
3312
3313void qemu_system_reset_request(void)
3314{
bellardd1beab82006-10-02 19:44:22 +00003315 if (no_reboot) {
3316 shutdown_requested = 1;
3317 } else {
3318 reset_requested = 1;
3319 }
aliguorid9f75a42009-04-24 18:03:11 +00003320 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003321}
3322
3323void qemu_system_shutdown_request(void)
3324{
3325 shutdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003326 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003327}
3328
bellard34751872005-07-02 14:31:34 +00003329void qemu_system_powerdown_request(void)
3330{
3331 powerdown_requested = 1;
aliguorid9f75a42009-04-24 18:03:11 +00003332 qemu_notify_event();
3333}
3334
aliguorid6dc3d42009-04-24 18:04:07 +00003335#ifdef CONFIG_IOTHREAD
3336static void qemu_system_vmstop_request(int reason)
aliguorid9f75a42009-04-24 18:03:11 +00003337{
aliguorid6dc3d42009-04-24 18:04:07 +00003338 vmstop_requested = reason;
3339 qemu_notify_event();
bellardbb0c6722004-06-20 12:37:32 +00003340}
aliguorid6dc3d42009-04-24 18:04:07 +00003341#endif
bellardbb0c6722004-06-20 12:37:32 +00003342
aliguori50317c72009-04-24 18:03:29 +00003343#ifndef _WIN32
3344static int io_thread_fd = -1;
3345
3346static void qemu_event_increment(void)
3347{
3348 static const char byte = 0;
3349
3350 if (io_thread_fd == -1)
3351 return;
3352
3353 write(io_thread_fd, &byte, sizeof(byte));
3354}
3355
3356static void qemu_event_read(void *opaque)
3357{
3358 int fd = (unsigned long)opaque;
3359 ssize_t len;
3360
3361 /* Drain the notify pipe */
3362 do {
3363 char buffer[512];
3364 len = read(fd, buffer, sizeof(buffer));
3365 } while ((len == -1 && errno == EINTR) || len > 0);
3366}
3367
3368static int qemu_event_init(void)
3369{
3370 int err;
3371 int fds[2];
3372
Kevin Wolf40ff6d72009-12-02 12:24:42 +01003373 err = qemu_pipe(fds);
aliguori50317c72009-04-24 18:03:29 +00003374 if (err == -1)
3375 return -errno;
3376
3377 err = fcntl_setfl(fds[0], O_NONBLOCK);
3378 if (err < 0)
3379 goto fail;
3380
3381 err = fcntl_setfl(fds[1], O_NONBLOCK);
3382 if (err < 0)
3383 goto fail;
3384
3385 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
3386 (void *)(unsigned long)fds[0]);
3387
3388 io_thread_fd = fds[1];
Jan Kiszkaa7e21212009-04-29 18:38:28 +00003389 return 0;
3390
aliguori50317c72009-04-24 18:03:29 +00003391fail:
3392 close(fds[0]);
3393 close(fds[1]);
3394 return err;
3395}
3396#else
3397HANDLE qemu_event_handle;
3398
3399static void dummy_event_handler(void *opaque)
3400{
3401}
3402
3403static int qemu_event_init(void)
3404{
3405 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
3406 if (!qemu_event_handle) {
Blue Swirl20889d42009-09-27 20:03:56 +00003407 fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError());
aliguori50317c72009-04-24 18:03:29 +00003408 return -1;
3409 }
3410 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
3411 return 0;
3412}
3413
3414static void qemu_event_increment(void)
3415{
malcde1c90c2009-09-27 14:38:18 +04003416 if (!SetEvent(qemu_event_handle)) {
Blue Swirl20889d42009-09-27 20:03:56 +00003417 fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n",
malcde1c90c2009-09-27 14:38:18 +04003418 GetLastError());
3419 exit (1);
3420 }
aliguori50317c72009-04-24 18:03:29 +00003421}
3422#endif
3423
aliguorid6dc3d42009-04-24 18:04:07 +00003424static int cpu_can_run(CPUState *env)
3425{
3426 if (env->stop)
3427 return 0;
3428 if (env->stopped)
3429 return 0;
3430 return 1;
3431}
3432
3433#ifndef CONFIG_IOTHREAD
aliguori3fcf7b62009-04-24 18:03:25 +00003434static int qemu_init_main_loop(void)
3435{
aliguori50317c72009-04-24 18:03:29 +00003436 return qemu_event_init();
aliguori3fcf7b62009-04-24 18:03:25 +00003437}
3438
aliguori0bf46a42009-04-24 18:03:41 +00003439void qemu_init_vcpu(void *_env)
3440{
3441 CPUState *env = _env;
3442
3443 if (kvm_enabled())
3444 kvm_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003445 env->nr_cores = smp_cores;
3446 env->nr_threads = smp_threads;
aliguori0bf46a42009-04-24 18:03:41 +00003447 return;
3448}
3449
aliguori8edac962009-04-24 18:03:45 +00003450int qemu_cpu_self(void *env)
3451{
3452 return 1;
3453}
3454
aliguorid6dc3d42009-04-24 18:04:07 +00003455static void resume_all_vcpus(void)
3456{
3457}
3458
3459static void pause_all_vcpus(void)
3460{
3461}
3462
aliguori8edac962009-04-24 18:03:45 +00003463void qemu_cpu_kick(void *env)
3464{
3465 return;
3466}
3467
aliguorid6dc3d42009-04-24 18:04:07 +00003468void qemu_notify_event(void)
3469{
3470 CPUState *env = cpu_single_env;
3471
3472 if (env) {
3473 cpu_exit(env);
Anthony Liguori4a1418e2009-08-10 17:07:24 -05003474 }
aliguorid6dc3d42009-04-24 18:04:07 +00003475}
3476
Glauber Costad549db52009-10-07 16:38:03 -03003477void qemu_mutex_lock_iothread(void) {}
3478void qemu_mutex_unlock_iothread(void) {}
aliguori48708522009-04-24 18:03:49 +00003479
aliguori6e29f5d2009-04-24 18:04:02 +00003480void vm_stop(int reason)
3481{
3482 do_vm_stop(reason);
3483}
3484
aliguorid6dc3d42009-04-24 18:04:07 +00003485#else /* CONFIG_IOTHREAD */
3486
3487#include "qemu-thread.h"
3488
3489QemuMutex qemu_global_mutex;
3490static QemuMutex qemu_fair_mutex;
3491
3492static QemuThread io_thread;
3493
3494static QemuThread *tcg_cpu_thread;
3495static QemuCond *tcg_halt_cond;
3496
3497static int qemu_system_ready;
3498/* cpu creation */
3499static QemuCond qemu_cpu_cond;
3500/* system init */
3501static QemuCond qemu_system_cond;
3502static QemuCond qemu_pause_cond;
3503
3504static void block_io_signals(void);
3505static void unblock_io_signals(void);
3506static int tcg_has_work(void);
3507
3508static int qemu_init_main_loop(void)
3509{
3510 int ret;
3511
3512 ret = qemu_event_init();
3513 if (ret)
3514 return ret;
3515
3516 qemu_cond_init(&qemu_pause_cond);
3517 qemu_mutex_init(&qemu_fair_mutex);
3518 qemu_mutex_init(&qemu_global_mutex);
3519 qemu_mutex_lock(&qemu_global_mutex);
3520
3521 unblock_io_signals();
3522 qemu_thread_self(&io_thread);
3523
3524 return 0;
3525}
3526
3527static void qemu_wait_io_event(CPUState *env)
3528{
3529 while (!tcg_has_work())
3530 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
3531
3532 qemu_mutex_unlock(&qemu_global_mutex);
3533
3534 /*
3535 * Users of qemu_global_mutex can be starved, having no chance
3536 * to acquire it since this path will get to it first.
3537 * So use another lock to provide fairness.
3538 */
3539 qemu_mutex_lock(&qemu_fair_mutex);
3540 qemu_mutex_unlock(&qemu_fair_mutex);
3541
3542 qemu_mutex_lock(&qemu_global_mutex);
3543 if (env->stop) {
3544 env->stop = 0;
3545 env->stopped = 1;
3546 qemu_cond_signal(&qemu_pause_cond);
3547 }
3548}
3549
3550static int qemu_cpu_exec(CPUState *env);
3551
3552static void *kvm_cpu_thread_fn(void *arg)
3553{
3554 CPUState *env = arg;
3555
3556 block_io_signals();
3557 qemu_thread_self(env->thread);
Jean-Christophe DUBOIS321c1cb2009-09-02 23:59:04 +02003558 if (kvm_enabled())
3559 kvm_init_vcpu(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003560
3561 /* signal CPU creation */
3562 qemu_mutex_lock(&qemu_global_mutex);
3563 env->created = 1;
3564 qemu_cond_signal(&qemu_cpu_cond);
3565
3566 /* and wait for machine initialization */
3567 while (!qemu_system_ready)
3568 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3569
3570 while (1) {
3571 if (cpu_can_run(env))
3572 qemu_cpu_exec(env);
Anthony Liguori1c3173b2009-09-10 08:45:43 -05003573 qemu_wait_io_event(env);
aliguorid6dc3d42009-04-24 18:04:07 +00003574 }
3575
3576 return NULL;
3577}
3578
3579static void tcg_cpu_exec(void);
3580
3581static void *tcg_cpu_thread_fn(void *arg)
3582{
3583 CPUState *env = arg;
3584
3585 block_io_signals();
3586 qemu_thread_self(env->thread);
3587
3588 /* signal CPU creation */
3589 qemu_mutex_lock(&qemu_global_mutex);
3590 for (env = first_cpu; env != NULL; env = env->next_cpu)
3591 env->created = 1;
3592 qemu_cond_signal(&qemu_cpu_cond);
3593
3594 /* and wait for machine initialization */
3595 while (!qemu_system_ready)
3596 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
3597
3598 while (1) {
3599 tcg_cpu_exec();
3600 qemu_wait_io_event(cur_cpu);
3601 }
3602
3603 return NULL;
3604}
3605
3606void qemu_cpu_kick(void *_env)
3607{
3608 CPUState *env = _env;
3609 qemu_cond_broadcast(env->halt_cond);
3610 if (kvm_enabled())
3611 qemu_thread_signal(env->thread, SIGUSR1);
3612}
3613
Glauber Costae5bc2012009-09-28 15:27:44 -03003614int qemu_cpu_self(void *_env)
aliguorid6dc3d42009-04-24 18:04:07 +00003615{
Glauber Costae5bc2012009-09-28 15:27:44 -03003616 CPUState *env = _env;
3617 QemuThread this;
3618
3619 qemu_thread_self(&this);
3620
3621 return qemu_thread_equal(&this, env->thread);
aliguorid6dc3d42009-04-24 18:04:07 +00003622}
3623
3624static void cpu_signal(int sig)
3625{
3626 if (cpu_single_env)
3627 cpu_exit(cpu_single_env);
3628}
3629
3630static void block_io_signals(void)
3631{
3632 sigset_t set;
3633 struct sigaction sigact;
3634
3635 sigemptyset(&set);
3636 sigaddset(&set, SIGUSR2);
3637 sigaddset(&set, SIGIO);
3638 sigaddset(&set, SIGALRM);
3639 pthread_sigmask(SIG_BLOCK, &set, NULL);
3640
3641 sigemptyset(&set);
3642 sigaddset(&set, SIGUSR1);
3643 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3644
3645 memset(&sigact, 0, sizeof(sigact));
3646 sigact.sa_handler = cpu_signal;
3647 sigaction(SIGUSR1, &sigact, NULL);
3648}
3649
3650static void unblock_io_signals(void)
3651{
3652 sigset_t set;
3653
3654 sigemptyset(&set);
3655 sigaddset(&set, SIGUSR2);
3656 sigaddset(&set, SIGIO);
3657 sigaddset(&set, SIGALRM);
3658 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3659
3660 sigemptyset(&set);
3661 sigaddset(&set, SIGUSR1);
3662 pthread_sigmask(SIG_BLOCK, &set, NULL);
3663}
3664
3665static void qemu_signal_lock(unsigned int msecs)
3666{
3667 qemu_mutex_lock(&qemu_fair_mutex);
3668
3669 while (qemu_mutex_trylock(&qemu_global_mutex)) {
3670 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
3671 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
3672 break;
3673 }
3674 qemu_mutex_unlock(&qemu_fair_mutex);
3675}
3676
Glauber Costad549db52009-10-07 16:38:03 -03003677void qemu_mutex_lock_iothread(void)
aliguorid6dc3d42009-04-24 18:04:07 +00003678{
3679 if (kvm_enabled()) {
3680 qemu_mutex_lock(&qemu_fair_mutex);
3681 qemu_mutex_lock(&qemu_global_mutex);
3682 qemu_mutex_unlock(&qemu_fair_mutex);
3683 } else
3684 qemu_signal_lock(100);
3685}
3686
Glauber Costad549db52009-10-07 16:38:03 -03003687void qemu_mutex_unlock_iothread(void)
aliguorid6dc3d42009-04-24 18:04:07 +00003688{
3689 qemu_mutex_unlock(&qemu_global_mutex);
3690}
3691
3692static int all_vcpus_paused(void)
3693{
3694 CPUState *penv = first_cpu;
3695
3696 while (penv) {
3697 if (!penv->stopped)
3698 return 0;
3699 penv = (CPUState *)penv->next_cpu;
3700 }
3701
3702 return 1;
3703}
3704
3705static void pause_all_vcpus(void)
3706{
3707 CPUState *penv = first_cpu;
3708
3709 while (penv) {
3710 penv->stop = 1;
3711 qemu_thread_signal(penv->thread, SIGUSR1);
3712 qemu_cpu_kick(penv);
3713 penv = (CPUState *)penv->next_cpu;
3714 }
3715
3716 while (!all_vcpus_paused()) {
3717 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
3718 penv = first_cpu;
3719 while (penv) {
3720 qemu_thread_signal(penv->thread, SIGUSR1);
3721 penv = (CPUState *)penv->next_cpu;
3722 }
3723 }
3724}
3725
3726static void resume_all_vcpus(void)
3727{
3728 CPUState *penv = first_cpu;
3729
3730 while (penv) {
3731 penv->stop = 0;
3732 penv->stopped = 0;
3733 qemu_thread_signal(penv->thread, SIGUSR1);
3734 qemu_cpu_kick(penv);
3735 penv = (CPUState *)penv->next_cpu;
3736 }
3737}
3738
3739static void tcg_init_vcpu(void *_env)
3740{
3741 CPUState *env = _env;
3742 /* share a single thread for all cpus with TCG */
3743 if (!tcg_cpu_thread) {
3744 env->thread = qemu_mallocz(sizeof(QemuThread));
3745 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3746 qemu_cond_init(env->halt_cond);
3747 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
3748 while (env->created == 0)
3749 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3750 tcg_cpu_thread = env->thread;
3751 tcg_halt_cond = env->halt_cond;
3752 } else {
3753 env->thread = tcg_cpu_thread;
3754 env->halt_cond = tcg_halt_cond;
3755 }
3756}
3757
3758static void kvm_start_vcpu(CPUState *env)
3759{
aliguorid6dc3d42009-04-24 18:04:07 +00003760 env->thread = qemu_mallocz(sizeof(QemuThread));
3761 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3762 qemu_cond_init(env->halt_cond);
3763 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
3764 while (env->created == 0)
3765 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3766}
3767
3768void qemu_init_vcpu(void *_env)
3769{
3770 CPUState *env = _env;
3771
3772 if (kvm_enabled())
3773 kvm_start_vcpu(env);
3774 else
3775 tcg_init_vcpu(env);
Andre Przywaradc6b1c02009-08-19 15:42:40 +02003776 env->nr_cores = smp_cores;
3777 env->nr_threads = smp_threads;
aliguorid6dc3d42009-04-24 18:04:07 +00003778}
3779
3780void qemu_notify_event(void)
3781{
3782 qemu_event_increment();
3783}
3784
3785void vm_stop(int reason)
3786{
3787 QemuThread me;
3788 qemu_thread_self(&me);
3789
3790 if (!qemu_thread_equal(&me, &io_thread)) {
3791 qemu_system_vmstop_request(reason);
3792 /*
3793 * FIXME: should not return to device code in case
3794 * vm_stop() has been requested.
3795 */
3796 if (cpu_single_env) {
3797 cpu_exit(cpu_single_env);
3798 cpu_single_env->stop = 1;
3799 }
3800 return;
3801 }
3802 do_vm_stop(reason);
3803}
3804
3805#endif
3806
3807
ths877cf882007-04-18 18:11:47 +00003808#ifdef _WIN32
blueswir169d64512008-12-07 19:30:18 +00003809static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003810{
3811 int ret, ret2, i;
bellardf3311102006-04-12 20:21:17 +00003812 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00003813
bellardf3311102006-04-12 20:21:17 +00003814
3815 /* XXX: need to suppress polling by better using win32 events */
3816 ret = 0;
3817 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
3818 ret |= pe->func(pe->opaque);
3819 }
thse6b1e552007-04-18 17:56:02 +00003820 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00003821 int err;
3822 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00003823
aliguori56f3a5d2008-10-31 18:07:17 +00003824 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
bellarda18e5242006-06-25 17:18:27 +00003825 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
3826 if (w->func[ret - WAIT_OBJECT_0])
3827 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00003828
ths5fafdf22007-09-16 21:08:06 +00003829 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00003830 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00003831
thse6b1e552007-04-18 17:56:02 +00003832 /* Check if event is signaled */
3833 ret2 = WaitForSingleObject(w->events[i], 0);
3834 if(ret2 == WAIT_OBJECT_0) {
3835 if (w->func[i])
3836 w->func[i](w->opaque[i]);
3837 } else if (ret2 == WAIT_TIMEOUT) {
3838 } else {
3839 err = GetLastError();
3840 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00003841 }
3842 }
bellarda18e5242006-06-25 17:18:27 +00003843 } else if (ret == WAIT_TIMEOUT) {
3844 } else {
3845 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00003846 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00003847 }
bellardf3311102006-04-12 20:21:17 +00003848 }
aliguori56f3a5d2008-10-31 18:07:17 +00003849
3850 *timeout = 0;
3851}
3852#else
blueswir169d64512008-12-07 19:30:18 +00003853static void host_main_loop_wait(int *timeout)
aliguori56f3a5d2008-10-31 18:07:17 +00003854{
3855}
bellardfd1dff42006-02-01 21:29:26 +00003856#endif
aliguori56f3a5d2008-10-31 18:07:17 +00003857
3858void main_loop_wait(int timeout)
3859{
3860 IOHandlerRecord *ioh;
3861 fd_set rfds, wfds, xfds;
3862 int ret, nfds;
3863 struct timeval tv;
3864
3865 qemu_bh_update_timeout(&timeout);
3866
3867 host_main_loop_wait(&timeout);
3868
bellardfd1dff42006-02-01 21:29:26 +00003869 /* poll any events */
3870 /* XXX: separate device handlers from system ones */
aliguori6abfbd72008-11-05 20:49:37 +00003871 nfds = -1;
bellardfd1dff42006-02-01 21:29:26 +00003872 FD_ZERO(&rfds);
3873 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00003874 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00003875 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00003876 if (ioh->deleted)
3877 continue;
bellardfd1dff42006-02-01 21:29:26 +00003878 if (ioh->fd_read &&
3879 (!ioh->fd_read_poll ||
3880 ioh->fd_read_poll(ioh->opaque) != 0)) {
3881 FD_SET(ioh->fd, &rfds);
3882 if (ioh->fd > nfds)
3883 nfds = ioh->fd;
3884 }
3885 if (ioh->fd_write) {
3886 FD_SET(ioh->fd, &wfds);
3887 if (ioh->fd > nfds)
3888 nfds = ioh->fd;
3889 }
3890 }
ths3b46e622007-09-17 08:09:54 +00003891
aliguori56f3a5d2008-10-31 18:07:17 +00003892 tv.tv_sec = timeout / 1000;
3893 tv.tv_usec = (timeout % 1000) * 1000;
3894
Jan Kiszkad918f232009-06-24 14:42:30 +02003895 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
3896
aliguori48708522009-04-24 18:03:49 +00003897 qemu_mutex_unlock_iothread();
bellarde0356492006-05-01 13:33:02 +00003898 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
aliguori48708522009-04-24 18:03:49 +00003899 qemu_mutex_lock_iothread();
bellardfd1dff42006-02-01 21:29:26 +00003900 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00003901 IOHandlerRecord **pioh;
3902
3903 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00003904 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003905 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00003906 }
ths6ab43fd2007-08-25 01:34:19 +00003907 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003908 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00003909 }
3910 }
thscafffd42007-02-28 21:59:44 +00003911
3912 /* remove deleted IO handlers */
3913 pioh = &first_io_handler;
3914 while (*pioh) {
3915 ioh = *pioh;
3916 if (ioh->deleted) {
3917 *pioh = ioh->next;
3918 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00003919 } else
thscafffd42007-02-28 21:59:44 +00003920 pioh = &ioh->next;
3921 }
bellardfd1dff42006-02-01 21:29:26 +00003922 }
Jan Kiszkad918f232009-06-24 14:42:30 +02003923
3924 slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
bellardc20709a2004-04-21 23:27:19 +00003925
aliguori50317c72009-04-24 18:03:29 +00003926 /* rearm timer, if not periodic */
3927 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
3928 alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
3929 qemu_rearm_alarm_timer(alarm_timer);
3930 }
3931
aliguori357c6922008-11-25 17:26:09 +00003932 /* vm time timers */
aliguorid6dc3d42009-04-24 18:04:07 +00003933 if (vm_running) {
3934 if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
Jan Kiszka0fdddf82009-09-15 13:36:04 +02003935 qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
3936 qemu_get_clock(vm_clock));
aliguorid6dc3d42009-04-24 18:04:07 +00003937 }
aliguori357c6922008-11-25 17:26:09 +00003938
3939 /* real time timers */
Jan Kiszka0fdddf82009-09-15 13:36:04 +02003940 qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
aliguori357c6922008-11-25 17:26:09 +00003941 qemu_get_clock(rt_clock));
3942
Jan Kiszka21d5d122009-09-15 13:36:04 +02003943 qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
3944 qemu_get_clock(host_clock));
3945
pbrook423f0742007-05-23 00:06:54 +00003946 /* Check bottom-halves last in case any of the earlier events triggered
3947 them. */
3948 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00003949
bellard5905b2e2004-08-01 21:53:26 +00003950}
3951
aliguori43b96852009-04-24 18:03:33 +00003952static int qemu_cpu_exec(CPUState *env)
bellard5905b2e2004-08-01 21:53:26 +00003953{
aliguori43b96852009-04-24 18:03:33 +00003954 int ret;
bellard89bfc102006-02-08 22:46:31 +00003955#ifdef CONFIG_PROFILER
3956 int64_t ti;
3957#endif
aliguori43b96852009-04-24 18:03:33 +00003958
3959#ifdef CONFIG_PROFILER
3960 ti = profile_getclock();
3961#endif
3962 if (use_icount) {
3963 int64_t count;
3964 int decr;
3965 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3966 env->icount_decr.u16.low = 0;
3967 env->icount_extra = 0;
3968 count = qemu_next_deadline();
3969 count = (count + (1 << icount_time_shift) - 1)
3970 >> icount_time_shift;
3971 qemu_icount += count;
3972 decr = (count > 0xffff) ? 0xffff : count;
3973 count -= decr;
3974 env->icount_decr.u16.low = decr;
3975 env->icount_extra = count;
3976 }
3977 ret = cpu_exec(env);
3978#ifdef CONFIG_PROFILER
3979 qemu_time += profile_getclock() - ti;
3980#endif
3981 if (use_icount) {
3982 /* Fold pending instructions back into the
3983 instruction counter, and clear the interrupt flag. */
3984 qemu_icount -= (env->icount_decr.u16.low
3985 + env->icount_extra);
3986 env->icount_decr.u32 = 0;
3987 env->icount_extra = 0;
3988 }
3989 return ret;
3990}
3991
aliguorie6e35b12009-04-24 18:03:57 +00003992static void tcg_cpu_exec(void)
3993{
aliguorid6dc3d42009-04-24 18:04:07 +00003994 int ret = 0;
aliguorie6e35b12009-04-24 18:03:57 +00003995
3996 if (next_cpu == NULL)
3997 next_cpu = first_cpu;
3998 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
3999 CPUState *env = cur_cpu = next_cpu;
4000
4001 if (!vm_running)
4002 break;
4003 if (timer_alarm_pending) {
4004 timer_alarm_pending = 0;
4005 break;
4006 }
aliguorid6dc3d42009-04-24 18:04:07 +00004007 if (cpu_can_run(env))
4008 ret = qemu_cpu_exec(env);
aliguorie6e35b12009-04-24 18:03:57 +00004009 if (ret == EXCP_DEBUG) {
4010 gdb_set_stop_cpu(env);
4011 debug_requested = 1;
4012 break;
4013 }
4014 }
4015}
4016
aliguori43b96852009-04-24 18:03:33 +00004017static int cpu_has_work(CPUState *env)
4018{
aliguorid6dc3d42009-04-24 18:04:07 +00004019 if (env->stop)
4020 return 1;
4021 if (env->stopped)
4022 return 0;
aliguori43b96852009-04-24 18:03:33 +00004023 if (!env->halted)
4024 return 1;
4025 if (qemu_cpu_has_work(env))
4026 return 1;
4027 return 0;
4028}
4029
4030static int tcg_has_work(void)
4031{
bellard6a00d602005-11-21 23:25:50 +00004032 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00004033
aliguori43b96852009-04-24 18:03:33 +00004034 for (env = first_cpu; env != NULL; env = env->next_cpu)
4035 if (cpu_has_work(env))
4036 return 1;
4037 return 0;
4038}
bellard15a76442005-11-23 21:01:03 +00004039
aliguori43b96852009-04-24 18:03:33 +00004040static int qemu_calculate_timeout(void)
4041{
Luiz Capitulinob3198202009-06-09 18:24:57 -03004042#ifndef CONFIG_IOTHREAD
aliguori43b96852009-04-24 18:03:33 +00004043 int timeout;
bellard15a76442005-11-23 21:01:03 +00004044
aliguori43b96852009-04-24 18:03:33 +00004045 if (!vm_running)
4046 timeout = 5000;
4047 else if (tcg_has_work())
4048 timeout = 0;
4049 else if (!use_icount)
4050 timeout = 5000;
4051 else {
4052 /* XXX: use timeout computed from timers */
4053 int64_t add;
4054 int64_t delta;
4055 /* Advance virtual time to the next event. */
4056 if (use_icount == 1) {
4057 /* When not using an adaptive execution frequency
4058 we tend to get badly out of sync with real time,
4059 so just delay for a reasonable amount of time. */
4060 delta = 0;
bellard5905b2e2004-08-01 21:53:26 +00004061 } else {
aliguori43b96852009-04-24 18:03:33 +00004062 delta = cpu_get_icount() - cpu_get_clock();
bellard5905b2e2004-08-01 21:53:26 +00004063 }
aliguori43b96852009-04-24 18:03:33 +00004064 if (delta > 0) {
4065 /* If virtual time is ahead of real time then just
4066 wait for IO. */
4067 timeout = (delta / 1000000) + 1;
4068 } else {
4069 /* Wait for either IO to occur or the next
4070 timer event. */
4071 add = qemu_next_deadline();
4072 /* We advance the timer before checking for IO.
4073 Limit the amount we advance so that early IO
4074 activity won't get the guest too far ahead. */
4075 if (add > 10000000)
4076 add = 10000000;
4077 delta += add;
4078 add = (add + (1 << icount_time_shift) - 1)
4079 >> icount_time_shift;
4080 qemu_icount += add;
4081 timeout = delta / 1000000;
4082 if (timeout < 0)
4083 timeout = 0;
4084 }
bellardb4608c02003-06-27 17:34:32 +00004085 }
aliguori43b96852009-04-24 18:03:33 +00004086
4087 return timeout;
Luiz Capitulinob3198202009-06-09 18:24:57 -03004088#else /* CONFIG_IOTHREAD */
4089 return 1000;
4090#endif
aliguori43b96852009-04-24 18:03:33 +00004091}
4092
4093static int vm_can_run(void)
4094{
4095 if (powerdown_requested)
4096 return 0;
4097 if (reset_requested)
4098 return 0;
4099 if (shutdown_requested)
4100 return 0;
aliguorie5689022009-04-24 18:03:54 +00004101 if (debug_requested)
4102 return 0;
aliguori43b96852009-04-24 18:03:33 +00004103 return 1;
4104}
4105
Blue Swirld9c32312009-08-09 08:42:19 +00004106qemu_irq qemu_system_powerdown;
4107
aliguori43b96852009-04-24 18:03:33 +00004108static void main_loop(void)
4109{
aliguori6e29f5d2009-04-24 18:04:02 +00004110 int r;
aliguori43b96852009-04-24 18:03:33 +00004111
aliguorid6dc3d42009-04-24 18:04:07 +00004112#ifdef CONFIG_IOTHREAD
4113 qemu_system_ready = 1;
4114 qemu_cond_broadcast(&qemu_system_cond);
4115#endif
4116
aliguori6e29f5d2009-04-24 18:04:02 +00004117 for (;;) {
aliguorie6e35b12009-04-24 18:03:57 +00004118 do {
4119#ifdef CONFIG_PROFILER
4120 int64_t ti;
4121#endif
aliguorid6dc3d42009-04-24 18:04:07 +00004122#ifndef CONFIG_IOTHREAD
aliguorie6e35b12009-04-24 18:03:57 +00004123 tcg_cpu_exec();
aliguorid6dc3d42009-04-24 18:04:07 +00004124#endif
aliguori43b96852009-04-24 18:03:33 +00004125#ifdef CONFIG_PROFILER
4126 ti = profile_getclock();
4127#endif
4128 main_loop_wait(qemu_calculate_timeout());
4129#ifdef CONFIG_PROFILER
4130 dev_time += profile_getclock() - ti;
4131#endif
aliguorie5689022009-04-24 18:03:54 +00004132 } while (vm_can_run());
aliguori43b96852009-04-24 18:03:33 +00004133
Luiz Capitulinob1a15e72009-11-26 22:59:04 -02004134 if (qemu_debug_requested()) {
Blue Swirl242cd002009-12-04 18:05:45 +00004135 monitor_protocol_event(QEVENT_DEBUG, NULL);
aliguori43b96852009-04-24 18:03:33 +00004136 vm_stop(EXCP_DEBUG);
Luiz Capitulinob1a15e72009-11-26 22:59:04 -02004137 }
aliguori43b96852009-04-24 18:03:33 +00004138 if (qemu_shutdown_requested()) {
Blue Swirl242cd002009-12-04 18:05:45 +00004139 monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
aliguori43b96852009-04-24 18:03:33 +00004140 if (no_shutdown) {
4141 vm_stop(0);
4142 no_shutdown = 0;
4143 } else
4144 break;
4145 }
aliguorid6dc3d42009-04-24 18:04:07 +00004146 if (qemu_reset_requested()) {
Blue Swirl242cd002009-12-04 18:05:45 +00004147 monitor_protocol_event(QEVENT_RESET, NULL);
aliguorid6dc3d42009-04-24 18:04:07 +00004148 pause_all_vcpus();
aliguori43b96852009-04-24 18:03:33 +00004149 qemu_system_reset();
aliguorid6dc3d42009-04-24 18:04:07 +00004150 resume_all_vcpus();
4151 }
Blue Swirld9c32312009-08-09 08:42:19 +00004152 if (qemu_powerdown_requested()) {
Blue Swirl242cd002009-12-04 18:05:45 +00004153 monitor_protocol_event(QEVENT_POWERDOWN, NULL);
Blue Swirld9c32312009-08-09 08:42:19 +00004154 qemu_irq_raise(qemu_system_powerdown);
4155 }
Luiz Capitulinob1a15e72009-11-26 22:59:04 -02004156 if ((r = qemu_vmstop_requested())) {
Blue Swirl242cd002009-12-04 18:05:45 +00004157 monitor_protocol_event(QEVENT_STOP, NULL);
aliguori6e29f5d2009-04-24 18:04:02 +00004158 vm_stop(r);
Luiz Capitulinob1a15e72009-11-26 22:59:04 -02004159 }
aliguori43b96852009-04-24 18:03:33 +00004160 }
aliguorid6dc3d42009-04-24 18:04:07 +00004161 pause_all_vcpus();
bellardb4608c02003-06-27 17:34:32 +00004162}
4163
pbrook9bd7e6d2009-04-07 22:58:45 +00004164static void version(void)
4165{
pbrook4a19f1e2009-04-07 23:17:49 +00004166 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
pbrook9bd7e6d2009-04-07 22:58:45 +00004167}
4168
ths15f82202007-06-29 23:26:08 +00004169static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00004170{
pbrook9bd7e6d2009-04-07 22:58:45 +00004171 version();
4172 printf("usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00004173 "\n"
bellarda20dd502003-09-30 21:07:02 +00004174 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00004175 "\n"
blueswir15824d652009-03-28 06:44:27 +00004176#define DEF(option, opt_arg, opt_enum, opt_help) \
4177 opt_help
4178#define DEFHEADING(text) stringify(text) "\n"
4179#include "qemu-options.h"
4180#undef DEF
4181#undef DEFHEADING
4182#undef GEN_DOCS
bellard0824d6f2003-06-24 13:42:40 +00004183 "\n"
bellard82c643f2004-07-14 17:28:13 +00004184 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00004185 "ctrl-alt-f toggle full screen\n"
4186 "ctrl-alt-n switch to virtual console 'n'\n"
4187 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00004188 "\n"
4189 "When using -nographic, press 'ctrl-a h' to get some help.\n"
4190 ,
bellard0db63472003-10-27 21:37:46 +00004191 "qemu",
bellarda00bad72004-05-22 21:39:06 +00004192 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00004193#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00004194 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00004195 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00004196#endif
bellard6e44ba72004-01-18 21:56:49 +00004197 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00004198 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00004199 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00004200}
4201
bellardcd6f1162004-05-13 22:02:20 +00004202#define HAS_ARG 0x0001
4203
4204enum {
blueswir15824d652009-03-28 06:44:27 +00004205#define DEF(option, opt_arg, opt_enum, opt_help) \
4206 opt_enum,
4207#define DEFHEADING(text)
4208#include "qemu-options.h"
4209#undef DEF
4210#undef DEFHEADING
4211#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004212};
4213
4214typedef struct QEMUOption {
4215 const char *name;
4216 int flags;
4217 int index;
4218} QEMUOption;
4219
blueswir1dbed7e42008-10-01 19:38:09 +00004220static const QEMUOption qemu_options[] = {
bellardcd6f1162004-05-13 22:02:20 +00004221 { "h", 0, QEMU_OPTION_h },
blueswir15824d652009-03-28 06:44:27 +00004222#define DEF(option, opt_arg, opt_enum, opt_help) \
4223 { option, opt_arg, opt_enum },
4224#define DEFHEADING(text)
4225#include "qemu-options.h"
4226#undef DEF
4227#undef DEFHEADING
4228#undef GEN_DOCS
bellardcd6f1162004-05-13 22:02:20 +00004229 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00004230};
4231
bellard1d14ffa2005-10-30 18:58:22 +00004232#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00004233struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00004234#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00004235#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00004236 {
4237 "pcspk",
4238 "PC speaker",
4239 0,
4240 1,
4241 { .init_isa = pcspk_audio_init }
4242 },
4243#endif
malc4c9b53e2009-01-09 10:46:34 +00004244
4245#ifdef CONFIG_SB16
bellard6a36d842005-12-18 20:34:32 +00004246 {
4247 "sb16",
4248 "Creative Sound Blaster 16",
4249 0,
4250 1,
4251 { .init_isa = SB16_init }
4252 },
malc4c9b53e2009-01-09 10:46:34 +00004253#endif
bellard6a36d842005-12-18 20:34:32 +00004254
malccc53d262008-06-13 10:48:22 +00004255#ifdef CONFIG_CS4231A
4256 {
4257 "cs4231a",
4258 "CS4231A",
4259 0,
4260 1,
4261 { .init_isa = cs4231a_init }
4262 },
4263#endif
4264
bellard6a36d842005-12-18 20:34:32 +00004265#ifdef CONFIG_ADLIB
4266 {
4267 "adlib",
4268#ifdef HAS_YMF262
4269 "Yamaha YMF262 (OPL3)",
4270#else
4271 "Yamaha YM3812 (OPL2)",
4272#endif
4273 0,
4274 1,
4275 { .init_isa = Adlib_init }
4276 },
4277#endif
4278
4279#ifdef CONFIG_GUS
4280 {
4281 "gus",
4282 "Gravis Ultrasound GF1",
4283 0,
4284 1,
4285 { .init_isa = GUS_init }
4286 },
4287#endif
4288
malc4c9b53e2009-01-09 10:46:34 +00004289#ifdef CONFIG_AC97
balroge5c9a132008-01-14 04:27:55 +00004290 {
4291 "ac97",
4292 "Intel 82801AA AC97 Audio",
4293 0,
4294 0,
4295 { .init_pci = ac97_init }
4296 },
malc4c9b53e2009-01-09 10:46:34 +00004297#endif
balroge5c9a132008-01-14 04:27:55 +00004298
malc4c9b53e2009-01-09 10:46:34 +00004299#ifdef CONFIG_ES1370
bellard6a36d842005-12-18 20:34:32 +00004300 {
4301 "es1370",
4302 "ENSONIQ AudioPCI ES1370",
4303 0,
4304 0,
4305 { .init_pci = es1370_init }
4306 },
balrogb00052e2007-04-30 02:22:06 +00004307#endif
bellard6a36d842005-12-18 20:34:32 +00004308
malc4c9b53e2009-01-09 10:46:34 +00004309#endif /* HAS_AUDIO_CHOICE */
4310
bellard6a36d842005-12-18 20:34:32 +00004311 { NULL, NULL, 0, 0, { NULL } }
4312};
4313
bellard1d14ffa2005-10-30 18:58:22 +00004314static void select_soundhw (const char *optarg)
4315{
bellard6a36d842005-12-18 20:34:32 +00004316 struct soundhw *c;
4317
bellard1d14ffa2005-10-30 18:58:22 +00004318 if (*optarg == '?') {
4319 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00004320
bellard1d14ffa2005-10-30 18:58:22 +00004321 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00004322 for (c = soundhw; c->name; ++c) {
4323 printf ("%-11s %s\n", c->name, c->descr);
4324 }
4325 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00004326 exit (*optarg != '?');
4327 }
4328 else {
bellard6a36d842005-12-18 20:34:32 +00004329 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00004330 const char *p;
4331 char *e;
4332 int bad_card = 0;
4333
bellard6a36d842005-12-18 20:34:32 +00004334 if (!strcmp (optarg, "all")) {
4335 for (c = soundhw; c->name; ++c) {
4336 c->enabled = 1;
4337 }
4338 return;
4339 }
bellard1d14ffa2005-10-30 18:58:22 +00004340
bellard6a36d842005-12-18 20:34:32 +00004341 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00004342 while (*p) {
4343 e = strchr (p, ',');
4344 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00004345
4346 for (c = soundhw; c->name; ++c) {
malcb3d6fb42009-09-06 06:49:03 +04004347 if (!strncmp (c->name, p, l) && !c->name[l]) {
bellard6a36d842005-12-18 20:34:32 +00004348 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00004349 break;
4350 }
4351 }
bellard6a36d842005-12-18 20:34:32 +00004352
4353 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00004354 if (l > 80) {
4355 fprintf (stderr,
4356 "Unknown sound card name (too big to show)\n");
4357 }
4358 else {
4359 fprintf (stderr, "Unknown sound card name `%.*s'\n",
4360 (int) l, p);
4361 }
4362 bad_card = 1;
4363 }
4364 p += l + (e != NULL);
4365 }
4366
4367 if (bad_card)
4368 goto show_valid_cards;
4369 }
4370}
4371#endif
4372
malc3893c122008-09-28 00:42:05 +00004373static void select_vgahw (const char *p)
4374{
4375 const char *opts;
4376
Gerd Hoffmann64465292009-12-08 13:11:45 +01004377 default_vga = 0;
Zachary Amsden86176752009-07-30 00:15:02 -10004378 vga_interface_type = VGA_NONE;
malc3893c122008-09-28 00:42:05 +00004379 if (strstart(p, "std", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004380 vga_interface_type = VGA_STD;
malc3893c122008-09-28 00:42:05 +00004381 } else if (strstart(p, "cirrus", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004382 vga_interface_type = VGA_CIRRUS;
malc3893c122008-09-28 00:42:05 +00004383 } else if (strstart(p, "vmware", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004384 vga_interface_type = VGA_VMWARE;
aliguori94909d92009-04-22 15:19:53 +00004385 } else if (strstart(p, "xenfb", &opts)) {
Zachary Amsden86176752009-07-30 00:15:02 -10004386 vga_interface_type = VGA_XENFB;
aliguori28b85ed2009-04-22 15:19:48 +00004387 } else if (!strstart(p, "none", &opts)) {
malc3893c122008-09-28 00:42:05 +00004388 invalid_vga:
4389 fprintf(stderr, "Unknown vga type: %s\n", p);
4390 exit(1);
4391 }
malccb5a7aa2008-09-28 00:42:12 +00004392 while (*opts) {
4393 const char *nextopt;
4394
4395 if (strstart(opts, ",retrace=", &nextopt)) {
4396 opts = nextopt;
4397 if (strstart(opts, "dumb", &nextopt))
4398 vga_retrace_method = VGA_RETRACE_DUMB;
4399 else if (strstart(opts, "precise", &nextopt))
4400 vga_retrace_method = VGA_RETRACE_PRECISE;
4401 else goto invalid_vga;
4402 } else goto invalid_vga;
4403 opts = nextopt;
4404 }
malc3893c122008-09-28 00:42:05 +00004405}
4406
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004407#ifdef TARGET_I386
4408static int balloon_parse(const char *arg)
4409{
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004410 QemuOpts *opts;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004411
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004412 if (strcmp(arg, "none") == 0) {
4413 return 0;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004414 }
Gerd Hoffmann382f0742009-08-14 10:34:22 +02004415
4416 if (!strncmp(arg, "virtio", 6)) {
4417 if (arg[6] == ',') {
4418 /* have params -> parse them */
4419 opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL);
4420 if (!opts)
4421 return -1;
4422 } else {
4423 /* create empty opts */
4424 opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
4425 }
4426 qemu_opt_set(opts, "driver", "virtio-balloon-pci");
4427 return 0;
4428 }
4429
4430 return -1;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02004431}
4432#endif
4433
bellard3587d7e2006-06-26 20:03:44 +00004434#ifdef _WIN32
4435static BOOL WINAPI qemu_ctrl_handler(DWORD type)
4436{
4437 exit(STATUS_CONTROL_C_EXIT);
4438 return TRUE;
4439}
4440#endif
4441
aliguoric4be29f2009-04-17 18:58:14 +00004442int qemu_uuid_parse(const char *str, uint8_t *uuid)
blueswir18fcb1b92008-09-18 18:29:08 +00004443{
4444 int ret;
4445
4446 if(strlen(str) != 36)
4447 return -1;
4448
4449 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
4450 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
4451 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
4452
4453 if(ret != 16)
4454 return -1;
4455
aliguorib6f6e3d2009-04-17 18:59:56 +00004456#ifdef TARGET_I386
4457 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
4458#endif
4459
blueswir18fcb1b92008-09-18 18:29:08 +00004460 return 0;
4461}
4462
aliguori5b08fc12008-08-21 20:08:03 +00004463#ifndef _WIN32
4464
4465static void termsig_handler(int signal)
4466{
4467 qemu_system_shutdown_request();
4468}
4469
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004470static void sigchld_handler(int signal)
4471{
4472 waitpid(-1, NULL, WNOHANG);
4473}
4474
4475static void sighandler_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00004476{
4477 struct sigaction act;
4478
4479 memset(&act, 0, sizeof(act));
4480 act.sa_handler = termsig_handler;
4481 sigaction(SIGINT, &act, NULL);
4482 sigaction(SIGHUP, &act, NULL);
4483 sigaction(SIGTERM, &act, NULL);
Jan Kiszka7c3370d2009-05-08 12:34:17 +02004484
4485 act.sa_handler = sigchld_handler;
4486 act.sa_flags = SA_NOCLDSTOP;
4487 sigaction(SIGCHLD, &act, NULL);
aliguori5b08fc12008-08-21 20:08:03 +00004488}
4489
4490#endif
4491
Paul Brook5cea8592009-05-30 00:52:44 +01004492#ifdef _WIN32
4493/* Look for support files in the same directory as the executable. */
4494static char *find_datadir(const char *argv0)
4495{
4496 char *p;
4497 char buf[MAX_PATH];
4498 DWORD len;
4499
4500 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
4501 if (len == 0) {
Blue Swirlc5947802009-06-09 20:51:21 +03004502 return NULL;
Paul Brook5cea8592009-05-30 00:52:44 +01004503 }
4504
4505 buf[len] = 0;
4506 p = buf + len - 1;
4507 while (p != buf && *p != '\\')
4508 p--;
4509 *p = 0;
4510 if (access(buf, R_OK) == 0) {
4511 return qemu_strdup(buf);
4512 }
4513 return NULL;
4514}
4515#else /* !_WIN32 */
4516
4517/* Find a likely location for support files using the location of the binary.
4518 For installed binaries this will be "$bindir/../share/qemu". When
4519 running from the build tree this will be "$bindir/../pc-bios". */
4520#define SHARE_SUFFIX "/share/qemu"
4521#define BUILD_SUFFIX "/pc-bios"
4522static char *find_datadir(const char *argv0)
4523{
4524 char *dir;
4525 char *p = NULL;
4526 char *res;
Paul Brook5cea8592009-05-30 00:52:44 +01004527 char buf[PATH_MAX];
Blue Swirl3a417592009-06-09 19:12:21 +00004528 size_t max_len;
Paul Brook5cea8592009-05-30 00:52:44 +01004529
4530#if defined(__linux__)
4531 {
4532 int len;
4533 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
4534 if (len > 0) {
4535 buf[len] = 0;
4536 p = buf;
4537 }
4538 }
4539#elif defined(__FreeBSD__)
4540 {
4541 int len;
4542 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
4543 if (len > 0) {
4544 buf[len] = 0;
4545 p = buf;
4546 }
4547 }
4548#endif
4549 /* If we don't have any way of figuring out the actual executable
4550 location then try argv[0]. */
4551 if (!p) {
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004552 p = realpath(argv0, buf);
Paul Brook5cea8592009-05-30 00:52:44 +01004553 if (!p) {
4554 return NULL;
4555 }
4556 }
4557 dir = dirname(p);
4558 dir = dirname(dir);
4559
Blue Swirl3a417592009-06-09 19:12:21 +00004560 max_len = strlen(dir) +
4561 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
4562 res = qemu_mallocz(max_len);
4563 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004564 if (access(res, R_OK)) {
Blue Swirl3a417592009-06-09 19:12:21 +00004565 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
Paul Brook5cea8592009-05-30 00:52:44 +01004566 if (access(res, R_OK)) {
4567 qemu_free(res);
4568 res = NULL;
4569 }
4570 }
Jean-Christophe DUBOIS4d224192009-09-02 23:59:02 +02004571
Paul Brook5cea8592009-05-30 00:52:44 +01004572 return res;
4573}
4574#undef SHARE_SUFFIX
4575#undef BUILD_SUFFIX
4576#endif
4577
4578char *qemu_find_file(int type, const char *name)
4579{
4580 int len;
4581 const char *subdir;
4582 char *buf;
4583
4584 /* If name contains path separators then try it as a straight path. */
4585 if ((strchr(name, '/') || strchr(name, '\\'))
4586 && access(name, R_OK) == 0) {
Jean-Christophe DUBOIS73ffc802009-09-02 23:59:06 +02004587 return qemu_strdup(name);
Paul Brook5cea8592009-05-30 00:52:44 +01004588 }
4589 switch (type) {
4590 case QEMU_FILE_TYPE_BIOS:
4591 subdir = "";
4592 break;
4593 case QEMU_FILE_TYPE_KEYMAP:
4594 subdir = "keymaps/";
4595 break;
4596 default:
4597 abort();
4598 }
4599 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
4600 buf = qemu_mallocz(len);
Blue Swirl3a417592009-06-09 19:12:21 +00004601 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
Paul Brook5cea8592009-05-30 00:52:44 +01004602 if (access(buf, R_OK)) {
4603 qemu_free(buf);
4604 return NULL;
4605 }
4606 return buf;
4607}
4608
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004609static int device_init_func(QemuOpts *opts, void *opaque)
4610{
4611 DeviceState *dev;
4612
4613 dev = qdev_device_add(opts);
4614 if (!dev)
4615 return -1;
4616 return 0;
4617}
4618
Gerd Hoffmann1a688d32009-12-08 13:11:36 +01004619static int chardev_init_func(QemuOpts *opts, void *opaque)
4620{
4621 CharDriverState *chr;
4622
4623 chr = qemu_chr_open_opts(opts, NULL);
4624 if (!chr)
4625 return -1;
4626 return 0;
4627}
4628
Gerd Hoffmann88589342009-12-08 13:11:50 +01004629static int mon_init_func(QemuOpts *opts, void *opaque)
4630{
4631 CharDriverState *chr;
4632 const char *chardev;
4633 const char *mode;
4634 int flags;
4635
4636 mode = qemu_opt_get(opts, "mode");
4637 if (mode == NULL) {
4638 mode = "readline";
4639 }
4640 if (strcmp(mode, "readline") == 0) {
4641 flags = MONITOR_USE_READLINE;
4642 } else if (strcmp(mode, "control") == 0) {
4643 flags = MONITOR_USE_CONTROL;
4644 } else {
4645 fprintf(stderr, "unknown monitor mode \"%s\"\n", mode);
4646 exit(1);
4647 }
4648
4649 if (qemu_opt_get_bool(opts, "default", 0))
4650 flags |= MONITOR_IS_DEFAULT;
4651
4652 chardev = qemu_opt_get(opts, "chardev");
4653 chr = qemu_chr_find(chardev);
4654 if (chr == NULL) {
4655 fprintf(stderr, "chardev \"%s\" not found\n", chardev);
4656 exit(1);
4657 }
4658
4659 monitor_init(chr, flags);
4660 return 0;
4661}
4662
Gerd Hoffmann6ca55822009-12-08 13:11:52 +01004663static void monitor_parse(const char *optarg, const char *mode)
Gerd Hoffmann88589342009-12-08 13:11:50 +01004664{
4665 static int monitor_device_index = 0;
4666 QemuOpts *opts;
4667 const char *p;
4668 char label[32];
4669 int def = 0;
4670
4671 if (strstart(optarg, "chardev:", &p)) {
4672 snprintf(label, sizeof(label), "%s", p);
4673 } else {
4674 if (monitor_device_index) {
4675 snprintf(label, sizeof(label), "monitor%d",
4676 monitor_device_index);
4677 } else {
4678 snprintf(label, sizeof(label), "monitor");
4679 def = 1;
4680 }
4681 opts = qemu_chr_parse_compat(label, optarg);
4682 if (!opts) {
4683 fprintf(stderr, "parse error: %s\n", optarg);
4684 exit(1);
4685 }
4686 }
4687
4688 opts = qemu_opts_create(&qemu_mon_opts, label, 1);
4689 if (!opts) {
4690 fprintf(stderr, "duplicate chardev: %s\n", label);
4691 exit(1);
4692 }
Gerd Hoffmann6ca55822009-12-08 13:11:52 +01004693 qemu_opt_set(opts, "mode", mode);
Gerd Hoffmann88589342009-12-08 13:11:50 +01004694 qemu_opt_set(opts, "chardev", label);
4695 if (def)
4696 qemu_opt_set(opts, "default", "on");
4697 monitor_device_index++;
4698}
4699
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004700struct device_config {
4701 enum {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004702 DEV_USB, /* -usbdevice */
4703 DEV_BT, /* -bt */
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01004704 DEV_SERIAL, /* -serial */
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01004705 DEV_PARALLEL, /* -parallel */
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004706 } type;
4707 const char *cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004708 QTAILQ_ENTRY(device_config) next;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004709};
Blue Swirl72cf2d42009-09-12 07:36:22 +00004710QTAILQ_HEAD(, device_config) device_configs = QTAILQ_HEAD_INITIALIZER(device_configs);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004711
4712static void add_device_config(int type, const char *cmdline)
4713{
4714 struct device_config *conf;
4715
4716 conf = qemu_mallocz(sizeof(*conf));
4717 conf->type = type;
4718 conf->cmdline = cmdline;
Blue Swirl72cf2d42009-09-12 07:36:22 +00004719 QTAILQ_INSERT_TAIL(&device_configs, conf, next);
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004720}
4721
4722static int foreach_device_config(int type, int (*func)(const char *cmdline))
4723{
4724 struct device_config *conf;
4725 int rc;
4726
Blue Swirl72cf2d42009-09-12 07:36:22 +00004727 QTAILQ_FOREACH(conf, &device_configs, next) {
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02004728 if (conf->type != type)
4729 continue;
4730 rc = func(conf->cmdline);
4731 if (0 != rc)
4732 return rc;
4733 }
4734 return 0;
4735}
4736
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01004737static int serial_parse(const char *devname)
4738{
4739 static int index = 0;
4740 char label[32];
4741
4742 if (strcmp(devname, "none") == 0)
4743 return 0;
4744 if (index == MAX_SERIAL_PORTS) {
4745 fprintf(stderr, "qemu: too many serial ports\n");
4746 exit(1);
4747 }
4748 snprintf(label, sizeof(label), "serial%d", index);
4749 serial_hds[index] = qemu_chr_open(label, devname, NULL);
4750 if (!serial_hds[index]) {
4751 fprintf(stderr, "qemu: could not open serial device '%s': %s\n",
4752 devname, strerror(errno));
4753 return -1;
4754 }
4755 index++;
4756 return 0;
4757}
4758
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01004759static int parallel_parse(const char *devname)
4760{
4761 static int index = 0;
4762 char label[32];
4763
4764 if (strcmp(devname, "none") == 0)
4765 return 0;
4766 if (index == MAX_PARALLEL_PORTS) {
4767 fprintf(stderr, "qemu: too many parallel ports\n");
4768 exit(1);
4769 }
4770 snprintf(label, sizeof(label), "parallel%d", index);
4771 parallel_hds[index] = qemu_chr_open(label, devname, NULL);
4772 if (!parallel_hds[index]) {
4773 fprintf(stderr, "qemu: could not open parallel device '%s': %s\n",
4774 devname, strerror(errno));
4775 return -1;
4776 }
4777 index++;
4778 return 0;
4779}
4780
malc902b3d52008-12-10 19:18:40 +00004781int main(int argc, char **argv, char **envp)
bellard0824d6f2003-06-24 13:42:40 +00004782{
aliguori59030a82009-04-05 18:43:41 +00004783 const char *gdbstub_dev = NULL;
j_mayer28c5af52007-11-11 01:50:45 +00004784 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00004785 int i;
j_mayer28c5af52007-11-11 01:50:45 +00004786 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00004787 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00004788 const char *kernel_filename, *kernel_cmdline;
Anthony Liguori195325a2009-10-30 12:42:29 -05004789 char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
aliguori3023f332009-01-16 19:04:14 +00004790 DisplayState *ds;
aliguori7d957bd2009-01-15 22:14:11 +00004791 DisplayChangeListener *dcl;
bellard46d47672004-11-16 01:45:27 +00004792 int cyls, heads, secs, translation;
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02004793 QemuOpts *hda_opts = NULL, *opts;
bellardcd6f1162004-05-13 22:02:20 +00004794 int optind;
4795 const char *r, *optarg;
aliguori9ede2fd2009-01-15 20:05:25 +00004796 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
4797 int virtio_console_index;
bellardd63d3072004-10-03 13:29:03 +00004798 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00004799 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00004800 const char *cpu_model;
blueswir1b9e82a52009-04-05 18:03:31 +00004801#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00004802 int fds[2];
blueswir1b9e82a52009-04-05 18:03:31 +00004803#endif
bellard26a5f132008-05-28 12:30:31 +00004804 int tb_size;
ths93815bc2007-03-19 15:58:31 +00004805 const char *pid_file = NULL;
aliguori5bb79102008-10-13 03:12:02 +00004806 const char *incoming = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004807#ifndef _WIN32
aliguori54042bc2009-02-27 22:16:47 +00004808 int fd = 0;
4809 struct passwd *pwd = NULL;
aliguori08585322009-02-27 22:09:45 +00004810 const char *chroot_dir = NULL;
4811 const char *run_as = NULL;
blueswir1b9e82a52009-04-05 18:03:31 +00004812#endif
aliguori268a3622009-04-21 22:30:27 +00004813 CPUState *env;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05004814 int show_vnc_port = 0;
bellard0bd48852005-11-11 00:00:47 +00004815
Jan Kiszka68752042009-09-15 13:36:04 +02004816 init_clocks();
4817
Gerd Hoffmannac7531e2009-08-14 10:36:06 +02004818 qemu_errors_to_file(stderr);
malc902b3d52008-12-10 19:18:40 +00004819 qemu_cache_utils_init(envp);
4820
Blue Swirl72cf2d42009-09-12 07:36:22 +00004821 QLIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00004822#ifndef _WIN32
4823 {
4824 struct sigaction act;
4825 sigfillset(&act.sa_mask);
4826 act.sa_flags = 0;
4827 act.sa_handler = SIG_IGN;
4828 sigaction(SIGPIPE, &act, NULL);
4829 }
bellard3587d7e2006-06-26 20:03:44 +00004830#else
4831 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00004832 /* Note: cpu_interrupt() is currently not SMP safe, so we force
4833 QEMU to run on a single CPU */
4834 {
4835 HANDLE h;
4836 DWORD mask, smask;
4837 int i;
4838 h = GetCurrentProcess();
4839 if (GetProcessAffinityMask(h, &mask, &smask)) {
4840 for(i = 0; i < 32; i++) {
4841 if (mask & (1 << i))
4842 break;
4843 }
4844 if (i != 32) {
4845 mask = 1 << i;
4846 SetProcessAffinityMask(h, mask);
4847 }
4848 }
4849 }
bellard67b915a2004-03-31 23:37:16 +00004850#endif
bellardbe995c22006-06-25 16:25:21 +00004851
Anthony Liguorif80f9ec2009-05-20 18:38:09 -05004852 module_call_init(MODULE_INIT_MACHINE);
Anthony Liguori0c257432009-05-21 20:41:01 -05004853 machine = find_default_machine();
j_mayer94fc95c2007-03-05 19:44:02 +00004854 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00004855 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00004856 ram_size = 0;
bellard33e39632003-07-06 17:15:21 +00004857 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00004858 kernel_filename = NULL;
4859 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00004860 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00004861 translation = BIOS_ATA_TRANSLATION_AUTO;
bellardc4b1fcc2004-03-14 21:44:30 +00004862
aliguori1b8fc812009-02-27 20:01:39 +00004863 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
aliguori9ede2fd2009-01-15 20:05:25 +00004864 virtio_consoles[i] = NULL;
4865 virtio_console_index = 0;
4866
aliguori268a3622009-04-21 22:30:27 +00004867 for (i = 0; i < MAX_NODES; i++) {
4868 node_mem[i] = 0;
4869 node_cpumask[i] = 0;
4870 }
4871
aliguori268a3622009-04-21 22:30:27 +00004872 nb_numa_nodes = 0;
bellard7c9d8e02005-11-15 22:16:05 +00004873 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00004874
bellard26a5f132008-05-28 12:30:31 +00004875 tb_size = 0;
blueswir141bd6392008-10-05 09:56:21 +00004876 autostart= 1;
4877
bellardcd6f1162004-05-13 22:02:20 +00004878 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00004879 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00004880 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00004881 break;
bellardcd6f1162004-05-13 22:02:20 +00004882 r = argv[optind];
4883 if (r[0] != '-') {
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004884 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00004885 } else {
4886 const QEMUOption *popt;
4887
4888 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00004889 /* Treat --foo the same as -foo. */
4890 if (r[1] == '-')
4891 r++;
bellardcd6f1162004-05-13 22:02:20 +00004892 popt = qemu_options;
4893 for(;;) {
4894 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00004895 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00004896 argv[0], r);
4897 exit(1);
4898 }
4899 if (!strcmp(popt->name, r + 1))
4900 break;
4901 popt++;
4902 }
4903 if (popt->flags & HAS_ARG) {
4904 if (optind >= argc) {
4905 fprintf(stderr, "%s: option '%s' requires an argument\n",
4906 argv[0], r);
4907 exit(1);
4908 }
4909 optarg = argv[optind++];
4910 } else {
4911 optarg = NULL;
4912 }
4913
4914 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00004915 case QEMU_OPTION_M:
4916 machine = find_machine(optarg);
4917 if (!machine) {
4918 QEMUMachine *m;
4919 printf("Supported machines are:\n");
4920 for(m = first_machine; m != NULL; m = m->next) {
Mark McLoughlin3f6599e2009-07-22 10:02:50 +01004921 if (m->alias)
4922 printf("%-10s %s (alias of %s)\n",
4923 m->alias, m->desc, m->name);
bellardcc1daa42005-06-05 14:49:17 +00004924 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00004925 m->name, m->desc,
Anthony Liguori0c257432009-05-21 20:41:01 -05004926 m->is_default ? " (default)" : "");
bellardcc1daa42005-06-05 14:49:17 +00004927 }
ths15f82202007-06-29 23:26:08 +00004928 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00004929 }
4930 break;
j_mayer94fc95c2007-03-05 19:44:02 +00004931 case QEMU_OPTION_cpu:
4932 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00004933 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00004934/* XXX: implement xxx_cpu_list for targets that still miss it */
4935#if defined(cpu_list)
4936 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00004937#endif
ths15f82202007-06-29 23:26:08 +00004938 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00004939 } else {
4940 cpu_model = optarg;
4941 }
4942 break;
bellardcd6f1162004-05-13 22:02:20 +00004943 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00004944 initrd_filename = optarg;
4945 break;
bellardcd6f1162004-05-13 22:02:20 +00004946 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00004947 if (cyls == 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004948 hda_opts = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00004949 else
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02004950 hda_opts = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00004951 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00004952 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00004953 translation == BIOS_ATA_TRANSLATION_LBA ?
4954 ",trans=lba" :
4955 translation == BIOS_ATA_TRANSLATION_NONE ?
4956 ",trans=none" : "");
4957 break;
bellardcd6f1162004-05-13 22:02:20 +00004958 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00004959 case QEMU_OPTION_hdc:
4960 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00004961 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00004962 break;
thse4bcb142007-12-02 04:51:10 +00004963 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00004964 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00004965 break;
Gerd Hoffmannd058fe02009-07-31 12:25:36 +02004966 case QEMU_OPTION_set:
4967 if (qemu_set_option(optarg) != 0)
4968 exit(1);
4969 break;
Gerd Hoffmannd0fef6f2009-12-08 13:11:34 +01004970 case QEMU_OPTION_global:
4971 if (qemu_global_option(optarg) != 0)
4972 exit(1);
4973 break;
balrog3e3d5812007-04-30 02:09:25 +00004974 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00004975 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00004976 break;
pbrooka1bb27b2007-04-06 16:49:48 +00004977 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00004978 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00004979 break;
j_mayer86f55662007-04-24 06:52:59 +00004980 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00004981 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00004982 break;
bellardcd6f1162004-05-13 22:02:20 +00004983 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00004984 snapshot = 1;
4985 break;
bellardcd6f1162004-05-13 22:02:20 +00004986 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00004987 {
bellard330d0412003-07-26 18:11:40 +00004988 const char *p;
4989 p = optarg;
4990 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004991 if (cyls < 1 || cyls > 16383)
4992 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004993 if (*p != ',')
4994 goto chs_fail;
4995 p++;
4996 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004997 if (heads < 1 || heads > 16)
4998 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004999 if (*p != ',')
5000 goto chs_fail;
5001 p++;
5002 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00005003 if (secs < 1 || secs > 63)
5004 goto chs_fail;
5005 if (*p == ',') {
5006 p++;
5007 if (!strcmp(p, "none"))
5008 translation = BIOS_ATA_TRANSLATION_NONE;
5009 else if (!strcmp(p, "lba"))
5010 translation = BIOS_ATA_TRANSLATION_LBA;
5011 else if (!strcmp(p, "auto"))
5012 translation = BIOS_ATA_TRANSLATION_AUTO;
5013 else
5014 goto chs_fail;
5015 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00005016 chs_fail:
bellard46d47672004-11-16 01:45:27 +00005017 fprintf(stderr, "qemu: invalid physical CHS format\n");
5018 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00005019 }
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005020 if (hda_opts != NULL) {
5021 char num[16];
5022 snprintf(num, sizeof(num), "%d", cyls);
5023 qemu_opt_set(hda_opts, "cyls", num);
5024 snprintf(num, sizeof(num), "%d", heads);
5025 qemu_opt_set(hda_opts, "heads", num);
5026 snprintf(num, sizeof(num), "%d", secs);
5027 qemu_opt_set(hda_opts, "secs", num);
5028 if (translation == BIOS_ATA_TRANSLATION_LBA)
5029 qemu_opt_set(hda_opts, "trans", "lba");
5030 if (translation == BIOS_ATA_TRANSLATION_NONE)
5031 qemu_opt_set(hda_opts, "trans", "none");
5032 }
bellard330d0412003-07-26 18:11:40 +00005033 }
5034 break;
aliguori268a3622009-04-21 22:30:27 +00005035 case QEMU_OPTION_numa:
5036 if (nb_numa_nodes >= MAX_NODES) {
5037 fprintf(stderr, "qemu: too many NUMA nodes\n");
5038 exit(1);
5039 }
5040 numa_add(optarg);
5041 break;
bellardcd6f1162004-05-13 22:02:20 +00005042 case QEMU_OPTION_nographic:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005043 display_type = DT_NOGRAPHIC;
bellarda20dd502003-09-30 21:07:02 +00005044 break;
balrog4d3b6f62008-02-10 16:33:14 +00005045#ifdef CONFIG_CURSES
5046 case QEMU_OPTION_curses:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005047 display_type = DT_CURSES;
balrog4d3b6f62008-02-10 16:33:14 +00005048 break;
5049#endif
balroga171fe32007-04-30 01:48:07 +00005050 case QEMU_OPTION_portrait:
5051 graphic_rotate = 1;
5052 break;
bellardcd6f1162004-05-13 22:02:20 +00005053 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00005054 kernel_filename = optarg;
5055 break;
bellardcd6f1162004-05-13 22:02:20 +00005056 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00005057 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00005058 break;
bellardcd6f1162004-05-13 22:02:20 +00005059 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00005060 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00005061 break;
bellardcd6f1162004-05-13 22:02:20 +00005062 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00005063 {
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005064 static const char * const params[] = {
Jan Kiszka95387492009-07-02 00:19:02 +02005065 "order", "once", "menu", NULL
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005066 };
5067 char buf[sizeof(boot_devices)];
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005068 char *standard_boot_devices;
Jan Kiszkaef3adf62009-07-02 00:19:02 +02005069 int legacy = 0;
5070
5071 if (!strchr(optarg, '=')) {
5072 legacy = 1;
5073 pstrcpy(buf, sizeof(buf), optarg);
5074 } else if (check_params(buf, sizeof(buf), params, optarg) < 0) {
5075 fprintf(stderr,
5076 "qemu: unknown boot parameter '%s' in '%s'\n",
5077 buf, optarg);
5078 exit(1);
5079 }
5080
5081 if (legacy ||
5082 get_param_value(buf, sizeof(buf), "order", optarg)) {
5083 boot_devices_bitmap = parse_bootdevices(buf);
5084 pstrcpy(boot_devices, sizeof(boot_devices), buf);
j_mayer28c5af52007-11-11 01:50:45 +00005085 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005086 if (!legacy) {
5087 if (get_param_value(buf, sizeof(buf),
5088 "once", optarg)) {
5089 boot_devices_bitmap |= parse_bootdevices(buf);
5090 standard_boot_devices = qemu_strdup(boot_devices);
5091 pstrcpy(boot_devices, sizeof(boot_devices), buf);
5092 qemu_register_reset(restore_boot_devices,
5093 standard_boot_devices);
5094 }
Jan Kiszka95387492009-07-02 00:19:02 +02005095 if (get_param_value(buf, sizeof(buf),
5096 "menu", optarg)) {
5097 if (!strcmp(buf, "on")) {
5098 boot_menu = 1;
5099 } else if (!strcmp(buf, "off")) {
5100 boot_menu = 0;
5101 } else {
5102 fprintf(stderr,
5103 "qemu: invalid option value '%s'\n",
5104 buf);
5105 exit(1);
5106 }
5107 }
Jan Kiszkae0f084b2009-07-02 00:19:02 +02005108 }
bellard36b486b2003-11-11 13:36:08 +00005109 }
5110 break;
bellardcd6f1162004-05-13 22:02:20 +00005111 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00005112 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00005113 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00005114 break;
bellard52ca8d62006-06-14 16:03:05 +00005115#ifdef TARGET_I386
5116 case QEMU_OPTION_no_fd_bootchk:
5117 fd_bootchk = 0;
5118 break;
5119#endif
Mark McLoughlina1ea4582009-10-08 19:58:26 +01005120 case QEMU_OPTION_netdev:
5121 if (net_client_parse(&qemu_netdev_opts, optarg) == -1) {
5122 exit(1);
5123 }
5124 break;
bellard7c9d8e02005-11-15 22:16:05 +00005125 case QEMU_OPTION_net:
Mark McLoughlin7f161aa2009-10-08 19:58:25 +01005126 if (net_client_parse(&qemu_net_opts, optarg) == -1) {
bellardc4b1fcc2004-03-14 21:44:30 +00005127 exit(1);
5128 }
bellard702c6512004-04-02 21:21:32 +00005129 break;
bellardc7f74642004-08-24 21:57:12 +00005130#ifdef CONFIG_SLIRP
5131 case QEMU_OPTION_tftp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005132 legacy_tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00005133 break;
ths47d5d012007-02-20 00:05:08 +00005134 case QEMU_OPTION_bootp:
Jan Kiszkaad196a92009-06-24 14:42:28 +02005135 legacy_bootp_filename = optarg;
ths47d5d012007-02-20 00:05:08 +00005136 break;
bellardc94c8d62004-09-13 21:37:34 +00005137#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00005138 case QEMU_OPTION_smb:
Markus Armbruster07527062009-10-06 12:16:57 +01005139 if (net_slirp_smb(optarg) < 0)
5140 exit(1);
bellard9d728e82004-09-05 23:09:03 +00005141 break;
bellardc94c8d62004-09-13 21:37:34 +00005142#endif
bellard9bf05442004-08-25 22:12:49 +00005143 case QEMU_OPTION_redir:
Markus Armbruster07527062009-10-06 12:16:57 +01005144 if (net_slirp_redir(optarg) < 0)
5145 exit(1);
bellard9bf05442004-08-25 22:12:49 +00005146 break;
bellardc7f74642004-08-24 21:57:12 +00005147#endif
balrogdc72ac12008-11-09 00:04:26 +00005148 case QEMU_OPTION_bt:
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005149 add_device_config(DEV_BT, optarg);
balrogdc72ac12008-11-09 00:04:26 +00005150 break;
bellard1d14ffa2005-10-30 18:58:22 +00005151#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00005152 case QEMU_OPTION_audio_help:
5153 AUD_help ();
5154 exit (0);
5155 break;
5156 case QEMU_OPTION_soundhw:
5157 select_soundhw (optarg);
5158 break;
5159#endif
bellardcd6f1162004-05-13 22:02:20 +00005160 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00005161 help(0);
bellardcd6f1162004-05-13 22:02:20 +00005162 break;
pbrook9bd7e6d2009-04-07 22:58:45 +00005163 case QEMU_OPTION_version:
5164 version();
5165 exit(0);
5166 break;
aurel3200f82b82008-04-27 21:12:55 +00005167 case QEMU_OPTION_m: {
5168 uint64_t value;
5169 char *ptr;
5170
5171 value = strtoul(optarg, &ptr, 10);
5172 switch (*ptr) {
5173 case 0: case 'M': case 'm':
5174 value <<= 20;
5175 break;
5176 case 'G': case 'g':
5177 value <<= 30;
5178 break;
5179 default:
5180 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00005181 exit(1);
5182 }
aurel3200f82b82008-04-27 21:12:55 +00005183
5184 /* On 32-bit hosts, QEMU is limited by virtual address space */
Anthony Liguori4a1418e2009-08-10 17:07:24 -05005185 if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
aurel3200f82b82008-04-27 21:12:55 +00005186 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
5187 exit(1);
5188 }
Anthony Liguoric227f092009-10-01 16:12:16 -05005189 if (value != (uint64_t)(ram_addr_t)value) {
aurel3200f82b82008-04-27 21:12:55 +00005190 fprintf(stderr, "qemu: ram size too large\n");
5191 exit(1);
5192 }
5193 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00005194 break;
aurel3200f82b82008-04-27 21:12:55 +00005195 }
bellardcd6f1162004-05-13 22:02:20 +00005196 case QEMU_OPTION_d:
5197 {
5198 int mask;
blueswir1c7cd6a32008-10-02 18:27:46 +00005199 const CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00005200
bellardcd6f1162004-05-13 22:02:20 +00005201 mask = cpu_str_to_log_mask(optarg);
5202 if (!mask) {
5203 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00005204 for(item = cpu_log_items; item->mask != 0; item++) {
5205 printf("%-10s %s\n", item->name, item->help);
5206 }
5207 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00005208 }
5209 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00005210 }
bellardcd6f1162004-05-13 22:02:20 +00005211 break;
bellardcd6f1162004-05-13 22:02:20 +00005212 case QEMU_OPTION_s:
aliguori59030a82009-04-05 18:43:41 +00005213 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
bellardcd6f1162004-05-13 22:02:20 +00005214 break;
aliguori59030a82009-04-05 18:43:41 +00005215 case QEMU_OPTION_gdb:
5216 gdbstub_dev = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005217 break;
bellardcd6f1162004-05-13 22:02:20 +00005218 case QEMU_OPTION_L:
Paul Brook5cea8592009-05-30 00:52:44 +01005219 data_dir = optarg;
bellardcd6f1162004-05-13 22:02:20 +00005220 break;
j_mayer1192dad2007-10-05 13:08:35 +00005221 case QEMU_OPTION_bios:
5222 bios_name = optarg;
5223 break;
aurel321b530a62009-04-05 20:08:59 +00005224 case QEMU_OPTION_singlestep:
5225 singlestep = 1;
5226 break;
bellardcd6f1162004-05-13 22:02:20 +00005227 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00005228 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00005229 break;
bellard3d11d0e2004-12-12 16:56:30 +00005230 case QEMU_OPTION_k:
5231 keyboard_layout = optarg;
5232 break;
bellardee22c2f2004-06-03 12:49:50 +00005233 case QEMU_OPTION_localtime:
5234 rtc_utc = 0;
5235 break;
malc3893c122008-09-28 00:42:05 +00005236 case QEMU_OPTION_vga:
5237 select_vgahw (optarg);
bellard1bfe8562004-07-08 21:17:50 +00005238 break;
blueswir15824d652009-03-28 06:44:27 +00005239#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00005240 case QEMU_OPTION_g:
5241 {
5242 const char *p;
5243 int w, h, depth;
5244 p = optarg;
5245 w = strtol(p, (char **)&p, 10);
5246 if (w <= 0) {
5247 graphic_error:
5248 fprintf(stderr, "qemu: invalid resolution or depth\n");
5249 exit(1);
5250 }
5251 if (*p != 'x')
5252 goto graphic_error;
5253 p++;
5254 h = strtol(p, (char **)&p, 10);
5255 if (h <= 0)
5256 goto graphic_error;
5257 if (*p == 'x') {
5258 p++;
5259 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00005260 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00005261 depth != 24 && depth != 32)
5262 goto graphic_error;
5263 } else if (*p == '\0') {
5264 depth = graphic_depth;
5265 } else {
5266 goto graphic_error;
5267 }
ths3b46e622007-09-17 08:09:54 +00005268
bellarde9b137c2004-06-21 16:46:10 +00005269 graphic_width = w;
5270 graphic_height = h;
5271 graphic_depth = depth;
5272 }
5273 break;
blueswir15824d652009-03-28 06:44:27 +00005274#endif
ths20d8a3e2007-02-18 17:04:49 +00005275 case QEMU_OPTION_echr:
5276 {
5277 char *r;
5278 term_escape_char = strtol(optarg, &r, 0);
5279 if (r == optarg)
5280 printf("Bad argument to echr\n");
5281 break;
5282 }
bellard82c643f2004-07-14 17:28:13 +00005283 case QEMU_OPTION_monitor:
Gerd Hoffmann6ca55822009-12-08 13:11:52 +01005284 monitor_parse(optarg, "readline");
5285 default_monitor = 0;
5286 break;
5287 case QEMU_OPTION_qmp:
5288 monitor_parse(optarg, "control");
Gerd Hoffmannabdeed02009-12-08 13:11:43 +01005289 default_monitor = 0;
bellard82c643f2004-07-14 17:28:13 +00005290 break;
Gerd Hoffmann22a0e042009-12-08 13:11:51 +01005291 case QEMU_OPTION_mon:
5292 opts = qemu_opts_parse(&qemu_mon_opts, optarg, "chardev");
5293 if (!opts) {
5294 fprintf(stderr, "parse error: %s\n", optarg);
5295 exit(1);
5296 }
5297 default_monitor = 0;
5298 break;
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005299 case QEMU_OPTION_chardev:
5300 opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
5301 if (!opts) {
5302 fprintf(stderr, "parse error: %s\n", optarg);
5303 exit(1);
5304 }
Gerd Hoffmann191bc012009-09-10 10:58:35 +02005305 break;
bellard82c643f2004-07-14 17:28:13 +00005306 case QEMU_OPTION_serial:
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01005307 add_device_config(DEV_SERIAL, optarg);
5308 default_serial = 0;
bellard82c643f2004-07-14 17:28:13 +00005309 break;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005310 case QEMU_OPTION_watchdog:
Markus Armbruster09aaa162009-08-21 10:31:34 +02005311 if (watchdog) {
5312 fprintf(stderr,
5313 "qemu: only one watchdog option may be given\n");
5314 return 1;
5315 }
5316 watchdog = optarg;
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01005317 break;
5318 case QEMU_OPTION_watchdog_action:
5319 if (select_watchdog_action(optarg) == -1) {
5320 fprintf(stderr, "Unknown -watchdog-action parameter\n");
5321 exit(1);
5322 }
5323 break;
aliguori51ecf132009-01-15 20:06:40 +00005324 case QEMU_OPTION_virtiocon:
5325 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
5326 fprintf(stderr, "qemu: too many virtio consoles\n");
5327 exit(1);
5328 }
5329 virtio_consoles[virtio_console_index] = optarg;
5330 virtio_console_index++;
5331 break;
bellard6508fe52005-01-15 12:02:56 +00005332 case QEMU_OPTION_parallel:
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01005333 add_device_config(DEV_PARALLEL, optarg);
5334 default_parallel = 0;
bellard6508fe52005-01-15 12:02:56 +00005335 break;
bellardd63d3072004-10-03 13:29:03 +00005336 case QEMU_OPTION_loadvm:
5337 loadvm = optarg;
5338 break;
5339 case QEMU_OPTION_full_screen:
5340 full_screen = 1;
5341 break;
ths667acca2006-12-11 02:08:05 +00005342#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00005343 case QEMU_OPTION_no_frame:
5344 no_frame = 1;
5345 break;
ths3780e192007-06-21 21:08:02 +00005346 case QEMU_OPTION_alt_grab:
5347 alt_grab = 1;
5348 break;
Dustin Kirkland0ca9f8a2009-09-17 15:48:04 -05005349 case QEMU_OPTION_ctrl_grab:
5350 ctrl_grab = 1;
5351 break;
ths667acca2006-12-11 02:08:05 +00005352 case QEMU_OPTION_no_quit:
5353 no_quit = 1;
5354 break;
aliguori7d957bd2009-01-15 22:14:11 +00005355 case QEMU_OPTION_sdl:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005356 display_type = DT_SDL;
aliguori7d957bd2009-01-15 22:14:11 +00005357 break;
ths667acca2006-12-11 02:08:05 +00005358#endif
bellardf7cce892004-12-08 22:21:25 +00005359 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00005360 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00005361 break;
bellarda09db212005-04-30 16:10:35 +00005362#ifdef TARGET_I386
5363 case QEMU_OPTION_win2k_hack:
5364 win2k_install_hack = 1;
5365 break;
aliguori73822ec2009-01-15 20:11:34 +00005366 case QEMU_OPTION_rtc_td_hack:
5367 rtc_td_hack = 1;
5368 break;
aliguori8a92ea22009-02-27 20:12:36 +00005369 case QEMU_OPTION_acpitable:
5370 if(acpi_table_add(optarg) < 0) {
5371 fprintf(stderr, "Wrong acpi table provided\n");
5372 exit(1);
5373 }
5374 break;
aliguorib6f6e3d2009-04-17 18:59:56 +00005375 case QEMU_OPTION_smbios:
5376 if(smbios_entry_add(optarg) < 0) {
5377 fprintf(stderr, "Wrong smbios provided\n");
5378 exit(1);
5379 }
5380 break;
bellarda09db212005-04-30 16:10:35 +00005381#endif
aliguori7ba1e612008-11-05 16:04:33 +00005382#ifdef CONFIG_KVM
5383 case QEMU_OPTION_enable_kvm:
5384 kvm_allowed = 1;
aliguori7ba1e612008-11-05 16:04:33 +00005385 break;
5386#endif
bellardbb36d472005-11-05 14:22:28 +00005387 case QEMU_OPTION_usb:
5388 usb_enabled = 1;
5389 break;
bellarda594cfb2005-11-06 16:13:29 +00005390 case QEMU_OPTION_usbdevice:
5391 usb_enabled = 1;
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005392 add_device_config(DEV_USB, optarg);
5393 break;
5394 case QEMU_OPTION_device:
Mark McLoughlinb386bec2009-10-06 12:17:01 +01005395 if (!qemu_opts_parse(&qemu_device_opts, optarg, "driver")) {
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005396 exit(1);
5397 }
bellarda594cfb2005-11-06 16:13:29 +00005398 break;
bellard6a00d602005-11-21 23:25:50 +00005399 case QEMU_OPTION_smp:
Andre Przywaradc6b1c02009-08-19 15:42:40 +02005400 smp_parse(optarg);
aliguorib2097002008-10-07 20:39:39 +00005401 if (smp_cpus < 1) {
bellard6a00d602005-11-21 23:25:50 +00005402 fprintf(stderr, "Invalid number of CPUs\n");
5403 exit(1);
5404 }
Jes Sorensen6be68d72009-07-23 17:03:42 +02005405 if (max_cpus < smp_cpus) {
5406 fprintf(stderr, "maxcpus must be equal to or greater than "
5407 "smp\n");
5408 exit(1);
5409 }
5410 if (max_cpus > 255) {
5411 fprintf(stderr, "Unsupported number of maxcpus\n");
5412 exit(1);
5413 }
bellard6a00d602005-11-21 23:25:50 +00005414 break;
bellard24236862006-04-30 21:28:36 +00005415 case QEMU_OPTION_vnc:
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005416 display_type = DT_VNC;
ths73fc9742006-12-22 02:09:07 +00005417 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00005418 break;
blueswir15824d652009-03-28 06:44:27 +00005419#ifdef TARGET_I386
bellard6515b202006-05-03 22:02:44 +00005420 case QEMU_OPTION_no_acpi:
5421 acpi_enabled = 0;
5422 break;
aliguori16b29ae2008-12-17 23:28:44 +00005423 case QEMU_OPTION_no_hpet:
5424 no_hpet = 1;
5425 break;
Markus Armbruster7d4c3d52009-06-26 19:15:14 +02005426 case QEMU_OPTION_balloon:
5427 if (balloon_parse(optarg) < 0) {
5428 fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
5429 exit(1);
5430 }
Eduardo Habkostdf97b922009-06-10 16:34:08 -03005431 break;
blueswir15824d652009-03-28 06:44:27 +00005432#endif
bellardd1beab82006-10-02 19:44:22 +00005433 case QEMU_OPTION_no_reboot:
5434 no_reboot = 1;
5435 break;
aurel32b2f76162008-04-11 21:35:52 +00005436 case QEMU_OPTION_no_shutdown:
5437 no_shutdown = 1;
5438 break;
balrog9467cd42007-05-01 01:34:14 +00005439 case QEMU_OPTION_show_cursor:
5440 cursor_hide = 0;
5441 break;
blueswir18fcb1b92008-09-18 18:29:08 +00005442 case QEMU_OPTION_uuid:
5443 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
5444 fprintf(stderr, "Fail to parse UUID string."
5445 " Wrong format.\n");
5446 exit(1);
5447 }
5448 break;
blueswir15824d652009-03-28 06:44:27 +00005449#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005450 case QEMU_OPTION_daemonize:
5451 daemonize = 1;
5452 break;
blueswir15824d652009-03-28 06:44:27 +00005453#endif
ths9ae02552007-01-05 17:39:04 +00005454 case QEMU_OPTION_option_rom:
5455 if (nb_option_roms >= MAX_OPTION_ROMS) {
5456 fprintf(stderr, "Too many option ROMs\n");
5457 exit(1);
5458 }
5459 option_rom[nb_option_roms] = optarg;
5460 nb_option_roms++;
5461 break;
blueswir15824d652009-03-28 06:44:27 +00005462#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00005463 case QEMU_OPTION_semihosting:
5464 semihosting_enabled = 1;
5465 break;
blueswir15824d652009-03-28 06:44:27 +00005466#endif
thsc35734b2007-03-19 15:17:08 +00005467 case QEMU_OPTION_name:
Andi Kleen18894652009-07-02 09:34:17 +02005468 qemu_name = qemu_strdup(optarg);
5469 {
5470 char *p = strchr(qemu_name, ',');
5471 if (p != NULL) {
5472 *p++ = 0;
5473 if (strncmp(p, "process=", 8)) {
5474 fprintf(stderr, "Unknown subargument %s to -name", p);
5475 exit(1);
5476 }
5477 p += 8;
5478 set_proc_name(p);
5479 }
5480 }
thsc35734b2007-03-19 15:17:08 +00005481 break;
blueswir195efd112008-12-24 20:26:14 +00005482#if defined(TARGET_SPARC) || defined(TARGET_PPC)
blueswir166508602007-05-01 14:16:52 +00005483 case QEMU_OPTION_prom_env:
5484 if (nb_prom_envs >= MAX_PROM_ENVS) {
5485 fprintf(stderr, "Too many prom variables\n");
5486 exit(1);
5487 }
5488 prom_envs[nb_prom_envs] = optarg;
5489 nb_prom_envs++;
5490 break;
5491#endif
balrog2b8f2d42007-07-27 22:08:46 +00005492#ifdef TARGET_ARM
5493 case QEMU_OPTION_old_param:
5494 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00005495 break;
balrog2b8f2d42007-07-27 22:08:46 +00005496#endif
thsf3dcfad2007-08-24 01:26:02 +00005497 case QEMU_OPTION_clock:
5498 configure_alarms(optarg);
5499 break;
bellard7e0af5d02007-11-07 16:24:33 +00005500 case QEMU_OPTION_startdate:
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005501 configure_rtc_date_offset(optarg, 1);
5502 break;
5503 case QEMU_OPTION_rtc:
5504 opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
5505 if (!opts) {
5506 fprintf(stderr, "parse error: %s\n", optarg);
5507 exit(1);
bellard7e0af5d02007-11-07 16:24:33 +00005508 }
Jan Kiszka1ed2fc12009-09-15 13:36:04 +02005509 configure_rtc(opts);
bellard7e0af5d02007-11-07 16:24:33 +00005510 break;
bellard26a5f132008-05-28 12:30:31 +00005511 case QEMU_OPTION_tb_size:
5512 tb_size = strtol(optarg, NULL, 0);
5513 if (tb_size < 0)
5514 tb_size = 0;
5515 break;
pbrook2e70f6e2008-06-29 01:03:05 +00005516 case QEMU_OPTION_icount:
5517 use_icount = 1;
5518 if (strcmp(optarg, "auto") == 0) {
5519 icount_time_shift = -1;
5520 } else {
5521 icount_time_shift = strtol(optarg, NULL, 0);
5522 }
5523 break;
aliguori5bb79102008-10-13 03:12:02 +00005524 case QEMU_OPTION_incoming:
5525 incoming = optarg;
5526 break;
Gerd Hoffmannd8c208d2009-12-08 13:11:46 +01005527 case QEMU_OPTION_nodefaults:
5528 default_serial = 0;
5529 default_parallel = 0;
5530 default_monitor = 0;
5531 default_vga = 0;
Gerd Hoffmanncb4522c2009-12-08 13:11:47 +01005532 default_net = 0;
Gerd Hoffmannaa40fc92009-12-08 13:11:48 +01005533 default_drive = 0;
Gerd Hoffmannd8c208d2009-12-08 13:11:46 +01005534 break;
blueswir15824d652009-03-28 06:44:27 +00005535#ifndef _WIN32
aliguori08585322009-02-27 22:09:45 +00005536 case QEMU_OPTION_chroot:
5537 chroot_dir = optarg;
5538 break;
5539 case QEMU_OPTION_runas:
5540 run_as = optarg;
5541 break;
blueswir15824d652009-03-28 06:44:27 +00005542#endif
aliguorie37630c2009-04-22 15:19:10 +00005543#ifdef CONFIG_XEN
5544 case QEMU_OPTION_xen_domid:
5545 xen_domid = atoi(optarg);
5546 break;
5547 case QEMU_OPTION_xen_create:
5548 xen_mode = XEN_CREATE;
5549 break;
5550 case QEMU_OPTION_xen_attach:
5551 xen_mode = XEN_ATTACH;
5552 break;
5553#endif
Gerd Hoffmann715a6642009-10-14 10:39:28 +02005554 case QEMU_OPTION_readconfig:
5555 {
5556 FILE *fp;
5557 fp = fopen(optarg, "r");
5558 if (fp == NULL) {
5559 fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
5560 exit(1);
5561 }
5562 if (qemu_config_parse(fp) != 0) {
5563 exit(1);
5564 }
5565 fclose(fp);
5566 break;
5567 }
5568 case QEMU_OPTION_writeconfig:
5569 {
5570 FILE *fp;
5571 if (strcmp(optarg, "-") == 0) {
5572 fp = stdout;
5573 } else {
5574 fp = fopen(optarg, "w");
5575 if (fp == NULL) {
5576 fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
5577 exit(1);
5578 }
5579 }
5580 qemu_config_write(fp);
5581 fclose(fp);
5582 break;
5583 }
bellardcd6f1162004-05-13 22:02:20 +00005584 }
bellard0824d6f2003-06-24 13:42:40 +00005585 }
5586 }
bellard330d0412003-07-26 18:11:40 +00005587
Paul Brook5cea8592009-05-30 00:52:44 +01005588 /* If no data_dir is specified then try to find it relative to the
5589 executable path. */
5590 if (!data_dir) {
5591 data_dir = find_datadir(argv[0]);
5592 }
5593 /* If all else fails use the install patch specified when building. */
5594 if (!data_dir) {
5595 data_dir = CONFIG_QEMU_SHAREDIR;
5596 }
5597
Jes Sorensen6be68d72009-07-23 17:03:42 +02005598 /*
5599 * Default to max_cpus = smp_cpus, in case the user doesn't
5600 * specify a max_cpus value.
5601 */
5602 if (!max_cpus)
5603 max_cpus = smp_cpus;
5604
balrog3d878ca2008-10-28 10:59:59 +00005605 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
aliguorib2097002008-10-07 20:39:39 +00005606 if (smp_cpus > machine->max_cpus) {
5607 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
5608 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
5609 machine->max_cpus);
5610 exit(1);
5611 }
5612
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01005613 qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0);
5614
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005615 if (display_type == DT_NOGRAPHIC) {
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01005616 if (default_parallel)
5617 add_device_config(DEV_PARALLEL, "null");
Gerd Hoffmanne1c09172009-12-08 13:11:44 +01005618 if (default_serial && default_monitor) {
5619 add_device_config(DEV_SERIAL, "mon:stdio");
5620 } else {
5621 if (default_serial)
5622 add_device_config(DEV_SERIAL, "stdio");
5623 if (default_monitor)
Gerd Hoffmann6ca55822009-12-08 13:11:52 +01005624 monitor_parse("stdio", "readline");
Gerd Hoffmanne1c09172009-12-08 13:11:44 +01005625 }
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01005626 } else {
5627 if (default_serial)
5628 add_device_config(DEV_SERIAL, "vc:80Cx24C");
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01005629 if (default_parallel)
5630 add_device_config(DEV_PARALLEL, "vc:80Cx24C");
Gerd Hoffmannabdeed02009-12-08 13:11:43 +01005631 if (default_monitor)
Gerd Hoffmann6ca55822009-12-08 13:11:52 +01005632 monitor_parse("vc:80Cx24C", "readline");
aliguoribc0129d2008-08-01 15:12:34 +00005633 }
Gerd Hoffmann64465292009-12-08 13:11:45 +01005634 if (default_vga)
5635 vga_interface_type = VGA_CIRRUS;
aliguoribc0129d2008-08-01 15:12:34 +00005636
Gerd Hoffmann1a688d32009-12-08 13:11:36 +01005637 if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0)
5638 exit(1);
5639
ths71e3ceb2006-12-22 02:11:31 +00005640#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005641 if (daemonize) {
5642 pid_t pid;
5643
5644 if (pipe(fds) == -1)
5645 exit(1);
5646
5647 pid = fork();
5648 if (pid > 0) {
5649 uint8_t status;
5650 ssize_t len;
5651
5652 close(fds[1]);
5653
5654 again:
ths93815bc2007-03-19 15:58:31 +00005655 len = read(fds[0], &status, 1);
5656 if (len == -1 && (errno == EINTR))
5657 goto again;
5658
5659 if (len != 1)
5660 exit(1);
5661 else if (status == 1) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005662 fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno));
ths93815bc2007-03-19 15:58:31 +00005663 exit(1);
5664 } else
5665 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00005666 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00005667 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00005668
Kevin Wolf40ff6d72009-12-02 12:24:42 +01005669 close(fds[0]);
5670 qemu_set_cloexec(fds[1]);
5671
ths71e3ceb2006-12-22 02:11:31 +00005672 setsid();
5673
5674 pid = fork();
5675 if (pid > 0)
5676 exit(0);
5677 else if (pid < 0)
5678 exit(1);
5679
5680 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00005681
5682 signal(SIGTSTP, SIG_IGN);
5683 signal(SIGTTOU, SIG_IGN);
5684 signal(SIGTTIN, SIG_IGN);
5685 }
ths71e3ceb2006-12-22 02:11:31 +00005686
thsaa26bb22007-03-25 21:33:06 +00005687 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00005688 if (daemonize) {
5689 uint8_t status = 1;
5690 write(fds[1], &status, 1);
5691 } else
Justin M. Forbes850810d2009-10-01 09:42:56 -05005692 fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
ths93815bc2007-03-19 15:58:31 +00005693 exit(1);
5694 }
blueswir1b9e82a52009-04-05 18:03:31 +00005695#endif
ths93815bc2007-03-19 15:58:31 +00005696
Marcelo Tosatti214910a2009-09-18 02:41:23 -03005697 if (kvm_enabled()) {
5698 int ret;
5699
5700 ret = kvm_init(smp_cpus);
5701 if (ret < 0) {
5702 fprintf(stderr, "failed to initialize KVM\n");
5703 exit(1);
5704 }
5705 }
5706
aliguori3fcf7b62009-04-24 18:03:25 +00005707 if (qemu_init_main_loop()) {
5708 fprintf(stderr, "qemu_init_main_loop failed\n");
5709 exit(1);
5710 }
bellarda20dd502003-09-30 21:07:02 +00005711 linux_boot = (kernel_filename != NULL);
balrog6c41b272007-11-17 12:12:29 +00005712
thsf8d39c02008-07-03 10:01:15 +00005713 if (!linux_boot && *kernel_cmdline != '\0') {
5714 fprintf(stderr, "-append only allowed with -kernel option\n");
5715 exit(1);
5716 }
5717
5718 if (!linux_boot && initrd_filename != NULL) {
5719 fprintf(stderr, "-initrd only allowed with -kernel option\n");
5720 exit(1);
5721 }
5722
Filip Navarabf65f532009-07-27 10:02:04 -05005723#ifndef _WIN32
5724 /* Win32 doesn't support line-buffering and requires size >= 2 */
bellardb118d612003-06-30 23:36:21 +00005725 setvbuf(stdout, NULL, _IOLBF, 0);
Filip Navarabf65f532009-07-27 10:02:04 -05005726#endif
ths3b46e622007-09-17 08:09:54 +00005727
aliguori7183b4b2008-11-05 20:40:18 +00005728 if (init_timer_alarm() < 0) {
5729 fprintf(stderr, "could not initialize alarm timer\n");
5730 exit(1);
5731 }
pbrook2e70f6e2008-06-29 01:03:05 +00005732 if (use_icount && icount_time_shift < 0) {
5733 use_icount = 2;
5734 /* 125MIPS seems a reasonable initial guess at the guest speed.
5735 It will be corrected fairly quickly anyway. */
5736 icount_time_shift = 3;
5737 init_icount_adjust();
5738 }
pbrook634fce92006-07-15 17:40:09 +00005739
bellardfd1dff42006-02-01 21:29:26 +00005740#ifdef _WIN32
5741 socket_init();
5742#endif
5743
Mark McLoughlindc1c9fe2009-10-06 12:17:16 +01005744 if (net_init_clients() < 0) {
5745 exit(1);
bellard702c6512004-04-02 21:21:32 +00005746 }
bellardf1510b22003-06-25 00:07:40 +00005747
Glauber Costa406c8df2009-06-17 09:05:30 -04005748 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
5749 net_set_boot_mask(net_boot);
5750
balrogdc72ac12008-11-09 00:04:26 +00005751 /* init the bluetooth world */
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005752 if (foreach_device_config(DEV_BT, bt_parse))
5753 exit(1);
balrogdc72ac12008-11-09 00:04:26 +00005754
bellard0824d6f2003-06-24 13:42:40 +00005755 /* init the memory */
pbrook94a6b542009-04-11 17:15:54 +00005756 if (ram_size == 0)
5757 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
balrog7fb4fdc2008-04-24 17:59:27 +00005758
bellard26a5f132008-05-28 12:30:31 +00005759 /* init the dynamic translator */
5760 cpu_exec_init_all(tb_size * 1024 * 1024);
5761
Markus Armbrustereb852012009-10-27 18:41:44 +01005762 bdrv_init_with_whitelist();
thse4bcb142007-12-02 04:51:10 +00005763
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02005764 blk_mig_init();
5765
Gerd Hoffmannaa40fc92009-12-08 13:11:48 +01005766 if (default_drive) {
5767 /* we always create the cdrom drive, even if no disk is there */
5768 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00005769
Gerd Hoffmannaa40fc92009-12-08 13:11:48 +01005770 /* we always create at least one floppy */
5771 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00005772
Gerd Hoffmannaa40fc92009-12-08 13:11:48 +01005773 /* we always create one sd slot, even if no card is in it */
5774 drive_add(NULL, SD_ALIAS);
5775 }
balrog9d413d12007-12-04 00:10:34 +00005776
ths96d30e42007-01-07 20:42:14 +00005777 /* open the virtual block devices */
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005778 if (snapshot)
Gerd Hoffmann7282a032009-07-31 12:25:35 +02005779 qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0);
5780 if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0)
Gerd Hoffmann9dfd7c72009-07-22 16:43:04 +02005781 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00005782
Juan Quintela2faf58c2009-09-10 03:04:28 +02005783 vmstate_register(0, &vmstate_timers ,&timers_state);
lirans@il.ibm.comc163b5c2009-11-02 15:40:58 +02005784 register_savevm_live("ram", 0, 3, NULL, ram_save_live, NULL,
5785 ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00005786
aliguori268a3622009-04-21 22:30:27 +00005787 if (nb_numa_nodes > 0) {
5788 int i;
5789
5790 if (nb_numa_nodes > smp_cpus) {
5791 nb_numa_nodes = smp_cpus;
5792 }
5793
5794 /* If no memory size if given for any node, assume the default case
5795 * and distribute the available memory equally across all nodes
5796 */
5797 for (i = 0; i < nb_numa_nodes; i++) {
5798 if (node_mem[i] != 0)
5799 break;
5800 }
5801 if (i == nb_numa_nodes) {
5802 uint64_t usedmem = 0;
5803
5804 /* On Linux, the each node's border has to be 8MB aligned,
5805 * the final node gets the rest.
5806 */
5807 for (i = 0; i < nb_numa_nodes - 1; i++) {
5808 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
5809 usedmem += node_mem[i];
5810 }
5811 node_mem[i] = ram_size - usedmem;
5812 }
5813
5814 for (i = 0; i < nb_numa_nodes; i++) {
5815 if (node_cpumask[i] != 0)
5816 break;
5817 }
5818 /* assigning the VCPUs round-robin is easier to implement, guest OSes
5819 * must cope with this anyway, because there are BIOSes out there in
5820 * real machines which also use this scheme.
5821 */
5822 if (i == nb_numa_nodes) {
5823 for (i = 0; i < smp_cpus; i++) {
5824 node_cpumask[i % nb_numa_nodes] |= 1 << i;
5825 }
5826 }
5827 }
5828
Gerd Hoffmann998bbd72009-12-08 13:11:41 +01005829 if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
5830 exit(1);
Gerd Hoffmann6a5e8b02009-12-08 13:11:42 +01005831 if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
5832 exit(1);
aliguori2796dae2009-01-16 20:23:27 +00005833
5834 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5835 const char *devname = virtio_consoles[i];
5836 if (devname && strcmp(devname, "none")) {
5837 char label[32];
5838 snprintf(label, sizeof(label), "virtcon%d", i);
aurel32ceecf1d2009-01-18 14:08:04 +00005839 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
aliguori2796dae2009-01-16 20:23:27 +00005840 if (!virtcon_hds[i]) {
Justin M. Forbes850810d2009-10-01 09:42:56 -05005841 fprintf(stderr, "qemu: could not open virtio console '%s': %s\n",
5842 devname, strerror(errno));
aliguori2796dae2009-01-16 20:23:27 +00005843 exit(1);
5844 }
5845 }
5846 }
5847
Paul Brookaae94602009-05-14 22:35:06 +01005848 module_call_init(MODULE_INIT_DEVICE);
5849
Markus Armbruster09aaa162009-08-21 10:31:34 +02005850 if (watchdog) {
5851 i = select_watchdog(watchdog);
5852 if (i > 0)
5853 exit (i == 1 ? 1 : 0);
5854 }
5855
Gerd Hoffmannb6b61142009-07-15 13:48:21 +02005856 if (machine->compat_props) {
Gerd Hoffmann458fb672009-12-08 13:11:33 +01005857 qdev_prop_register_global_list(machine->compat_props);
Gerd Hoffmannb6b61142009-07-15 13:48:21 +02005858 }
Gerd Hoffmannd0fef6f2009-12-08 13:11:34 +01005859 qemu_add_globals();
5860
Paul Brookfbe1b592009-05-13 17:56:25 +01005861 machine->init(ram_size, boot_devices,
aliguori3023f332009-01-16 19:04:14 +00005862 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
5863
aliguori268a3622009-04-21 22:30:27 +00005864
Juan Quintela67b3b712009-08-28 19:25:15 +02005865#ifndef _WIN32
5866 /* must be after terminal init, SDL library changes signal handlers */
5867 sighandler_setup();
5868#endif
5869
aliguori268a3622009-04-21 22:30:27 +00005870 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5871 for (i = 0; i < nb_numa_nodes; i++) {
5872 if (node_cpumask[i] & (1 << env->cpu_index)) {
5873 env->numa_node = i;
5874 }
5875 }
5876 }
5877
aliguori6f338c32009-02-11 15:21:54 +00005878 current_machine = machine;
5879
aliguori3023f332009-01-16 19:04:14 +00005880 /* init USB devices */
5881 if (usb_enabled) {
Markus Armbruster07527062009-10-06 12:16:57 +01005882 if (foreach_device_config(DEV_USB, usb_parse) < 0)
5883 exit(1);
aliguori3023f332009-01-16 19:04:14 +00005884 }
5885
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005886 /* init generic devices */
Gerd Hoffmannf31d07d2009-07-31 12:25:37 +02005887 if (qemu_opts_foreach(&qemu_device_opts, device_init_func, NULL, 1) != 0)
Gerd Hoffmannbd3c9482009-07-15 13:59:26 +02005888 exit(1);
5889
aliguori8f391ab2009-01-19 16:34:10 +00005890 if (!display_state)
5891 dumb_display_init();
aliguori3023f332009-01-16 19:04:14 +00005892 /* just use the first displaystate for the moment */
5893 ds = display_state;
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005894
5895 if (display_type == DT_DEFAULT) {
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005896#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005897 display_type = DT_SDL;
5898#else
5899 display_type = DT_VNC;
5900 vnc_display = "localhost:0,to=99";
5901 show_vnc_port = 1;
5902#endif
5903 }
5904
5905
5906 switch (display_type) {
5907 case DT_NOGRAPHIC:
5908 break;
5909#if defined(CONFIG_CURSES)
5910 case DT_CURSES:
5911 curses_display_init(ds, full_screen);
5912 break;
5913#endif
bellard5b0753e2005-03-01 21:37:28 +00005914#if defined(CONFIG_SDL)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005915 case DT_SDL:
5916 sdl_display_init(ds, full_screen, no_frame);
5917 break;
bellard5b0753e2005-03-01 21:37:28 +00005918#elif defined(CONFIG_COCOA)
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005919 case DT_SDL:
5920 cocoa_display_init(ds, full_screen);
5921 break;
bellard313aa562003-08-10 21:52:11 +00005922#endif
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005923 case DT_VNC:
5924 vnc_display_init(ds);
5925 if (vnc_display_open(ds, vnc_display) < 0)
5926 exit(1);
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005927
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005928 if (show_vnc_port) {
5929 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
Anthony Liguorif92f8af2009-05-20 13:01:02 -05005930 }
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005931 break;
5932 default:
5933 break;
bellard313aa562003-08-10 21:52:11 +00005934 }
aliguori7d957bd2009-01-15 22:14:11 +00005935 dpy_resize(ds);
aliguori5b08fc12008-08-21 20:08:03 +00005936
aliguori3023f332009-01-16 19:04:14 +00005937 dcl = ds->listeners;
5938 while (dcl != NULL) {
5939 if (dcl->dpy_refresh != NULL) {
5940 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5941 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
ths20d8a3e2007-02-18 17:04:49 +00005942 }
aliguori3023f332009-01-16 19:04:14 +00005943 dcl = dcl->next;
bellard82c643f2004-07-14 17:28:13 +00005944 }
aliguori3023f332009-01-16 19:04:14 +00005945
Anthony Liguori993fbfd2009-05-21 16:54:00 -05005946 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
blueswir19043b622009-01-21 19:28:13 +00005947 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5948 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5949 }
5950
aliguori2796dae2009-01-16 20:23:27 +00005951 text_consoles_set_display(display_state);
5952
Gerd Hoffmann88589342009-12-08 13:11:50 +01005953 if (qemu_opts_foreach(&qemu_mon_opts, mon_init_func, NULL, 1) != 0)
5954 exit(1);
bellard82c643f2004-07-14 17:28:13 +00005955
aliguori59030a82009-04-05 18:43:41 +00005956 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
5957 fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
5958 gdbstub_dev);
5959 exit(1);
balrog45669e02007-07-02 13:20:17 +00005960 }
balrog45669e02007-07-02 13:20:17 +00005961
Gerd Hoffmann3418bd22009-09-25 21:42:41 +02005962 qdev_machine_creation_done();
5963
Gerd Hoffmann45a50b12009-10-01 16:42:33 +02005964 rom_load_all();
5965
Juan Quintela504c2942009-11-12 00:39:13 +01005966 qemu_system_reset();
Juan Quintela05f24012009-08-20 19:42:22 +02005967 if (loadvm) {
5968 if (load_vmstate(cur_mon, loadvm) < 0) {
5969 autostart = 0;
5970 }
5971 }
bellardd63d3072004-10-03 13:29:03 +00005972
Glauber Costa2bb8c102009-07-24 16:20:23 -04005973 if (incoming) {
aliguori5bb79102008-10-13 03:12:02 +00005974 qemu_start_incoming_migration(incoming);
Avi Kivity6b99dad2009-08-09 14:39:20 +03005975 } else if (autostart) {
aliguoric0f4ce72009-03-05 23:01:01 +00005976 vm_start();
Avi Kivity6b99dad2009-08-09 14:39:20 +03005977 }
thsffd843b2006-12-21 19:46:43 +00005978
blueswir1b9e82a52009-04-05 18:03:31 +00005979#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005980 if (daemonize) {
5981 uint8_t status = 0;
5982 ssize_t len;
ths71e3ceb2006-12-22 02:11:31 +00005983
5984 again1:
5985 len = write(fds[1], &status, 1);
5986 if (len == -1 && (errno == EINTR))
5987 goto again1;
5988
5989 if (len != 1)
5990 exit(1);
5991
aliguoribd54b862008-07-23 00:58:33 +00005992 chdir("/");
Kevin Wolf40ff6d72009-12-02 12:24:42 +01005993 TFR(fd = qemu_open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00005994 if (fd == -1)
5995 exit(1);
aliguori08585322009-02-27 22:09:45 +00005996 }
ths71e3ceb2006-12-22 02:11:31 +00005997
aliguori08585322009-02-27 22:09:45 +00005998 if (run_as) {
5999 pwd = getpwnam(run_as);
6000 if (!pwd) {
6001 fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
6002 exit(1);
6003 }
6004 }
ths71e3ceb2006-12-22 02:11:31 +00006005
aliguori08585322009-02-27 22:09:45 +00006006 if (chroot_dir) {
6007 if (chroot(chroot_dir) < 0) {
6008 fprintf(stderr, "chroot failed\n");
6009 exit(1);
6010 }
6011 chdir("/");
6012 }
6013
6014 if (run_as) {
6015 if (setgid(pwd->pw_gid) < 0) {
6016 fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
6017 exit(1);
6018 }
6019 if (setuid(pwd->pw_uid) < 0) {
6020 fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
6021 exit(1);
6022 }
6023 if (setuid(0) != -1) {
6024 fprintf(stderr, "Dropping privileges failed\n");
6025 exit(1);
6026 }
6027 }
aliguori08585322009-02-27 22:09:45 +00006028
6029 if (daemonize) {
6030 dup2(fd, 0);
6031 dup2(fd, 1);
6032 dup2(fd, 2);
6033
6034 close(fd);
ths71e3ceb2006-12-22 02:11:31 +00006035 }
blueswir1b9e82a52009-04-05 18:03:31 +00006036#endif
ths71e3ceb2006-12-22 02:11:31 +00006037
bellard8a7ddc32004-03-31 19:00:16 +00006038 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00006039 quit_timers();
aliguori63a01ef2008-10-31 19:10:00 +00006040 net_cleanup();
thsb46a8902007-10-21 23:20:45 +00006041
bellard0824d6f2003-06-24 13:42:40 +00006042 return 0;
6043}