blob: 01d57d49fbc22a188af4354bd72fa092058500b6 [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 */
pbrook87ecb682007-11-17 17:14:51 +000024#include "hw/hw.h"
25#include "hw/boards.h"
26#include "hw/usb.h"
27#include "hw/pcmcia.h"
28#include "hw/pc.h"
pbrook87ecb682007-11-17 17:14:51 +000029#include "hw/audiodev.h"
30#include "hw/isa.h"
aurel322e4d9fb2008-04-08 06:01:02 +000031#include "hw/baum.h"
balrog1ae26a12008-09-28 23:19:47 +000032#include "hw/bt.h"
pbrook87ecb682007-11-17 17:14:51 +000033#include "net.h"
34#include "console.h"
35#include "sysemu.h"
36#include "gdbstub.h"
37#include "qemu-timer.h"
38#include "qemu-char.h"
39#include "block.h"
40#include "audio/audio.h"
aliguori5bb79102008-10-13 03:12:02 +000041#include "migration.h"
aliguori7ba1e612008-11-05 16:04:33 +000042#include "kvm.h"
bellard67b915a2004-03-31 23:37:16 +000043
bellard0824d6f2003-06-24 13:42:40 +000044#include <unistd.h>
bellard0824d6f2003-06-24 13:42:40 +000045#include <fcntl.h>
46#include <signal.h>
47#include <time.h>
bellard0824d6f2003-06-24 13:42:40 +000048#include <errno.h>
bellard67b915a2004-03-31 23:37:16 +000049#include <sys/time.h>
bellardc88676f2006-08-06 13:36:11 +000050#include <zlib.h>
bellard67b915a2004-03-31 23:37:16 +000051
52#ifndef _WIN32
53#include <sys/times.h>
bellardf1510b22003-06-25 00:07:40 +000054#include <sys/wait.h>
bellard67b915a2004-03-31 23:37:16 +000055#include <termios.h>
bellard67b915a2004-03-31 23:37:16 +000056#include <sys/mman.h>
bellardf1510b22003-06-25 00:07:40 +000057#include <sys/ioctl.h>
blueswir124646c72008-11-07 16:55:48 +000058#include <sys/resource.h>
bellardf1510b22003-06-25 00:07:40 +000059#include <sys/socket.h>
bellardc94c8d62004-09-13 21:37:34 +000060#include <netinet/in.h>
blueswir124646c72008-11-07 16:55:48 +000061#include <net/if.h>
62#if defined(__NetBSD__)
63#include <net/if_tap.h>
64#endif
65#ifdef __linux__
66#include <linux/if_tun.h>
67#endif
68#include <arpa/inet.h>
bellard9d728e82004-09-05 23:09:03 +000069#include <dirent.h>
bellard7c9d8e02005-11-15 22:16:05 +000070#include <netdb.h>
thscb4b9762007-09-13 12:39:35 +000071#include <sys/select.h>
bellard7d3505c2004-05-12 19:32:15 +000072#ifdef _BSD
73#include <sys/stat.h>
blueswir124646c72008-11-07 16:55:48 +000074#ifdef __FreeBSD__
bellard7d3505c2004-05-12 19:32:15 +000075#include <libutil.h>
blueswir124646c72008-11-07 16:55:48 +000076#else
77#include <util.h>
blueswir1128ab2f2008-08-15 18:33:42 +000078#endif
ths5c40d2b2007-06-23 16:03:36 +000079#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
80#include <freebsd/stdlib.h>
bellard7d3505c2004-05-12 19:32:15 +000081#else
blueswir1223f0d72008-09-30 18:12:18 +000082#ifdef __linux__
bellard7d3505c2004-05-12 19:32:15 +000083#include <pty.h>
84#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000085#include <linux/rtc.h>
thsbd494f42007-09-16 20:03:23 +000086
87/* For the benefit of older linux systems which don't supply it,
88 we use a local copy of hpet.h. */
89/* #include <linux/hpet.h> */
90#include "hpet.h"
91
bellarde57a8c02005-11-10 23:58:52 +000092#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000093#include <linux/parport.h>
blueswir1223f0d72008-09-30 18:12:18 +000094#endif
95#ifdef __sun__
thsd5d10bc2007-02-17 22:54:49 +000096#include <sys/stat.h>
97#include <sys/ethernet.h>
98#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000099#include <netinet/arp.h>
100#include <netinet/in.h>
101#include <netinet/in_systm.h>
102#include <netinet/ip.h>
103#include <netinet/ip_icmp.h> // must come after ip.h
104#include <netinet/udp.h>
105#include <netinet/tcp.h>
106#include <net/if.h>
107#include <syslog.h>
108#include <stropts.h>
bellard67b915a2004-03-31 23:37:16 +0000109#endif
bellard7d3505c2004-05-12 19:32:15 +0000110#endif
bellardec530c82006-04-25 22:36:06 +0000111#endif
bellard67b915a2004-03-31 23:37:16 +0000112
aliguori03ff3ca2008-09-15 15:51:35 +0000113#include "qemu_socket.h"
114
bellardc20709a2004-04-21 23:27:19 +0000115#if defined(CONFIG_SLIRP)
116#include "libslirp.h"
117#endif
118
blueswir19892fbf2008-08-24 10:34:20 +0000119#if defined(__OpenBSD__)
120#include <util.h>
121#endif
122
ths8a16d272008-07-19 09:56:24 +0000123#if defined(CONFIG_VDE)
124#include <libvdeplug.h>
125#endif
126
bellard67b915a2004-03-31 23:37:16 +0000127#ifdef _WIN32
bellard7d3505c2004-05-12 19:32:15 +0000128#include <malloc.h>
bellard67b915a2004-03-31 23:37:16 +0000129#include <sys/timeb.h>
ths4fddf622007-12-17 04:42:29 +0000130#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000131#define getopt_long_only getopt_long
132#define memalign(align, size) malloc(size)
133#endif
134
bellard73332e52004-04-04 20:22:28 +0000135#ifdef CONFIG_SDL
bellard96bcd4f2004-07-10 16:26:15 +0000136#ifdef __APPLE__
bellard83fb7ad2004-07-05 21:25:26 +0000137#include <SDL/SDL.h>
bellard96bcd4f2004-07-10 16:26:15 +0000138#endif
bellard73332e52004-04-04 20:22:28 +0000139#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000140
bellard5b0753e2005-03-01 21:37:28 +0000141#ifdef CONFIG_COCOA
142#undef main
143#define main qemu_main
144#endif /* CONFIG_COCOA */
145
bellard0824d6f2003-06-24 13:42:40 +0000146#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000147
bellard8a7ddc32004-03-31 19:00:16 +0000148#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000149
bellard5a671352003-10-01 00:13:48 +0000150#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
thsb46a8902007-10-21 23:20:45 +0000151#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
pbrooka14d6c82006-12-23 15:37:33 +0000152#ifdef __sun__
153#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
154#else
155#define SMBD_COMMAND "/usr/sbin/smbd"
156#endif
bellardf1510b22003-06-25 00:07:40 +0000157
bellard0824d6f2003-06-24 13:42:40 +0000158//#define DEBUG_UNUSED_IOPORT
bellardfd872592004-05-12 19:11:15 +0000159//#define DEBUG_IOPORT
blueswir19dc63a12008-10-04 07:25:46 +0000160//#define DEBUG_NET
161//#define DEBUG_SLIRP
bellard330d0412003-07-26 18:11:40 +0000162
bellard77d4bc32004-05-26 22:13:53 +0000163#ifdef TARGET_PPC
164#define DEFAULT_RAM_SIZE 144
165#else
bellard1bfe8562004-07-08 21:17:50 +0000166#define DEFAULT_RAM_SIZE 128
bellard77d4bc32004-05-26 22:13:53 +0000167#endif
bellard313aa562003-08-10 21:52:11 +0000168
pbrook0d92ed32006-05-21 16:30:15 +0000169/* Max number of USB devices that can be specified on the commandline. */
170#define MAX_USB_CMDLINE 8
171
balrogdc72ac12008-11-09 00:04:26 +0000172/* Max number of bluetooth switches on the commandline. */
173#define MAX_BT_CMDLINE 10
174
bellard7dea1da2003-11-16 15:59:30 +0000175/* XXX: use a two level table to limit memory usage */
176#define MAX_IOPORTS 65536
bellard0824d6f2003-06-24 13:42:40 +0000177
bellard80cabfa2004-03-14 12:20:30 +0000178const char *bios_dir = CONFIG_QEMU_SHAREDIR;
j_mayer1192dad2007-10-05 13:08:35 +0000179const char *bios_name = NULL;
blueswir1dbed7e42008-10-01 19:38:09 +0000180static void *ioport_opaque[MAX_IOPORTS];
181static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
182static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
thse4bcb142007-12-02 04:51:10 +0000183/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000184 to store the VM snapshots */
thse4bcb142007-12-02 04:51:10 +0000185DriveInfo drives_table[MAX_DRIVES+1];
186int nb_drives;
blueswir1dbed7e42008-10-01 19:38:09 +0000187static int vga_ram_size;
malccb5a7aa2008-09-28 00:42:12 +0000188enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
aliguori0e82f342008-10-31 18:44:40 +0000189DisplayState display_state;
bellarda20dd502003-09-30 21:07:02 +0000190int nographic;
blueswir1dbed7e42008-10-01 19:38:09 +0000191static int curses;
bellard3d11d0e2004-12-12 16:56:30 +0000192const char* keyboard_layout = NULL;
bellard313aa562003-08-10 21:52:11 +0000193int64_t ticks_per_sec;
aurel3200f82b82008-04-27 21:12:55 +0000194ram_addr_t ram_size;
bellardc4b1fcc2004-03-14 21:44:30 +0000195int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000196NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000197int vm_running;
balrogf6503052008-02-17 11:42:19 +0000198static int rtc_utc = 1;
199static int rtc_date_offset = -1; /* -1 means no change */
bellard1bfe8562004-07-08 21:17:50 +0000200int cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +0000201int vmsvga_enabled = 0;
bellardd8272202005-04-06 20:32:23 +0000202#ifdef TARGET_SPARC
203int graphic_width = 1024;
204int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000205int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000206#else
bellard1bfe8562004-07-08 21:17:50 +0000207int graphic_width = 800;
208int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000209int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000210#endif
blueswir1dbed7e42008-10-01 19:38:09 +0000211static int full_screen = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000212#ifdef CONFIG_SDL
blueswir1dbed7e42008-10-01 19:38:09 +0000213static int no_frame = 0;
blueswir1634a21f2008-11-16 11:34:07 +0000214#endif
ths667acca2006-12-11 02:08:05 +0000215int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000216CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000217CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
bellarda09db212005-04-30 16:10:35 +0000218#ifdef TARGET_I386
219int win2k_install_hack = 0;
220#endif
bellardbb36d472005-11-05 14:22:28 +0000221int usb_enabled = 0;
bellard6a00d602005-11-21 23:25:50 +0000222int smp_cpus = 1;
ths73fc9742006-12-22 02:09:07 +0000223const char *vnc_display;
bellard6515b202006-05-03 22:02:44 +0000224int acpi_enabled = 1;
bellard52ca8d62006-06-14 16:03:05 +0000225int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000226int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000227int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000228int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000229int graphic_rotate = 0;
ths71e3ceb2006-12-22 02:11:31 +0000230int daemonize = 0;
ths9ae02552007-01-05 17:39:04 +0000231const char *option_rom[MAX_OPTION_ROMS];
232int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000233int semihosting_enabled = 0;
balrog2b8f2d42007-07-27 22:08:46 +0000234#ifdef TARGET_ARM
235int old_param = 0;
236#endif
thsc35734b2007-03-19 15:17:08 +0000237const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000238int alt_grab = 0;
blueswir166508602007-05-01 14:16:52 +0000239#ifdef TARGET_SPARC
240unsigned int nb_prom_envs = 0;
241const char *prom_envs[MAX_PROM_ENVS];
242#endif
blueswir1dbed7e42008-10-01 19:38:09 +0000243static int nb_drives_opt;
244static struct drive_opt {
balrog609497a2008-01-14 02:56:53 +0000245 const char *file;
246 char opt[1024];
247} drives_opt[MAX_DRIVES];
bellard0824d6f2003-06-24 13:42:40 +0000248
balrogee5605e2007-12-03 03:01:40 +0000249static CPUState *cur_cpu;
250static CPUState *next_cpu;
balrog76ea08f2007-12-16 11:48:54 +0000251static int event_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000252/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000253static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000254/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000255#define MAX_ICOUNT_SHIFT 10
256/* Compensate for varying guest execution speed. */
257static int64_t qemu_icount_bias;
blueswir1dbed7e42008-10-01 19:38:09 +0000258static QEMUTimer *icount_rt_timer;
259static QEMUTimer *icount_vm_timer;
balrogee5605e2007-12-03 03:01:40 +0000260
blueswir18fcb1b92008-09-18 18:29:08 +0000261uint8_t qemu_uuid[16];
262
bellard0824d6f2003-06-24 13:42:40 +0000263/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000264/* x86 ISA bus support */
265
266target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000267PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000268
aliguori477e3ed2008-07-23 15:19:59 +0000269static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
270static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
271
272static uint32_t ioport_read(int index, uint32_t address)
273{
274 static IOPortReadFunc *default_func[3] = {
275 default_ioport_readb,
276 default_ioport_readw,
277 default_ioport_readl
278 };
279 IOPortReadFunc *func = ioport_read_table[index][address];
280 if (!func)
281 func = default_func[index];
282 return func(ioport_opaque[address], address);
283}
284
285static void ioport_write(int index, uint32_t address, uint32_t data)
286{
287 static IOPortWriteFunc *default_func[3] = {
288 default_ioport_writeb,
289 default_ioport_writew,
290 default_ioport_writel
291 };
292 IOPortWriteFunc *func = ioport_write_table[index][address];
293 if (!func)
294 func = default_func[index];
295 func(ioport_opaque[address], address, data);
296}
297
pbrook9596ebb2007-11-18 01:44:38 +0000298static uint32_t default_ioport_readb(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000299{
300#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000301 fprintf(stderr, "unused inb: port=0x%04x\n", address);
bellard0824d6f2003-06-24 13:42:40 +0000302#endif
bellardfc01f7e2003-06-30 10:03:06 +0000303 return 0xff;
bellard0824d6f2003-06-24 13:42:40 +0000304}
305
pbrook9596ebb2007-11-18 01:44:38 +0000306static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000307{
308#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000309 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
bellard0824d6f2003-06-24 13:42:40 +0000310#endif
311}
312
313/* default is to make two byte accesses */
pbrook9596ebb2007-11-18 01:44:38 +0000314static uint32_t default_ioport_readw(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000315{
316 uint32_t data;
aliguori477e3ed2008-07-23 15:19:59 +0000317 data = ioport_read(0, address);
bellarddb45c292004-05-12 19:50:26 +0000318 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000319 data |= ioport_read(0, address) << 8;
bellard0824d6f2003-06-24 13:42:40 +0000320 return data;
321}
322
pbrook9596ebb2007-11-18 01:44:38 +0000323static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000324{
aliguori477e3ed2008-07-23 15:19:59 +0000325 ioport_write(0, address, data & 0xff);
bellarddb45c292004-05-12 19:50:26 +0000326 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000327 ioport_write(0, address, (data >> 8) & 0xff);
bellardfc01f7e2003-06-30 10:03:06 +0000328}
329
pbrook9596ebb2007-11-18 01:44:38 +0000330static uint32_t default_ioport_readl(void *opaque, uint32_t address)
bellardfc01f7e2003-06-30 10:03:06 +0000331{
332#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000333 fprintf(stderr, "unused inl: port=0x%04x\n", address);
bellardfc01f7e2003-06-30 10:03:06 +0000334#endif
335 return 0xffffffff;
336}
337
pbrook9596ebb2007-11-18 01:44:38 +0000338static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
bellardfc01f7e2003-06-30 10:03:06 +0000339{
340#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000341 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
bellardfc01f7e2003-06-30 10:03:06 +0000342#endif
bellard0824d6f2003-06-24 13:42:40 +0000343}
344
bellardfc01f7e2003-06-30 10:03:06 +0000345/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000346int register_ioport_read(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000347 IOPortReadFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000348{
bellardfc01f7e2003-06-30 10:03:06 +0000349 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000350
bellardc4b1fcc2004-03-14 21:44:30 +0000351 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000352 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000353 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000354 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000355 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000356 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000357 } else {
balrog88fdf562008-04-26 21:11:22 +0000358 hw_error("register_ioport_read: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000359 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000360 }
361 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000362 ioport_read_table[bsize][i] = func;
bellardc4b1fcc2004-03-14 21:44:30 +0000363 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
balrog88fdf562008-04-26 21:11:22 +0000364 hw_error("register_ioport_read: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000365 ioport_opaque[i] = opaque;
366 }
bellard0824d6f2003-06-24 13:42:40 +0000367 return 0;
368}
369
bellardfc01f7e2003-06-30 10:03:06 +0000370/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000371int register_ioport_write(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000372 IOPortWriteFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000373{
bellardfc01f7e2003-06-30 10:03:06 +0000374 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000375
bellardc4b1fcc2004-03-14 21:44:30 +0000376 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000377 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000378 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000379 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000380 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000381 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000382 } else {
balrog88fdf562008-04-26 21:11:22 +0000383 hw_error("register_ioport_write: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000384 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000385 }
386 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000387 ioport_write_table[bsize][i] = func;
balrog88fdf562008-04-26 21:11:22 +0000388 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
389 hw_error("register_ioport_write: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000390 ioport_opaque[i] = opaque;
391 }
bellardf1510b22003-06-25 00:07:40 +0000392 return 0;
393}
394
bellard69b91032004-05-18 23:05:28 +0000395void isa_unassign_ioport(int start, int length)
396{
397 int i;
398
399 for(i = start; i < start + length; i++) {
400 ioport_read_table[0][i] = default_ioport_readb;
401 ioport_read_table[1][i] = default_ioport_readw;
402 ioport_read_table[2][i] = default_ioport_readl;
403
404 ioport_write_table[0][i] = default_ioport_writeb;
405 ioport_write_table[1][i] = default_ioport_writew;
406 ioport_write_table[2][i] = default_ioport_writel;
407 }
408}
409
bellard20f32282005-01-03 23:36:21 +0000410/***********************************************************/
411
bellardc45886d2004-01-05 00:02:06 +0000412void cpu_outb(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000413{
bellardfd872592004-05-12 19:11:15 +0000414#ifdef DEBUG_IOPORT
415 if (loglevel & CPU_LOG_IOPORT)
416 fprintf(logfile, "outb: %04x %02x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000417#endif
aliguori477e3ed2008-07-23 15:19:59 +0000418 ioport_write(0, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000419#ifdef USE_KQEMU
420 if (env)
421 env->last_io_time = cpu_get_time_fast();
422#endif
bellard0824d6f2003-06-24 13:42:40 +0000423}
424
bellardc45886d2004-01-05 00:02:06 +0000425void cpu_outw(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000426{
bellardfd872592004-05-12 19:11:15 +0000427#ifdef DEBUG_IOPORT
428 if (loglevel & CPU_LOG_IOPORT)
429 fprintf(logfile, "outw: %04x %04x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000430#endif
aliguori477e3ed2008-07-23 15:19:59 +0000431 ioport_write(1, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000432#ifdef USE_KQEMU
433 if (env)
434 env->last_io_time = cpu_get_time_fast();
435#endif
bellard0824d6f2003-06-24 13:42:40 +0000436}
437
bellardc45886d2004-01-05 00:02:06 +0000438void cpu_outl(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000439{
bellardfd872592004-05-12 19:11:15 +0000440#ifdef DEBUG_IOPORT
441 if (loglevel & CPU_LOG_IOPORT)
442 fprintf(logfile, "outl: %04x %08x\n", addr, val);
443#endif
aliguori477e3ed2008-07-23 15:19:59 +0000444 ioport_write(2, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000445#ifdef USE_KQEMU
446 if (env)
447 env->last_io_time = cpu_get_time_fast();
448#endif
bellard0824d6f2003-06-24 13:42:40 +0000449}
450
bellardc45886d2004-01-05 00:02:06 +0000451int cpu_inb(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000452{
bellardfd872592004-05-12 19:11:15 +0000453 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000454 val = ioport_read(0, addr);
bellardfd872592004-05-12 19:11:15 +0000455#ifdef DEBUG_IOPORT
456 if (loglevel & CPU_LOG_IOPORT)
457 fprintf(logfile, "inb : %04x %02x\n", addr, val);
458#endif
bellard89bfc102006-02-08 22:46:31 +0000459#ifdef USE_KQEMU
460 if (env)
461 env->last_io_time = cpu_get_time_fast();
462#endif
bellardfd872592004-05-12 19:11:15 +0000463 return val;
bellard0824d6f2003-06-24 13:42:40 +0000464}
465
bellardc45886d2004-01-05 00:02:06 +0000466int cpu_inw(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000467{
bellardfd872592004-05-12 19:11:15 +0000468 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000469 val = ioport_read(1, addr);
bellardfd872592004-05-12 19:11:15 +0000470#ifdef DEBUG_IOPORT
471 if (loglevel & CPU_LOG_IOPORT)
472 fprintf(logfile, "inw : %04x %04x\n", addr, val);
473#endif
bellard89bfc102006-02-08 22:46:31 +0000474#ifdef USE_KQEMU
475 if (env)
476 env->last_io_time = cpu_get_time_fast();
477#endif
bellardfd872592004-05-12 19:11:15 +0000478 return val;
bellard0824d6f2003-06-24 13:42:40 +0000479}
480
bellardc45886d2004-01-05 00:02:06 +0000481int cpu_inl(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000482{
bellardfd872592004-05-12 19:11:15 +0000483 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000484 val = ioport_read(2, addr);
bellardfd872592004-05-12 19:11:15 +0000485#ifdef DEBUG_IOPORT
486 if (loglevel & CPU_LOG_IOPORT)
487 fprintf(logfile, "inl : %04x %08x\n", addr, val);
488#endif
bellard89bfc102006-02-08 22:46:31 +0000489#ifdef USE_KQEMU
490 if (env)
491 env->last_io_time = cpu_get_time_fast();
492#endif
bellardfd872592004-05-12 19:11:15 +0000493 return val;
bellard0824d6f2003-06-24 13:42:40 +0000494}
495
496/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000497void hw_error(const char *fmt, ...)
498{
499 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000500 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000501
502 va_start(ap, fmt);
503 fprintf(stderr, "qemu: hardware error: ");
504 vfprintf(stderr, fmt, ap);
505 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000506 for(env = first_cpu; env != NULL; env = env->next_cpu) {
507 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000508#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000509 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000510#else
bellard6a00d602005-11-21 23:25:50 +0000511 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000512#endif
bellard6a00d602005-11-21 23:25:50 +0000513 }
bellard0824d6f2003-06-24 13:42:40 +0000514 va_end(ap);
515 abort();
516}
517
bellard8a7ddc32004-03-31 19:00:16 +0000518/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000519/* keyboard/mouse */
520
521static QEMUPutKBDEvent *qemu_put_kbd_event;
522static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000523static QEMUPutMouseEntry *qemu_put_mouse_event_head;
524static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000525
526void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
527{
528 qemu_put_kbd_event_opaque = opaque;
529 qemu_put_kbd_event = func;
530}
531
ths455204e2007-01-05 16:42:13 +0000532QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
533 void *opaque, int absolute,
534 const char *name)
bellard63066f42004-06-03 18:45:02 +0000535{
ths455204e2007-01-05 16:42:13 +0000536 QEMUPutMouseEntry *s, *cursor;
537
538 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
539 if (!s)
540 return NULL;
541
542 s->qemu_put_mouse_event = func;
543 s->qemu_put_mouse_event_opaque = opaque;
544 s->qemu_put_mouse_event_absolute = absolute;
545 s->qemu_put_mouse_event_name = qemu_strdup(name);
546 s->next = NULL;
547
548 if (!qemu_put_mouse_event_head) {
549 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
550 return s;
551 }
552
553 cursor = qemu_put_mouse_event_head;
554 while (cursor->next != NULL)
555 cursor = cursor->next;
556
557 cursor->next = s;
558 qemu_put_mouse_event_current = s;
559
560 return s;
561}
562
563void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
564{
565 QEMUPutMouseEntry *prev = NULL, *cursor;
566
567 if (!qemu_put_mouse_event_head || entry == NULL)
568 return;
569
570 cursor = qemu_put_mouse_event_head;
571 while (cursor != NULL && cursor != entry) {
572 prev = cursor;
573 cursor = cursor->next;
574 }
575
576 if (cursor == NULL) // does not exist or list empty
577 return;
578 else if (prev == NULL) { // entry is head
579 qemu_put_mouse_event_head = cursor->next;
580 if (qemu_put_mouse_event_current == entry)
581 qemu_put_mouse_event_current = cursor->next;
582 qemu_free(entry->qemu_put_mouse_event_name);
583 qemu_free(entry);
584 return;
585 }
586
587 prev->next = entry->next;
588
589 if (qemu_put_mouse_event_current == entry)
590 qemu_put_mouse_event_current = prev;
591
592 qemu_free(entry->qemu_put_mouse_event_name);
593 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000594}
595
596void kbd_put_keycode(int keycode)
597{
598 if (qemu_put_kbd_event) {
599 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
600 }
601}
602
603void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
604{
ths455204e2007-01-05 16:42:13 +0000605 QEMUPutMouseEvent *mouse_event;
606 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000607 int width;
ths455204e2007-01-05 16:42:13 +0000608
609 if (!qemu_put_mouse_event_current) {
610 return;
611 }
612
613 mouse_event =
614 qemu_put_mouse_event_current->qemu_put_mouse_event;
615 mouse_event_opaque =
616 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
617
618 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000619 if (graphic_rotate) {
620 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
621 width = 0x7fff;
622 else
aurel32b94ed572008-03-10 19:34:27 +0000623 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000624 mouse_event(mouse_event_opaque,
625 width - dy, dx, dz, buttons_state);
626 } else
627 mouse_event(mouse_event_opaque,
628 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000629 }
630}
631
bellard09b26c52006-04-12 21:09:08 +0000632int kbd_mouse_is_absolute(void)
633{
ths455204e2007-01-05 16:42:13 +0000634 if (!qemu_put_mouse_event_current)
635 return 0;
636
637 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
638}
639
640void do_info_mice(void)
641{
642 QEMUPutMouseEntry *cursor;
643 int index = 0;
644
645 if (!qemu_put_mouse_event_head) {
646 term_printf("No mouse devices connected\n");
647 return;
648 }
649
650 term_printf("Mouse devices available:\n");
651 cursor = qemu_put_mouse_event_head;
652 while (cursor != NULL) {
653 term_printf("%c Mouse #%d: %s\n",
654 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
655 index, cursor->qemu_put_mouse_event_name);
656 index++;
657 cursor = cursor->next;
658 }
659}
660
661void do_mouse_set(int index)
662{
663 QEMUPutMouseEntry *cursor;
664 int i = 0;
665
666 if (!qemu_put_mouse_event_head) {
667 term_printf("No mouse devices connected\n");
668 return;
669 }
670
671 cursor = qemu_put_mouse_event_head;
672 while (cursor != NULL && index != i) {
673 i++;
674 cursor = cursor->next;
675 }
676
677 if (cursor != NULL)
678 qemu_put_mouse_event_current = cursor;
679 else
680 term_printf("Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000681}
682
bellard87858c82003-06-27 12:01:39 +0000683/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000684uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000685{
686 union {
687 uint64_t ll;
688 struct {
689#ifdef WORDS_BIGENDIAN
690 uint32_t high, low;
691#else
692 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000693#endif
bellard87858c82003-06-27 12:01:39 +0000694 } l;
695 } u, res;
696 uint64_t rl, rh;
697
698 u.ll = a;
699 rl = (uint64_t)u.l.low * (uint64_t)b;
700 rh = (uint64_t)u.l.high * (uint64_t)b;
701 rh += (rl >> 32);
702 res.l.high = rh / c;
703 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
704 return res.ll;
705}
706
bellard1dce7c32006-07-13 23:20:22 +0000707/***********************************************************/
708/* real time host monotonic timer */
709
710#define QEMU_TIMER_BASE 1000000000LL
711
712#ifdef WIN32
713
714static int64_t clock_freq;
715
716static void init_get_clock(void)
717{
bellarda8e5ac32006-07-14 09:36:13 +0000718 LARGE_INTEGER freq;
719 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000720 ret = QueryPerformanceFrequency(&freq);
721 if (ret == 0) {
722 fprintf(stderr, "Could not calibrate ticks\n");
723 exit(1);
724 }
725 clock_freq = freq.QuadPart;
726}
727
728static int64_t get_clock(void)
729{
730 LARGE_INTEGER ti;
731 QueryPerformanceCounter(&ti);
732 return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
733}
734
735#else
736
737static int use_rt_clock;
738
739static void init_get_clock(void)
740{
741 use_rt_clock = 0;
aurel3260759372008-10-13 21:08:25 +0000742#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000)
bellard1dce7c32006-07-13 23:20:22 +0000743 {
744 struct timespec ts;
745 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
746 use_rt_clock = 1;
747 }
748 }
749#endif
750}
751
752static int64_t get_clock(void)
753{
aurel3260759372008-10-13 21:08:25 +0000754#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000)
bellard1dce7c32006-07-13 23:20:22 +0000755 if (use_rt_clock) {
756 struct timespec ts;
757 clock_gettime(CLOCK_MONOTONIC, &ts);
758 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000759 } else
bellard1dce7c32006-07-13 23:20:22 +0000760#endif
761 {
762 /* XXX: using gettimeofday leads to problems if the date
763 changes, so it should be avoided. */
764 struct timeval tv;
765 gettimeofday(&tv, NULL);
766 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
767 }
768}
bellard1dce7c32006-07-13 23:20:22 +0000769#endif
770
pbrook2e70f6e2008-06-29 01:03:05 +0000771/* Return the virtual CPU time, based on the instruction counter. */
772static int64_t cpu_get_icount(void)
773{
774 int64_t icount;
775 CPUState *env = cpu_single_env;;
776 icount = qemu_icount;
777 if (env) {
778 if (!can_do_io(env))
779 fprintf(stderr, "Bad clock read\n");
780 icount -= (env->icount_decr.u16.low + env->icount_extra);
781 }
782 return qemu_icount_bias + (icount << icount_time_shift);
783}
784
bellard1dce7c32006-07-13 23:20:22 +0000785/***********************************************************/
786/* guest cycle counter */
787
788static int64_t cpu_ticks_prev;
789static int64_t cpu_ticks_offset;
790static int64_t cpu_clock_offset;
791static int cpu_ticks_enabled;
792
793/* return the host CPU cycle counter and handle stop/restart */
794int64_t cpu_get_ticks(void)
795{
pbrook2e70f6e2008-06-29 01:03:05 +0000796 if (use_icount) {
797 return cpu_get_icount();
798 }
bellard1dce7c32006-07-13 23:20:22 +0000799 if (!cpu_ticks_enabled) {
800 return cpu_ticks_offset;
801 } else {
802 int64_t ticks;
803 ticks = cpu_get_real_ticks();
804 if (cpu_ticks_prev > ticks) {
805 /* Note: non increasing ticks may happen if the host uses
806 software suspend */
807 cpu_ticks_offset += cpu_ticks_prev - ticks;
808 }
809 cpu_ticks_prev = ticks;
810 return ticks + cpu_ticks_offset;
811 }
812}
813
814/* return the host CPU monotonic timer and handle stop/restart */
815static int64_t cpu_get_clock(void)
816{
817 int64_t ti;
818 if (!cpu_ticks_enabled) {
819 return cpu_clock_offset;
820 } else {
821 ti = get_clock();
822 return ti + cpu_clock_offset;
823 }
824}
825
826/* enable cpu_get_ticks() */
827void cpu_enable_ticks(void)
828{
829 if (!cpu_ticks_enabled) {
830 cpu_ticks_offset -= cpu_get_real_ticks();
831 cpu_clock_offset -= get_clock();
832 cpu_ticks_enabled = 1;
833 }
834}
835
836/* disable cpu_get_ticks() : the clock is stopped. You must not call
837 cpu_get_ticks() after that. */
838void cpu_disable_ticks(void)
839{
840 if (cpu_ticks_enabled) {
841 cpu_ticks_offset = cpu_get_ticks();
842 cpu_clock_offset = cpu_get_clock();
843 cpu_ticks_enabled = 0;
844 }
845}
846
847/***********************************************************/
848/* timers */
ths5fafdf22007-09-16 21:08:06 +0000849
bellard8a7ddc32004-03-31 19:00:16 +0000850#define QEMU_TIMER_REALTIME 0
851#define QEMU_TIMER_VIRTUAL 1
852
853struct QEMUClock {
854 int type;
855 /* XXX: add frequency */
856};
857
858struct QEMUTimer {
859 QEMUClock *clock;
860 int64_t expire_time;
861 QEMUTimerCB *cb;
862 void *opaque;
863 struct QEMUTimer *next;
864};
865
thsc8994012007-08-19 21:56:03 +0000866struct qemu_alarm_timer {
867 char const *name;
thsefe75412007-08-24 01:36:32 +0000868 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000869
870 int (*start)(struct qemu_alarm_timer *t);
871 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000872 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000873 void *priv;
874};
875
thsefe75412007-08-24 01:36:32 +0000876#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000877#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000878
879static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
880{
881 return t->flags & ALARM_FLAG_DYNTICKS;
882}
883
884static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
885{
886 if (!alarm_has_dynticks(t))
887 return;
888
889 t->rearm(t);
890}
891
892/* TODO: MIN_TIMER_REARM_US should be optimized */
893#define MIN_TIMER_REARM_US 250
894
thsc8994012007-08-19 21:56:03 +0000895static struct qemu_alarm_timer *alarm_timer;
aliguorif49e58d2008-11-05 21:22:34 +0000896#ifndef _WIN32
aliguoric96f1a42008-11-05 20:29:45 +0000897static int alarm_timer_rfd, alarm_timer_wfd;
aliguorif49e58d2008-11-05 21:22:34 +0000898#endif
thsc8994012007-08-19 21:56:03 +0000899
900#ifdef _WIN32
901
902struct qemu_alarm_win32 {
903 MMRESULT timerId;
904 HANDLE host_alarm;
905 unsigned int period;
906} alarm_win32_data = {0, NULL, -1};
907
908static int win32_start_timer(struct qemu_alarm_timer *t);
909static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000910static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000911
912#else
913
914static int unix_start_timer(struct qemu_alarm_timer *t);
915static void unix_stop_timer(struct qemu_alarm_timer *t);
916
ths231c6582007-08-26 17:29:15 +0000917#ifdef __linux__
918
thsefe75412007-08-24 01:36:32 +0000919static int dynticks_start_timer(struct qemu_alarm_timer *t);
920static void dynticks_stop_timer(struct qemu_alarm_timer *t);
921static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
922
thsc40ec5a2007-08-19 22:09:40 +0000923static int hpet_start_timer(struct qemu_alarm_timer *t);
924static void hpet_stop_timer(struct qemu_alarm_timer *t);
925
thsc8994012007-08-19 21:56:03 +0000926static int rtc_start_timer(struct qemu_alarm_timer *t);
927static void rtc_stop_timer(struct qemu_alarm_timer *t);
928
thsefe75412007-08-24 01:36:32 +0000929#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000930
931#endif /* _WIN32 */
932
pbrook2e70f6e2008-06-29 01:03:05 +0000933/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000934 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000935 When the guest is idle real and virtual time will be aligned in
936 the IO wait loop. */
937#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
938
939static void icount_adjust(void)
940{
941 int64_t cur_time;
942 int64_t cur_icount;
943 int64_t delta;
944 static int64_t last_delta;
945 /* If the VM is not running, then do nothing. */
946 if (!vm_running)
947 return;
948
949 cur_time = cpu_get_clock();
950 cur_icount = qemu_get_clock(vm_clock);
951 delta = cur_icount - cur_time;
952 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
953 if (delta > 0
954 && last_delta + ICOUNT_WOBBLE < delta * 2
955 && icount_time_shift > 0) {
956 /* The guest is getting too far ahead. Slow time down. */
957 icount_time_shift--;
958 }
959 if (delta < 0
960 && last_delta - ICOUNT_WOBBLE > delta * 2
961 && icount_time_shift < MAX_ICOUNT_SHIFT) {
962 /* The guest is getting too far behind. Speed time up. */
963 icount_time_shift++;
964 }
965 last_delta = delta;
966 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
967}
968
969static void icount_adjust_rt(void * opaque)
970{
971 qemu_mod_timer(icount_rt_timer,
972 qemu_get_clock(rt_clock) + 1000);
973 icount_adjust();
974}
975
976static void icount_adjust_vm(void * opaque)
977{
978 qemu_mod_timer(icount_vm_timer,
979 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
980 icount_adjust();
981}
982
983static void init_icount_adjust(void)
984{
985 /* Have both realtime and virtual time triggers for speed adjustment.
986 The realtime trigger catches emulated time passing too slowly,
987 the virtual time trigger catches emulated time passing too fast.
988 Realtime triggers occur even when idle, so use them less frequently
989 than VM triggers. */
990 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
991 qemu_mod_timer(icount_rt_timer,
992 qemu_get_clock(rt_clock) + 1000);
993 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
994 qemu_mod_timer(icount_vm_timer,
995 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
996}
997
thsc8994012007-08-19 21:56:03 +0000998static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000999#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +00001000#ifdef __linux__
thsefe75412007-08-24 01:36:32 +00001001 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
1002 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +00001003 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +00001004 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +00001005 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +00001006 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001007#endif
thsefe75412007-08-24 01:36:32 +00001008 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001009#else
thsefe75412007-08-24 01:36:32 +00001010 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
1011 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
1012 {"win32", 0, win32_start_timer,
1013 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +00001014#endif
1015 {NULL, }
1016};
1017
blueswir13f47aa82008-03-09 06:59:01 +00001018static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +00001019{
1020 int i;
1021
1022 printf("Available alarm timers, in order of precedence:\n");
1023 for (i = 0; alarm_timers[i].name; i++)
1024 printf("%s\n", alarm_timers[i].name);
1025}
1026
1027static void configure_alarms(char const *opt)
1028{
1029 int i;
1030 int cur = 0;
1031 int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
1032 char *arg;
1033 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +00001034 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +00001035
aurel323adda042008-03-09 23:43:49 +00001036 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +00001037 show_available_alarms();
1038 exit(0);
1039 }
1040
1041 arg = strdup(opt);
1042
1043 /* Reorder the array */
1044 name = strtok(arg, ",");
1045 while (name) {
balroge2b577e2007-09-17 21:25:20 +00001046 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +00001047 if (!strcmp(alarm_timers[i].name, name))
1048 break;
1049 }
1050
1051 if (i == count) {
1052 fprintf(stderr, "Unknown clock %s\n", name);
1053 goto next;
1054 }
1055
1056 if (i < cur)
1057 /* Ignore */
1058 goto next;
1059
1060 /* Swap */
1061 tmp = alarm_timers[i];
1062 alarm_timers[i] = alarm_timers[cur];
1063 alarm_timers[cur] = tmp;
1064
1065 cur++;
1066next:
1067 name = strtok(NULL, ",");
1068 }
1069
1070 free(arg);
1071
1072 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +00001073 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +00001074 for (i = cur; i < count; i++)
1075 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +00001076 } else {
1077 show_available_alarms();
1078 exit(1);
thsf3dcfad2007-08-24 01:26:02 +00001079 }
thsf3dcfad2007-08-24 01:26:02 +00001080}
1081
bellard8a7ddc32004-03-31 19:00:16 +00001082QEMUClock *rt_clock;
1083QEMUClock *vm_clock;
1084
1085static QEMUTimer *active_timers[2];
bellard8a7ddc32004-03-31 19:00:16 +00001086
pbrook9596ebb2007-11-18 01:44:38 +00001087static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +00001088{
1089 QEMUClock *clock;
1090 clock = qemu_mallocz(sizeof(QEMUClock));
1091 if (!clock)
1092 return NULL;
1093 clock->type = type;
1094 return clock;
1095}
1096
1097QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
1098{
1099 QEMUTimer *ts;
1100
1101 ts = qemu_mallocz(sizeof(QEMUTimer));
1102 ts->clock = clock;
1103 ts->cb = cb;
1104 ts->opaque = opaque;
1105 return ts;
1106}
1107
1108void qemu_free_timer(QEMUTimer *ts)
1109{
1110 qemu_free(ts);
1111}
1112
1113/* stop a timer, but do not dealloc it */
1114void qemu_del_timer(QEMUTimer *ts)
1115{
1116 QEMUTimer **pt, *t;
1117
1118 /* NOTE: this code must be signal safe because
1119 qemu_timer_expired() can be called from a signal. */
1120 pt = &active_timers[ts->clock->type];
1121 for(;;) {
1122 t = *pt;
1123 if (!t)
1124 break;
1125 if (t == ts) {
1126 *pt = t->next;
1127 break;
1128 }
1129 pt = &t->next;
1130 }
1131}
1132
1133/* modify the current timer so that it will be fired when current_time
1134 >= expire_time. The corresponding callback will be called. */
1135void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1136{
1137 QEMUTimer **pt, *t;
1138
1139 qemu_del_timer(ts);
1140
1141 /* add the timer in the sorted list */
1142 /* NOTE: this code must be signal safe because
1143 qemu_timer_expired() can be called from a signal. */
1144 pt = &active_timers[ts->clock->type];
1145 for(;;) {
1146 t = *pt;
1147 if (!t)
1148 break;
ths5fafdf22007-09-16 21:08:06 +00001149 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +00001150 break;
1151 pt = &t->next;
1152 }
1153 ts->expire_time = expire_time;
1154 ts->next = *pt;
1155 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +00001156
1157 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +00001158 if (pt == &active_timers[ts->clock->type]) {
1159 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
1160 qemu_rearm_alarm_timer(alarm_timer);
1161 }
1162 /* Interrupt execution to force deadline recalculation. */
1163 if (use_icount && cpu_single_env) {
1164 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1165 }
1166 }
bellard8a7ddc32004-03-31 19:00:16 +00001167}
1168
1169int qemu_timer_pending(QEMUTimer *ts)
1170{
1171 QEMUTimer *t;
1172 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1173 if (t == ts)
1174 return 1;
1175 }
1176 return 0;
1177}
1178
1179static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1180{
1181 if (!timer_head)
1182 return 0;
1183 return (timer_head->expire_time <= current_time);
1184}
1185
1186static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1187{
1188 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001189
bellard8a7ddc32004-03-31 19:00:16 +00001190 for(;;) {
1191 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001192 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001193 break;
1194 /* remove timer from the list before calling the callback */
1195 *ptimer_head = ts->next;
1196 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001197
bellard8a7ddc32004-03-31 19:00:16 +00001198 /* run the callback (the timer list can be modified) */
1199 ts->cb(ts->opaque);
1200 }
1201}
1202
1203int64_t qemu_get_clock(QEMUClock *clock)
1204{
1205 switch(clock->type) {
1206 case QEMU_TIMER_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001207 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001208 default:
1209 case QEMU_TIMER_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001210 if (use_icount) {
1211 return cpu_get_icount();
1212 } else {
1213 return cpu_get_clock();
1214 }
bellard8a7ddc32004-03-31 19:00:16 +00001215 }
1216}
1217
bellard1dce7c32006-07-13 23:20:22 +00001218static void init_timers(void)
1219{
1220 init_get_clock();
1221 ticks_per_sec = QEMU_TIMER_BASE;
1222 rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1223 vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1224}
1225
bellard8a7ddc32004-03-31 19:00:16 +00001226/* save a timer */
1227void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1228{
1229 uint64_t expire_time;
1230
1231 if (qemu_timer_pending(ts)) {
1232 expire_time = ts->expire_time;
1233 } else {
1234 expire_time = -1;
1235 }
1236 qemu_put_be64(f, expire_time);
1237}
1238
1239void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1240{
1241 uint64_t expire_time;
1242
1243 expire_time = qemu_get_be64(f);
1244 if (expire_time != -1) {
1245 qemu_mod_timer(ts, expire_time);
1246 } else {
1247 qemu_del_timer(ts);
1248 }
1249}
1250
1251static void timer_save(QEMUFile *f, void *opaque)
1252{
1253 if (cpu_ticks_enabled) {
1254 hw_error("cannot save state if virtual timers are running");
1255 }
thsbee8d682007-12-16 23:41:11 +00001256 qemu_put_be64(f, cpu_ticks_offset);
1257 qemu_put_be64(f, ticks_per_sec);
1258 qemu_put_be64(f, cpu_clock_offset);
bellard8a7ddc32004-03-31 19:00:16 +00001259}
1260
1261static int timer_load(QEMUFile *f, void *opaque, int version_id)
1262{
bellardc88676f2006-08-06 13:36:11 +00001263 if (version_id != 1 && version_id != 2)
bellard8a7ddc32004-03-31 19:00:16 +00001264 return -EINVAL;
1265 if (cpu_ticks_enabled) {
1266 return -EINVAL;
1267 }
thsbee8d682007-12-16 23:41:11 +00001268 cpu_ticks_offset=qemu_get_be64(f);
1269 ticks_per_sec=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001270 if (version_id == 2) {
thsbee8d682007-12-16 23:41:11 +00001271 cpu_clock_offset=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001272 }
bellard8a7ddc32004-03-31 19:00:16 +00001273 return 0;
1274}
1275
bellard67b915a2004-03-31 23:37:16 +00001276#ifdef _WIN32
ths5fafdf22007-09-16 21:08:06 +00001277void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
bellard67b915a2004-03-31 23:37:16 +00001278 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1279#else
bellard8a7ddc32004-03-31 19:00:16 +00001280static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001281#endif
bellard8a7ddc32004-03-31 19:00:16 +00001282{
bellard02ba45c2004-06-25 14:46:23 +00001283#if 0
1284#define DISP_FREQ 1000
1285 {
1286 static int64_t delta_min = INT64_MAX;
1287 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1288 static int count;
1289 ti = qemu_get_clock(vm_clock);
1290 if (last_clock != 0) {
1291 delta = ti - last_clock;
1292 if (delta < delta_min)
1293 delta_min = delta;
1294 if (delta > delta_max)
1295 delta_max = delta;
1296 delta_cum += delta;
1297 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001298 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
bellard02ba45c2004-06-25 14:46:23 +00001299 muldiv64(delta_min, 1000000, ticks_per_sec),
1300 muldiv64(delta_max, 1000000, ticks_per_sec),
1301 muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1302 (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1303 count = 0;
1304 delta_min = INT64_MAX;
1305 delta_max = 0;
1306 delta_cum = 0;
1307 }
1308 }
1309 last_clock = ti;
1310 }
1311#endif
thsefe75412007-08-24 01:36:32 +00001312 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001313 (!use_icount &&
1314 qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1315 qemu_get_clock(vm_clock))) ||
bellard8a7ddc32004-03-31 19:00:16 +00001316 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1317 qemu_get_clock(rt_clock))) {
aliguoric96f1a42008-11-05 20:29:45 +00001318 CPUState *env = next_cpu;
aliguoric96f1a42008-11-05 20:29:45 +00001319
bellard06d9f2f2006-05-01 13:23:04 +00001320#ifdef _WIN32
thsc8994012007-08-19 21:56:03 +00001321 struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1322 SetEvent(data->host_alarm);
aliguorif49e58d2008-11-05 21:22:34 +00001323#else
1324 static const char byte = 0;
aliguoric96f1a42008-11-05 20:29:45 +00001325 write(alarm_timer_wfd, &byte, sizeof(byte));
aliguorif49e58d2008-11-05 21:22:34 +00001326#endif
balrogd5d08332008-01-05 19:41:47 +00001327 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1328
balrog4f8eb8d2007-12-16 12:39:38 +00001329 if (env) {
1330 /* stop the currently executing cpu because a timer occured */
1331 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
bellarda332e112005-09-03 17:55:47 +00001332#ifdef USE_KQEMU
balrog4f8eb8d2007-12-16 12:39:38 +00001333 if (env->kqemu_enabled) {
1334 kqemu_cpu_interrupt(env);
1335 }
balrogee5605e2007-12-03 03:01:40 +00001336#endif
balrog4f8eb8d2007-12-16 12:39:38 +00001337 }
balrogee5605e2007-12-03 03:01:40 +00001338 event_pending = 1;
bellard8a7ddc32004-03-31 19:00:16 +00001339 }
1340}
1341
pbrook2e70f6e2008-06-29 01:03:05 +00001342static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001343{
pbrook2e70f6e2008-06-29 01:03:05 +00001344 int64_t delta;
thsefe75412007-08-24 01:36:32 +00001345
1346 if (active_timers[QEMU_TIMER_VIRTUAL]) {
pbrook2e70f6e2008-06-29 01:03:05 +00001347 delta = active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1348 qemu_get_clock(vm_clock);
1349 } else {
1350 /* To avoid problems with overflow limit this to 2^32. */
1351 delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001352 }
1353
pbrook2e70f6e2008-06-29 01:03:05 +00001354 if (delta < 0)
1355 delta = 0;
thsefe75412007-08-24 01:36:32 +00001356
pbrook2e70f6e2008-06-29 01:03:05 +00001357 return delta;
1358}
1359
blueswir18632fb92008-09-14 13:59:34 +00001360#if defined(__linux__) || defined(_WIN32)
pbrook2e70f6e2008-06-29 01:03:05 +00001361static uint64_t qemu_next_deadline_dyntick(void)
1362{
1363 int64_t delta;
1364 int64_t rtdelta;
1365
1366 if (use_icount)
1367 delta = INT32_MAX;
1368 else
1369 delta = (qemu_next_deadline() + 999) / 1000;
1370
1371 if (active_timers[QEMU_TIMER_REALTIME]) {
1372 rtdelta = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
1373 qemu_get_clock(rt_clock))*1000;
1374 if (rtdelta < delta)
1375 delta = rtdelta;
1376 }
1377
1378 if (delta < MIN_TIMER_REARM_US)
1379 delta = MIN_TIMER_REARM_US;
1380
1381 return delta;
thsefe75412007-08-24 01:36:32 +00001382}
blueswir18632fb92008-09-14 13:59:34 +00001383#endif
thsefe75412007-08-24 01:36:32 +00001384
bellardfd872592004-05-12 19:11:15 +00001385#ifndef _WIN32
1386
aliguori7183b4b2008-11-05 20:40:18 +00001387/* Sets a specific flag */
1388static int fcntl_setfl(int fd, int flag)
1389{
1390 int flags;
1391
1392 flags = fcntl(fd, F_GETFL);
1393 if (flags == -1)
1394 return -errno;
1395
1396 if (fcntl(fd, F_SETFL, flags | flag) == -1)
1397 return -errno;
1398
1399 return 0;
1400}
1401
bellard829309c2004-05-20 13:20:12 +00001402#if defined(__linux__)
1403
bellardfd872592004-05-12 19:11:15 +00001404#define RTC_FREQ 1024
1405
aurel32de9a95f2008-11-11 13:41:01 +00001406static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001407{
thsc8994012007-08-19 21:56:03 +00001408 struct sigaction act;
1409
1410 /* timer signal */
1411 sigfillset(&act.sa_mask);
1412 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001413 act.sa_handler = host_alarm_handler;
1414
1415 sigaction(SIGIO, &act, NULL);
aliguori7183b4b2008-11-05 20:40:18 +00001416 fcntl_setfl(fd, O_ASYNC);
thsc8994012007-08-19 21:56:03 +00001417 fcntl(fd, F_SETOWN, getpid());
1418}
1419
thsc40ec5a2007-08-19 22:09:40 +00001420static int hpet_start_timer(struct qemu_alarm_timer *t)
1421{
1422 struct hpet_info info;
1423 int r, fd;
1424
1425 fd = open("/dev/hpet", O_RDONLY);
1426 if (fd < 0)
1427 return -1;
1428
1429 /* Set frequency */
1430 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1431 if (r < 0) {
1432 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1433 "error, but for better emulation accuracy type:\n"
1434 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1435 goto fail;
1436 }
1437
1438 /* Check capabilities */
1439 r = ioctl(fd, HPET_INFO, &info);
1440 if (r < 0)
1441 goto fail;
1442
1443 /* Enable periodic mode */
1444 r = ioctl(fd, HPET_EPI, 0);
1445 if (info.hi_flags && (r < 0))
1446 goto fail;
1447
1448 /* Enable interrupt */
1449 r = ioctl(fd, HPET_IE_ON, 0);
1450 if (r < 0)
1451 goto fail;
1452
1453 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001454 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001455
1456 return 0;
1457fail:
1458 close(fd);
1459 return -1;
1460}
1461
1462static void hpet_stop_timer(struct qemu_alarm_timer *t)
1463{
pbrookfcdc2122007-08-23 20:22:22 +00001464 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001465
1466 close(fd);
1467}
1468
thsc8994012007-08-19 21:56:03 +00001469static int rtc_start_timer(struct qemu_alarm_timer *t)
1470{
1471 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001472 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001473
balrogaeb30be2007-07-02 15:03:13 +00001474 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001475 if (rtc_fd < 0)
1476 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001477 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1478 if (current_rtc_freq != RTC_FREQ &&
1479 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001480 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1481 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1482 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1483 goto fail;
1484 }
1485 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1486 fail:
1487 close(rtc_fd);
1488 return -1;
1489 }
thsc8994012007-08-19 21:56:03 +00001490
1491 enable_sigio_timer(rtc_fd);
1492
pbrookfcdc2122007-08-23 20:22:22 +00001493 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001494
bellardfd872592004-05-12 19:11:15 +00001495 return 0;
1496}
1497
thsc8994012007-08-19 21:56:03 +00001498static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001499{
pbrookfcdc2122007-08-23 20:22:22 +00001500 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001501
1502 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001503}
1504
thsefe75412007-08-24 01:36:32 +00001505static int dynticks_start_timer(struct qemu_alarm_timer *t)
1506{
1507 struct sigevent ev;
1508 timer_t host_timer;
1509 struct sigaction act;
1510
1511 sigfillset(&act.sa_mask);
1512 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001513 act.sa_handler = host_alarm_handler;
1514
1515 sigaction(SIGALRM, &act, NULL);
1516
1517 ev.sigev_value.sival_int = 0;
1518 ev.sigev_notify = SIGEV_SIGNAL;
1519 ev.sigev_signo = SIGALRM;
1520
1521 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1522 perror("timer_create");
1523
1524 /* disable dynticks */
1525 fprintf(stderr, "Dynamic Ticks disabled\n");
1526
1527 return -1;
1528 }
1529
1530 t->priv = (void *)host_timer;
1531
1532 return 0;
1533}
1534
1535static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1536{
1537 timer_t host_timer = (timer_t)t->priv;
1538
1539 timer_delete(host_timer);
1540}
1541
1542static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1543{
1544 timer_t host_timer = (timer_t)t->priv;
1545 struct itimerspec timeout;
1546 int64_t nearest_delta_us = INT64_MAX;
1547 int64_t current_us;
1548
1549 if (!active_timers[QEMU_TIMER_REALTIME] &&
1550 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001551 return;
thsefe75412007-08-24 01:36:32 +00001552
pbrook2e70f6e2008-06-29 01:03:05 +00001553 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001554
1555 /* check whether a timer is already running */
1556 if (timer_gettime(host_timer, &timeout)) {
1557 perror("gettime");
1558 fprintf(stderr, "Internal timer error: aborting\n");
1559 exit(1);
1560 }
1561 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1562 if (current_us && current_us <= nearest_delta_us)
1563 return;
1564
1565 timeout.it_interval.tv_sec = 0;
1566 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1567 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1568 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1569 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1570 perror("settime");
1571 fprintf(stderr, "Internal timer error: aborting\n");
1572 exit(1);
1573 }
1574}
1575
ths70744b32007-08-26 17:31:30 +00001576#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001577
thsc8994012007-08-19 21:56:03 +00001578static int unix_start_timer(struct qemu_alarm_timer *t)
1579{
1580 struct sigaction act;
1581 struct itimerval itv;
1582 int err;
1583
1584 /* timer signal */
1585 sigfillset(&act.sa_mask);
1586 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001587 act.sa_handler = host_alarm_handler;
1588
1589 sigaction(SIGALRM, &act, NULL);
1590
1591 itv.it_interval.tv_sec = 0;
1592 /* for i386 kernel 2.6 to get 1 ms */
1593 itv.it_interval.tv_usec = 999;
1594 itv.it_value.tv_sec = 0;
1595 itv.it_value.tv_usec = 10 * 1000;
1596
1597 err = setitimer(ITIMER_REAL, &itv, NULL);
1598 if (err)
1599 return -1;
1600
1601 return 0;
1602}
1603
1604static void unix_stop_timer(struct qemu_alarm_timer *t)
1605{
1606 struct itimerval itv;
1607
1608 memset(&itv, 0, sizeof(itv));
1609 setitimer(ITIMER_REAL, &itv, NULL);
1610}
1611
bellard829309c2004-05-20 13:20:12 +00001612#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001613
aliguorif49e58d2008-11-05 21:22:34 +00001614static void try_to_rearm_timer(void *opaque)
1615{
1616 struct qemu_alarm_timer *t = opaque;
1617#ifndef _WIN32
1618 ssize_t len;
1619
1620 /* Drain the notify pipe */
1621 do {
1622 char buffer[512];
1623 len = read(alarm_timer_rfd, buffer, sizeof(buffer));
1624 } while ((len == -1 && errno == EINTR) || len > 0);
1625#endif
1626
1627 /* vm time timers */
1628 if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
1629 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
1630 qemu_get_clock(vm_clock));
1631
1632 /* real time timers */
1633 qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
1634 qemu_get_clock(rt_clock));
1635
1636 if (t->flags & ALARM_FLAG_EXPIRED) {
1637 alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
1638 qemu_rearm_alarm_timer(alarm_timer);
1639 }
1640}
1641
thsc8994012007-08-19 21:56:03 +00001642#ifdef _WIN32
1643
1644static int win32_start_timer(struct qemu_alarm_timer *t)
1645{
1646 TIMECAPS tc;
1647 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001648 UINT flags;
thsc8994012007-08-19 21:56:03 +00001649
1650 data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1651 if (!data->host_alarm) {
1652 perror("Failed CreateEvent");
thsc396a7f2007-08-20 15:42:22 +00001653 return -1;
thsc8994012007-08-19 21:56:03 +00001654 }
1655
1656 memset(&tc, 0, sizeof(tc));
1657 timeGetDevCaps(&tc, sizeof(tc));
1658
1659 if (data->period < tc.wPeriodMin)
1660 data->period = tc.wPeriodMin;
1661
1662 timeBeginPeriod(data->period);
1663
thsefe75412007-08-24 01:36:32 +00001664 flags = TIME_CALLBACK_FUNCTION;
1665 if (alarm_has_dynticks(t))
1666 flags |= TIME_ONESHOT;
1667 else
1668 flags |= TIME_PERIODIC;
1669
thsc8994012007-08-19 21:56:03 +00001670 data->timerId = timeSetEvent(1, // interval (ms)
1671 data->period, // resolution
1672 host_alarm_handler, // function
1673 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001674 flags);
thsc8994012007-08-19 21:56:03 +00001675
1676 if (!data->timerId) {
1677 perror("Failed to initialize win32 alarm timer");
1678
1679 timeEndPeriod(data->period);
1680 CloseHandle(data->host_alarm);
1681 return -1;
1682 }
1683
aliguorif49e58d2008-11-05 21:22:34 +00001684 qemu_add_wait_object(data->host_alarm, try_to_rearm_timer, t);
thsc8994012007-08-19 21:56:03 +00001685
1686 return 0;
1687}
1688
1689static void win32_stop_timer(struct qemu_alarm_timer *t)
1690{
1691 struct qemu_alarm_win32 *data = t->priv;
1692
1693 timeKillEvent(data->timerId);
1694 timeEndPeriod(data->period);
1695
1696 CloseHandle(data->host_alarm);
1697}
1698
thsefe75412007-08-24 01:36:32 +00001699static void win32_rearm_timer(struct qemu_alarm_timer *t)
1700{
1701 struct qemu_alarm_win32 *data = t->priv;
1702 uint64_t nearest_delta_us;
1703
1704 if (!active_timers[QEMU_TIMER_REALTIME] &&
1705 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001706 return;
thsefe75412007-08-24 01:36:32 +00001707
pbrook2e70f6e2008-06-29 01:03:05 +00001708 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001709 nearest_delta_us /= 1000;
1710
1711 timeKillEvent(data->timerId);
1712
1713 data->timerId = timeSetEvent(1,
1714 data->period,
1715 host_alarm_handler,
1716 (DWORD)t,
1717 TIME_ONESHOT | TIME_PERIODIC);
1718
1719 if (!data->timerId) {
1720 perror("Failed to re-arm win32 alarm timer");
1721
1722 timeEndPeriod(data->period);
1723 CloseHandle(data->host_alarm);
1724 exit(1);
1725 }
1726}
1727
thsc8994012007-08-19 21:56:03 +00001728#endif /* _WIN32 */
1729
aliguori7183b4b2008-11-05 20:40:18 +00001730static int init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001731{
blueswir1223f0d72008-09-30 18:12:18 +00001732 struct qemu_alarm_timer *t = NULL;
thsc8994012007-08-19 21:56:03 +00001733 int i, err = -1;
aliguorif49e58d2008-11-05 21:22:34 +00001734
1735#ifndef _WIN32
aliguoric96f1a42008-11-05 20:29:45 +00001736 int fds[2];
1737
aliguori7183b4b2008-11-05 20:40:18 +00001738 err = pipe(fds);
1739 if (err == -1)
1740 return -errno;
1741
1742 err = fcntl_setfl(fds[0], O_NONBLOCK);
1743 if (err < 0)
1744 goto fail;
1745
1746 err = fcntl_setfl(fds[1], O_NONBLOCK);
1747 if (err < 0)
1748 goto fail;
1749
aliguoric96f1a42008-11-05 20:29:45 +00001750 alarm_timer_rfd = fds[0];
1751 alarm_timer_wfd = fds[1];
aliguorif49e58d2008-11-05 21:22:34 +00001752#endif
bellard06d9f2f2006-05-01 13:23:04 +00001753
thsc8994012007-08-19 21:56:03 +00001754 for (i = 0; alarm_timers[i].name; i++) {
1755 t = &alarm_timers[i];
1756
thsc8994012007-08-19 21:56:03 +00001757 err = t->start(t);
1758 if (!err)
1759 break;
bellard67b915a2004-03-31 23:37:16 +00001760 }
bellardfd872592004-05-12 19:11:15 +00001761
thsc8994012007-08-19 21:56:03 +00001762 if (err) {
aliguori7183b4b2008-11-05 20:40:18 +00001763 err = -ENOENT;
1764 goto fail;
bellard67b915a2004-03-31 23:37:16 +00001765 }
thsc8994012007-08-19 21:56:03 +00001766
aliguorif49e58d2008-11-05 21:22:34 +00001767#ifndef _WIN32
aliguori6abfbd72008-11-05 20:49:37 +00001768 qemu_set_fd_handler2(alarm_timer_rfd, NULL,
1769 try_to_rearm_timer, NULL, t);
aliguorif49e58d2008-11-05 21:22:34 +00001770#endif
aliguori6abfbd72008-11-05 20:49:37 +00001771
thsc8994012007-08-19 21:56:03 +00001772 alarm_timer = t;
aliguori7183b4b2008-11-05 20:40:18 +00001773
aliguori6abfbd72008-11-05 20:49:37 +00001774 return 0;
aliguori7183b4b2008-11-05 20:40:18 +00001775
1776fail:
aliguorif49e58d2008-11-05 21:22:34 +00001777#ifndef _WIN32
aliguori7183b4b2008-11-05 20:40:18 +00001778 close(fds[0]);
1779 close(fds[1]);
aliguorif49e58d2008-11-05 21:22:34 +00001780#endif
aliguori7183b4b2008-11-05 20:40:18 +00001781 return err;
bellard8a7ddc32004-03-31 19:00:16 +00001782}
1783
pbrook9596ebb2007-11-18 01:44:38 +00001784static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001785{
thsc8994012007-08-19 21:56:03 +00001786 alarm_timer->stop(alarm_timer);
1787 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001788}
1789
bellardc4b1fcc2004-03-14 21:44:30 +00001790/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001791/* host time/date access */
1792void qemu_get_timedate(struct tm *tm, int offset)
1793{
1794 time_t ti;
1795 struct tm *ret;
1796
1797 time(&ti);
1798 ti += offset;
1799 if (rtc_date_offset == -1) {
1800 if (rtc_utc)
1801 ret = gmtime(&ti);
1802 else
1803 ret = localtime(&ti);
1804 } else {
1805 ti -= rtc_date_offset;
1806 ret = gmtime(&ti);
1807 }
1808
1809 memcpy(tm, ret, sizeof(struct tm));
1810}
1811
1812int qemu_timedate_diff(struct tm *tm)
1813{
1814 time_t seconds;
1815
1816 if (rtc_date_offset == -1)
1817 if (rtc_utc)
1818 seconds = mktimegm(tm);
1819 else
1820 seconds = mktime(tm);
1821 else
1822 seconds = mktimegm(tm) + rtc_date_offset;
1823
1824 return seconds - time(NULL);
1825}
1826
bellardfd1dff42006-02-01 21:29:26 +00001827#ifdef _WIN32
bellardfd1dff42006-02-01 21:29:26 +00001828static void socket_cleanup(void)
1829{
1830 WSACleanup();
1831}
bellard82c643f2004-07-14 17:28:13 +00001832
bellardfd1dff42006-02-01 21:29:26 +00001833static int socket_init(void)
1834{
1835 WSADATA Data;
1836 int ret, err;
1837
1838 ret = WSAStartup(MAKEWORD(2,2), &Data);
1839 if (ret != 0) {
1840 err = WSAGetLastError();
1841 fprintf(stderr, "WSAStartup: %d\n", err);
1842 return -1;
1843 }
1844 atexit(socket_cleanup);
1845 return 0;
1846}
aurel3264b7b732008-05-05 10:05:31 +00001847#endif
1848
aliguori63a01ef2008-10-31 19:10:00 +00001849const char *get_opt_name(char *buf, int buf_size, const char *p)
thse4bcb142007-12-02 04:51:10 +00001850{
1851 char *q;
thse4bcb142007-12-02 04:51:10 +00001852
balrog609497a2008-01-14 02:56:53 +00001853 q = buf;
1854 while (*p != '\0' && *p != '=') {
1855 if (q && (q - buf) < buf_size - 1)
1856 *q++ = *p;
1857 p++;
1858 }
1859 if (q)
1860 *q = '\0';
1861
1862 return p;
1863}
1864
aliguori63a01ef2008-10-31 19:10:00 +00001865const char *get_opt_value(char *buf, int buf_size, const char *p)
balrog609497a2008-01-14 02:56:53 +00001866{
1867 char *q;
1868
thse4bcb142007-12-02 04:51:10 +00001869 q = buf;
1870 while (*p != '\0') {
balrog609497a2008-01-14 02:56:53 +00001871 if (*p == ',') {
1872 if (*(p + 1) != ',')
thse4bcb142007-12-02 04:51:10 +00001873 break;
thse4bcb142007-12-02 04:51:10 +00001874 p++;
balrog609497a2008-01-14 02:56:53 +00001875 }
thse4bcb142007-12-02 04:51:10 +00001876 if (q && (q - buf) < buf_size - 1)
1877 *q++ = *p;
1878 p++;
1879 }
1880 if (q)
1881 *q = '\0';
1882
1883 return p;
1884}
1885
aliguori63a01ef2008-10-31 19:10:00 +00001886int get_param_value(char *buf, int buf_size,
1887 const char *tag, const char *str)
bellard7c9d8e02005-11-15 22:16:05 +00001888{
1889 const char *p;
bellard7c9d8e02005-11-15 22:16:05 +00001890 char option[128];
1891
1892 p = str;
1893 for(;;) {
balrog609497a2008-01-14 02:56:53 +00001894 p = get_opt_name(option, sizeof(option), p);
bellard7c9d8e02005-11-15 22:16:05 +00001895 if (*p != '=')
1896 break;
1897 p++;
1898 if (!strcmp(tag, option)) {
balrog609497a2008-01-14 02:56:53 +00001899 (void)get_opt_value(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00001900 return strlen(buf);
bellard7c9d8e02005-11-15 22:16:05 +00001901 } else {
balrog609497a2008-01-14 02:56:53 +00001902 p = get_opt_value(NULL, 0, p);
bellard7c9d8e02005-11-15 22:16:05 +00001903 }
1904 if (*p != ',')
1905 break;
1906 p++;
1907 }
1908 return 0;
1909}
1910
aliguori63a01ef2008-10-31 19:10:00 +00001911int check_params(char *buf, int buf_size,
1912 const char * const *params, const char *str)
thse4bcb142007-12-02 04:51:10 +00001913{
1914 const char *p;
1915 int i;
1916
1917 p = str;
1918 for(;;) {
balrog609497a2008-01-14 02:56:53 +00001919 p = get_opt_name(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00001920 if (*p != '=')
1921 return -1;
1922 p++;
1923 for(i = 0; params[i] != NULL; i++)
1924 if (!strcmp(params[i], buf))
1925 break;
1926 if (params[i] == NULL)
1927 return -1;
balrog609497a2008-01-14 02:56:53 +00001928 p = get_opt_value(NULL, 0, p);
thse4bcb142007-12-02 04:51:10 +00001929 if (*p != ',')
1930 break;
1931 p++;
1932 }
1933 return 0;
1934}
1935
balrog1ae26a12008-09-28 23:19:47 +00001936/***********************************************************/
1937/* Bluetooth support */
1938static int nb_hcis;
1939static int cur_hci;
1940static struct HCIInfo *hci_table[MAX_NICS];
balrogdc72ac12008-11-09 00:04:26 +00001941
balrog1ae26a12008-09-28 23:19:47 +00001942static struct bt_vlan_s {
1943 struct bt_scatternet_s net;
1944 int id;
1945 struct bt_vlan_s *next;
1946} *first_bt_vlan;
1947
1948/* find or alloc a new bluetooth "VLAN" */
blueswir1674bb262008-09-30 18:18:27 +00001949static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
balrog1ae26a12008-09-28 23:19:47 +00001950{
1951 struct bt_vlan_s **pvlan, *vlan;
1952 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
1953 if (vlan->id == id)
1954 return &vlan->net;
1955 }
1956 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
1957 vlan->id = id;
1958 pvlan = &first_bt_vlan;
1959 while (*pvlan != NULL)
1960 pvlan = &(*pvlan)->next;
1961 *pvlan = vlan;
1962 return &vlan->net;
1963}
1964
1965static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
1966{
1967}
1968
1969static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
1970{
1971 return -ENOTSUP;
1972}
1973
1974static struct HCIInfo null_hci = {
1975 .cmd_send = null_hci_send,
1976 .sco_send = null_hci_send,
1977 .acl_send = null_hci_send,
1978 .bdaddr_set = null_hci_addr_set,
1979};
1980
1981struct HCIInfo *qemu_next_hci(void)
1982{
1983 if (cur_hci == nb_hcis)
1984 return &null_hci;
1985
1986 return hci_table[cur_hci++];
1987}
1988
balrogdc72ac12008-11-09 00:04:26 +00001989static struct HCIInfo *hci_init(const char *str)
1990{
1991 char *endp;
1992 struct bt_scatternet_s *vlan = 0;
1993
1994 if (!strcmp(str, "null"))
1995 /* null */
1996 return &null_hci;
1997 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
1998 /* host[:hciN] */
1999 return bt_host_hci(str[4] ? str + 5 : "hci0");
2000 else if (!strncmp(str, "hci", 3)) {
2001 /* hci[,vlan=n] */
2002 if (str[3]) {
2003 if (!strncmp(str + 3, ",vlan=", 6)) {
2004 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
2005 if (*endp)
2006 vlan = 0;
2007 }
2008 } else
2009 vlan = qemu_find_bt_vlan(0);
2010 if (vlan)
2011 return bt_new_hci(vlan);
2012 }
2013
2014 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
2015
2016 return 0;
2017}
2018
2019static int bt_hci_parse(const char *str)
2020{
2021 struct HCIInfo *hci;
2022 bdaddr_t bdaddr;
2023
2024 if (nb_hcis >= MAX_NICS) {
2025 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
2026 return -1;
2027 }
2028
2029 hci = hci_init(str);
2030 if (!hci)
2031 return -1;
2032
2033 bdaddr.b[0] = 0x52;
2034 bdaddr.b[1] = 0x54;
2035 bdaddr.b[2] = 0x00;
2036 bdaddr.b[3] = 0x12;
2037 bdaddr.b[4] = 0x34;
2038 bdaddr.b[5] = 0x56 + nb_hcis;
2039 hci->bdaddr_set(hci, bdaddr.b);
2040
2041 hci_table[nb_hcis++] = hci;
2042
2043 return 0;
2044}
2045
2046static void bt_vhci_add(int vlan_id)
2047{
2048 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
2049
2050 if (!vlan->slave)
2051 fprintf(stderr, "qemu: warning: adding a VHCI to "
2052 "an empty scatternet %i\n", vlan_id);
2053
2054 bt_vhci_init(bt_new_hci(vlan));
2055}
2056
2057static struct bt_device_s *bt_device_add(const char *opt)
2058{
2059 struct bt_scatternet_s *vlan;
2060 int vlan_id = 0;
2061 char *endp = strstr(opt, ",vlan=");
2062 int len = (endp ? endp - opt : strlen(opt)) + 1;
2063 char devname[10];
2064
2065 pstrcpy(devname, MIN(sizeof(devname), len), opt);
2066
2067 if (endp) {
2068 vlan_id = strtol(endp + 6, &endp, 0);
2069 if (*endp) {
2070 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
2071 return 0;
2072 }
2073 }
2074
2075 vlan = qemu_find_bt_vlan(vlan_id);
2076
2077 if (!vlan->slave)
2078 fprintf(stderr, "qemu: warning: adding a slave device to "
2079 "an empty scatternet %i\n", vlan_id);
2080
2081 if (!strcmp(devname, "keyboard"))
2082 return bt_keyboard_init(vlan);
2083
2084 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
2085 return 0;
2086}
2087
2088static int bt_parse(const char *opt)
2089{
2090 const char *endp, *p;
2091 int vlan;
2092
2093 if (strstart(opt, "hci", &endp)) {
2094 if (!*endp || *endp == ',') {
2095 if (*endp)
2096 if (!strstart(endp, ",vlan=", 0))
2097 opt = endp + 1;
2098
2099 return bt_hci_parse(opt);
2100 }
2101 } else if (strstart(opt, "vhci", &endp)) {
2102 if (!*endp || *endp == ',') {
2103 if (*endp) {
2104 if (strstart(endp, ",vlan=", &p)) {
2105 vlan = strtol(p, (char **) &endp, 0);
2106 if (*endp) {
2107 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
2108 return 1;
2109 }
2110 } else {
2111 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
2112 return 1;
2113 }
2114 } else
2115 vlan = 0;
2116
2117 bt_vhci_add(vlan);
2118 return 0;
2119 }
2120 } else if (strstart(opt, "device:", &endp))
2121 return !bt_device_add(endp);
2122
2123 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
2124 return 1;
2125}
2126
balrog1ae26a12008-09-28 23:19:47 +00002127/***********************************************************/
2128/* QEMU Block devices */
2129
balrog609497a2008-01-14 02:56:53 +00002130#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00002131#ifdef TARGET_PPC
2132#define CDROM_ALIAS "index=1,media=cdrom"
2133#else
2134#define CDROM_ALIAS "index=2,media=cdrom"
2135#endif
2136#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00002137#define PFLASH_ALIAS "if=pflash"
2138#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00002139#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00002140
balrog609497a2008-01-14 02:56:53 +00002141static int drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00002142{
2143 va_list ap;
2144
2145 if (nb_drives_opt >= MAX_DRIVES) {
2146 fprintf(stderr, "qemu: too many drives\n");
2147 exit(1);
2148 }
2149
balrog609497a2008-01-14 02:56:53 +00002150 drives_opt[nb_drives_opt].file = file;
thse4bcb142007-12-02 04:51:10 +00002151 va_start(ap, fmt);
balrog609497a2008-01-14 02:56:53 +00002152 vsnprintf(drives_opt[nb_drives_opt].opt,
2153 sizeof(drives_opt[0].opt), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00002154 va_end(ap);
2155
2156 return nb_drives_opt++;
2157}
2158
thsf60d39b2007-12-17 03:55:57 +00002159int drive_get_index(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00002160{
2161 int index;
2162
2163 /* seek interface, bus and unit */
2164
2165 for (index = 0; index < nb_drives; index++)
thsf60d39b2007-12-17 03:55:57 +00002166 if (drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00002167 drives_table[index].bus == bus &&
2168 drives_table[index].unit == unit)
2169 return index;
2170
2171 return -1;
2172}
2173
thsf60d39b2007-12-17 03:55:57 +00002174int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00002175{
2176 int max_bus;
2177 int index;
2178
2179 max_bus = -1;
2180 for (index = 0; index < nb_drives; index++) {
thsf60d39b2007-12-17 03:55:57 +00002181 if(drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00002182 drives_table[index].bus > max_bus)
2183 max_bus = drives_table[index].bus;
2184 }
2185 return max_bus;
2186}
2187
aurel32a1620fa2008-04-29 05:58:01 +00002188static void bdrv_format_print(void *opaque, const char *name)
2189{
2190 fprintf(stderr, " %s", name);
2191}
2192
balrog609497a2008-01-14 02:56:53 +00002193static int drive_init(struct drive_opt *arg, int snapshot,
2194 QEMUMachine *machine)
thse4bcb142007-12-02 04:51:10 +00002195{
2196 char buf[128];
2197 char file[1024];
balrogc8522bd2007-12-06 22:11:20 +00002198 char devname[128];
2199 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00002200 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00002201 enum { MEDIA_DISK, MEDIA_CDROM } media;
2202 int bus_id, unit_id;
2203 int cyls, heads, secs, translation;
2204 BlockDriverState *bdrv;
aurel321e72d3b2008-04-28 20:26:45 +00002205 BlockDriver *drv = NULL;
thse4bcb142007-12-02 04:51:10 +00002206 int max_devs;
2207 int index;
balrog33f00272007-12-24 14:33:24 +00002208 int cache;
2209 int bdrv_flags;
balrog609497a2008-01-14 02:56:53 +00002210 char *str = arg->opt;
blueswir17ccfb2e2008-09-14 06:45:34 +00002211 static const char * const params[] = { "bus", "unit", "if", "index",
2212 "cyls", "heads", "secs", "trans",
2213 "media", "snapshot", "file",
2214 "cache", "format", NULL };
thse4bcb142007-12-02 04:51:10 +00002215
2216 if (check_params(buf, sizeof(buf), params, str) < 0) {
balrogff993632008-02-10 13:21:25 +00002217 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
thse4bcb142007-12-02 04:51:10 +00002218 buf, str);
2219 return -1;
2220 }
2221
2222 file[0] = 0;
2223 cyls = heads = secs = 0;
2224 bus_id = 0;
2225 unit_id = -1;
2226 translation = BIOS_ATA_TRANSLATION_AUTO;
2227 index = -1;
balrog33f00272007-12-24 14:33:24 +00002228 cache = 1;
thse4bcb142007-12-02 04:51:10 +00002229
blueswir1c9b1ae22008-09-28 18:55:17 +00002230 if (machine->use_scsi) {
thsf60d39b2007-12-17 03:55:57 +00002231 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002232 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002233 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00002234 } else {
thsf60d39b2007-12-17 03:55:57 +00002235 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002236 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00002237 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00002238 }
2239 media = MEDIA_DISK;
2240
2241 /* extract parameters */
2242
2243 if (get_param_value(buf, sizeof(buf), "bus", str)) {
2244 bus_id = strtol(buf, NULL, 0);
2245 if (bus_id < 0) {
2246 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
2247 return -1;
2248 }
2249 }
2250
2251 if (get_param_value(buf, sizeof(buf), "unit", str)) {
2252 unit_id = strtol(buf, NULL, 0);
2253 if (unit_id < 0) {
2254 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
2255 return -1;
2256 }
2257 }
2258
2259 if (get_param_value(buf, sizeof(buf), "if", str)) {
bellardae45d362008-06-11 09:44:44 +00002260 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00002261 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00002262 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00002263 max_devs = MAX_IDE_DEVS;
2264 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00002265 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00002266 max_devs = MAX_SCSI_DEVS;
2267 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00002268 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00002269 max_devs = 0;
2270 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00002271 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00002272 max_devs = 0;
2273 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00002274 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00002275 max_devs = 0;
2276 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00002277 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00002278 max_devs = 0;
2279 } else {
2280 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
2281 return -1;
2282 }
2283 }
2284
2285 if (get_param_value(buf, sizeof(buf), "index", str)) {
2286 index = strtol(buf, NULL, 0);
2287 if (index < 0) {
2288 fprintf(stderr, "qemu: '%s' invalid index\n", str);
2289 return -1;
2290 }
2291 }
2292
2293 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
2294 cyls = strtol(buf, NULL, 0);
2295 }
2296
2297 if (get_param_value(buf, sizeof(buf), "heads", str)) {
2298 heads = strtol(buf, NULL, 0);
2299 }
2300
2301 if (get_param_value(buf, sizeof(buf), "secs", str)) {
2302 secs = strtol(buf, NULL, 0);
2303 }
2304
2305 if (cyls || heads || secs) {
2306 if (cyls < 1 || cyls > 16383) {
2307 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
2308 return -1;
2309 }
2310 if (heads < 1 || heads > 16) {
2311 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
2312 return -1;
2313 }
2314 if (secs < 1 || secs > 63) {
2315 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
2316 return -1;
2317 }
2318 }
2319
2320 if (get_param_value(buf, sizeof(buf), "trans", str)) {
2321 if (!cyls) {
2322 fprintf(stderr,
2323 "qemu: '%s' trans must be used with cyls,heads and secs\n",
2324 str);
2325 return -1;
2326 }
2327 if (!strcmp(buf, "none"))
2328 translation = BIOS_ATA_TRANSLATION_NONE;
2329 else if (!strcmp(buf, "lba"))
2330 translation = BIOS_ATA_TRANSLATION_LBA;
2331 else if (!strcmp(buf, "auto"))
2332 translation = BIOS_ATA_TRANSLATION_AUTO;
2333 else {
2334 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
2335 return -1;
2336 }
2337 }
2338
2339 if (get_param_value(buf, sizeof(buf), "media", str)) {
2340 if (!strcmp(buf, "disk")) {
2341 media = MEDIA_DISK;
2342 } else if (!strcmp(buf, "cdrom")) {
2343 if (cyls || secs || heads) {
2344 fprintf(stderr,
2345 "qemu: '%s' invalid physical CHS format\n", str);
2346 return -1;
2347 }
2348 media = MEDIA_CDROM;
2349 } else {
2350 fprintf(stderr, "qemu: '%s' invalid media\n", str);
2351 return -1;
2352 }
2353 }
2354
2355 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
2356 if (!strcmp(buf, "on"))
2357 snapshot = 1;
2358 else if (!strcmp(buf, "off"))
2359 snapshot = 0;
2360 else {
2361 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
2362 return -1;
2363 }
2364 }
2365
balrog33f00272007-12-24 14:33:24 +00002366 if (get_param_value(buf, sizeof(buf), "cache", str)) {
aliguori9f7965c2008-10-14 14:42:54 +00002367 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
balrog33f00272007-12-24 14:33:24 +00002368 cache = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002369 else if (!strcmp(buf, "writethrough"))
balrog33f00272007-12-24 14:33:24 +00002370 cache = 1;
aliguori9f7965c2008-10-14 14:42:54 +00002371 else if (!strcmp(buf, "writeback"))
2372 cache = 2;
balrog33f00272007-12-24 14:33:24 +00002373 else {
2374 fprintf(stderr, "qemu: invalid cache option\n");
2375 return -1;
2376 }
2377 }
2378
aurel321e72d3b2008-04-28 20:26:45 +00002379 if (get_param_value(buf, sizeof(buf), "format", str)) {
aurel32a1620fa2008-04-29 05:58:01 +00002380 if (strcmp(buf, "?") == 0) {
2381 fprintf(stderr, "qemu: Supported formats:");
2382 bdrv_iterate_format(bdrv_format_print, NULL);
2383 fprintf(stderr, "\n");
2384 return -1;
2385 }
aurel321e72d3b2008-04-28 20:26:45 +00002386 drv = bdrv_find_format(buf);
2387 if (!drv) {
2388 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
2389 return -1;
2390 }
2391 }
2392
balrog609497a2008-01-14 02:56:53 +00002393 if (arg->file == NULL)
2394 get_param_value(file, sizeof(file), "file", str);
2395 else
2396 pstrcpy(file, sizeof(file), arg->file);
thse4bcb142007-12-02 04:51:10 +00002397
2398 /* compute bus and unit according index */
2399
2400 if (index != -1) {
2401 if (bus_id != 0 || unit_id != -1) {
2402 fprintf(stderr,
2403 "qemu: '%s' index cannot be used with bus and unit\n", str);
2404 return -1;
2405 }
2406 if (max_devs == 0)
2407 {
2408 unit_id = index;
2409 bus_id = 0;
2410 } else {
2411 unit_id = index % max_devs;
2412 bus_id = index / max_devs;
2413 }
2414 }
2415
2416 /* if user doesn't specify a unit_id,
2417 * try to find the first free
2418 */
2419
2420 if (unit_id == -1) {
2421 unit_id = 0;
thsf60d39b2007-12-17 03:55:57 +00002422 while (drive_get_index(type, bus_id, unit_id) != -1) {
thse4bcb142007-12-02 04:51:10 +00002423 unit_id++;
2424 if (max_devs && unit_id >= max_devs) {
2425 unit_id -= max_devs;
2426 bus_id++;
2427 }
2428 }
2429 }
2430
2431 /* check unit id */
2432
2433 if (max_devs && unit_id >= max_devs) {
2434 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
2435 str, unit_id, max_devs - 1);
2436 return -1;
2437 }
2438
2439 /*
2440 * ignore multiple definitions
2441 */
2442
thsf60d39b2007-12-17 03:55:57 +00002443 if (drive_get_index(type, bus_id, unit_id) != -1)
thse4bcb142007-12-02 04:51:10 +00002444 return 0;
2445
2446 /* init */
2447
thsf60d39b2007-12-17 03:55:57 +00002448 if (type == IF_IDE || type == IF_SCSI)
balrogc8522bd2007-12-06 22:11:20 +00002449 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
balroge6198a72007-12-24 13:58:47 +00002450 if (max_devs)
2451 snprintf(buf, sizeof(buf), "%s%i%s%i",
2452 devname, bus_id, mediastr, unit_id);
2453 else
2454 snprintf(buf, sizeof(buf), "%s%s%i",
2455 devname, mediastr, unit_id);
thse4bcb142007-12-02 04:51:10 +00002456 bdrv = bdrv_new(buf);
2457 drives_table[nb_drives].bdrv = bdrv;
thsf60d39b2007-12-17 03:55:57 +00002458 drives_table[nb_drives].type = type;
thse4bcb142007-12-02 04:51:10 +00002459 drives_table[nb_drives].bus = bus_id;
2460 drives_table[nb_drives].unit = unit_id;
2461 nb_drives++;
2462
thsf60d39b2007-12-17 03:55:57 +00002463 switch(type) {
thse4bcb142007-12-02 04:51:10 +00002464 case IF_IDE:
2465 case IF_SCSI:
2466 switch(media) {
2467 case MEDIA_DISK:
2468 if (cyls != 0) {
2469 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
2470 bdrv_set_translation_hint(bdrv, translation);
2471 }
2472 break;
2473 case MEDIA_CDROM:
2474 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
2475 break;
2476 }
2477 break;
2478 case IF_SD:
2479 /* FIXME: This isn't really a floppy, but it's a reasonable
2480 approximation. */
2481 case IF_FLOPPY:
2482 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
2483 break;
2484 case IF_PFLASH:
2485 case IF_MTD:
2486 break;
2487 }
2488 if (!file[0])
2489 return 0;
balrog33f00272007-12-24 14:33:24 +00002490 bdrv_flags = 0;
aliguori9f7965c2008-10-14 14:42:54 +00002491 if (snapshot) {
balrog33f00272007-12-24 14:33:24 +00002492 bdrv_flags |= BDRV_O_SNAPSHOT;
aliguori9f7965c2008-10-14 14:42:54 +00002493 cache = 2; /* always use write-back with snapshot */
2494 }
2495 if (cache == 0) /* no caching */
2496 bdrv_flags |= BDRV_O_NOCACHE;
2497 else if (cache == 2) /* write-back */
2498 bdrv_flags |= BDRV_O_CACHE_WB;
aliguori83ab7952008-08-19 14:44:22 +00002499 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
thse4bcb142007-12-02 04:51:10 +00002500 fprintf(stderr, "qemu: could not open disk image %s\n",
2501 file);
2502 return -1;
2503 }
2504 return 0;
2505}
2506
bellard330d0412003-07-26 18:11:40 +00002507/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00002508/* USB devices */
2509
pbrook0d92ed32006-05-21 16:30:15 +00002510static USBPort *used_usb_ports;
2511static USBPort *free_usb_ports;
2512
2513/* ??? Maybe change this to register a hub to keep track of the topology. */
2514void qemu_register_usb_port(USBPort *port, void *opaque, int index,
2515 usb_attachfn attach)
2516{
2517 port->opaque = opaque;
2518 port->index = index;
2519 port->attach = attach;
2520 port->next = free_usb_ports;
2521 free_usb_ports = port;
2522}
2523
aliguori4b096fc2008-08-21 19:28:55 +00002524int usb_device_add_dev(USBDevice *dev)
2525{
2526 USBPort *port;
2527
2528 /* Find a USB port to add the device to. */
2529 port = free_usb_ports;
2530 if (!port->next) {
2531 USBDevice *hub;
2532
2533 /* Create a new hub and chain it on. */
2534 free_usb_ports = NULL;
2535 port->next = used_usb_ports;
2536 used_usb_ports = port;
2537
2538 hub = usb_hub_init(VM_USB_HUB_SIZE);
2539 usb_attach(port, hub);
2540 port = free_usb_ports;
2541 }
2542
2543 free_usb_ports = port->next;
2544 port->next = used_usb_ports;
2545 used_usb_ports = port;
2546 usb_attach(port, dev);
2547 return 0;
2548}
2549
bellarda594cfb2005-11-06 16:13:29 +00002550static int usb_device_add(const char *devname)
2551{
2552 const char *p;
2553 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00002554
pbrook0d92ed32006-05-21 16:30:15 +00002555 if (!free_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00002556 return -1;
2557
2558 if (strstart(devname, "host:", &p)) {
2559 dev = usb_host_device_open(p);
bellarda594cfb2005-11-06 16:13:29 +00002560 } else if (!strcmp(devname, "mouse")) {
2561 dev = usb_mouse_init();
bellard09b26c52006-04-12 21:09:08 +00002562 } else if (!strcmp(devname, "tablet")) {
balrog47b2d332007-06-22 08:16:00 +00002563 dev = usb_tablet_init();
2564 } else if (!strcmp(devname, "keyboard")) {
2565 dev = usb_keyboard_init();
pbrook2e5d83b2006-05-25 23:58:51 +00002566 } else if (strstart(devname, "disk:", &p)) {
2567 dev = usb_msd_init(p);
balrogf6d2a312007-06-10 19:21:04 +00002568 } else if (!strcmp(devname, "wacom-tablet")) {
2569 dev = usb_wacom_init();
balroga7954212008-01-14 03:41:02 +00002570 } else if (strstart(devname, "serial:", &p)) {
2571 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00002572#ifdef CONFIG_BRLAPI
2573 } else if (!strcmp(devname, "braille")) {
2574 dev = usb_baum_init();
2575#endif
balrog6c9f8862008-07-17 20:47:13 +00002576 } else if (strstart(devname, "net:", &p)) {
balrog9ad97e62008-07-29 13:16:31 +00002577 int nic = nb_nics;
balrog6c9f8862008-07-17 20:47:13 +00002578
balrog9ad97e62008-07-29 13:16:31 +00002579 if (net_client_init("nic", p) < 0)
balrog6c9f8862008-07-17 20:47:13 +00002580 return -1;
balrog9ad97e62008-07-29 13:16:31 +00002581 nd_table[nic].model = "usb";
2582 dev = usb_net_init(&nd_table[nic]);
balrogdc72ac12008-11-09 00:04:26 +00002583 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
2584 dev = usb_bt_init(devname[2] ? hci_init(p) :
2585 bt_new_hci(qemu_find_bt_vlan(0)));
bellarda594cfb2005-11-06 16:13:29 +00002586 } else {
2587 return -1;
2588 }
pbrook0d92ed32006-05-21 16:30:15 +00002589 if (!dev)
2590 return -1;
2591
aliguori4b096fc2008-08-21 19:28:55 +00002592 return usb_device_add_dev(dev);
bellarda594cfb2005-11-06 16:13:29 +00002593}
2594
aliguori1f3870a2008-08-21 19:27:48 +00002595int usb_device_del_addr(int bus_num, int addr)
bellarda594cfb2005-11-06 16:13:29 +00002596{
pbrook0d92ed32006-05-21 16:30:15 +00002597 USBPort *port;
2598 USBPort **lastp;
bellard059809e2006-07-19 18:06:15 +00002599 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00002600
pbrook0d92ed32006-05-21 16:30:15 +00002601 if (!used_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00002602 return -1;
2603
bellarda594cfb2005-11-06 16:13:29 +00002604 if (bus_num != 0)
2605 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00002606
2607 lastp = &used_usb_ports;
2608 port = used_usb_ports;
2609 while (port && port->dev->addr != addr) {
2610 lastp = &port->next;
2611 port = port->next;
bellarda594cfb2005-11-06 16:13:29 +00002612 }
pbrook0d92ed32006-05-21 16:30:15 +00002613
2614 if (!port)
bellarda594cfb2005-11-06 16:13:29 +00002615 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00002616
bellard059809e2006-07-19 18:06:15 +00002617 dev = port->dev;
pbrook0d92ed32006-05-21 16:30:15 +00002618 *lastp = port->next;
2619 usb_attach(port, NULL);
bellard059809e2006-07-19 18:06:15 +00002620 dev->handle_destroy(dev);
pbrook0d92ed32006-05-21 16:30:15 +00002621 port->next = free_usb_ports;
2622 free_usb_ports = port;
bellarda594cfb2005-11-06 16:13:29 +00002623 return 0;
2624}
2625
aliguori1f3870a2008-08-21 19:27:48 +00002626static int usb_device_del(const char *devname)
2627{
2628 int bus_num, addr;
2629 const char *p;
2630
aliguori5d0c5752008-09-14 01:07:41 +00002631 if (strstart(devname, "host:", &p))
2632 return usb_host_device_close(p);
2633
aliguori1f3870a2008-08-21 19:27:48 +00002634 if (!used_usb_ports)
2635 return -1;
2636
2637 p = strchr(devname, '.');
2638 if (!p)
2639 return -1;
2640 bus_num = strtoul(devname, NULL, 0);
2641 addr = strtoul(p + 1, NULL, 0);
2642
2643 return usb_device_del_addr(bus_num, addr);
2644}
2645
bellarda594cfb2005-11-06 16:13:29 +00002646void do_usb_add(const char *devname)
2647{
aliguori4b096fc2008-08-21 19:28:55 +00002648 usb_device_add(devname);
bellarda594cfb2005-11-06 16:13:29 +00002649}
2650
2651void do_usb_del(const char *devname)
2652{
aliguori4b096fc2008-08-21 19:28:55 +00002653 usb_device_del(devname);
bellarda594cfb2005-11-06 16:13:29 +00002654}
2655
2656void usb_info(void)
2657{
2658 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00002659 USBPort *port;
bellarda594cfb2005-11-06 16:13:29 +00002660 const char *speed_str;
2661
pbrook0d92ed32006-05-21 16:30:15 +00002662 if (!usb_enabled) {
bellarda594cfb2005-11-06 16:13:29 +00002663 term_printf("USB support not enabled\n");
2664 return;
2665 }
2666
pbrook0d92ed32006-05-21 16:30:15 +00002667 for (port = used_usb_ports; port; port = port->next) {
2668 dev = port->dev;
2669 if (!dev)
2670 continue;
2671 switch(dev->speed) {
ths5fafdf22007-09-16 21:08:06 +00002672 case USB_SPEED_LOW:
2673 speed_str = "1.5";
pbrook0d92ed32006-05-21 16:30:15 +00002674 break;
ths5fafdf22007-09-16 21:08:06 +00002675 case USB_SPEED_FULL:
2676 speed_str = "12";
pbrook0d92ed32006-05-21 16:30:15 +00002677 break;
ths5fafdf22007-09-16 21:08:06 +00002678 case USB_SPEED_HIGH:
2679 speed_str = "480";
pbrook0d92ed32006-05-21 16:30:15 +00002680 break;
2681 default:
ths5fafdf22007-09-16 21:08:06 +00002682 speed_str = "?";
pbrook0d92ed32006-05-21 16:30:15 +00002683 break;
bellarda594cfb2005-11-06 16:13:29 +00002684 }
ths5fafdf22007-09-16 21:08:06 +00002685 term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
bellard1f6e24e2006-06-26 21:00:51 +00002686 0, dev->addr, speed_str, dev->devname);
bellarda594cfb2005-11-06 16:13:29 +00002687 }
2688}
2689
bellardf7cce892004-12-08 22:21:25 +00002690/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00002691/* PCMCIA/Cardbus */
2692
2693static struct pcmcia_socket_entry_s {
2694 struct pcmcia_socket_s *socket;
2695 struct pcmcia_socket_entry_s *next;
2696} *pcmcia_sockets = 0;
2697
2698void pcmcia_socket_register(struct pcmcia_socket_s *socket)
2699{
2700 struct pcmcia_socket_entry_s *entry;
2701
2702 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
2703 entry->socket = socket;
2704 entry->next = pcmcia_sockets;
2705 pcmcia_sockets = entry;
2706}
2707
2708void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
2709{
2710 struct pcmcia_socket_entry_s *entry, **ptr;
2711
2712 ptr = &pcmcia_sockets;
2713 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
2714 if (entry->socket == socket) {
2715 *ptr = entry->next;
2716 qemu_free(entry);
2717 }
2718}
2719
2720void pcmcia_info(void)
2721{
2722 struct pcmcia_socket_entry_s *iter;
2723 if (!pcmcia_sockets)
2724 term_printf("No PCMCIA sockets\n");
2725
2726 for (iter = pcmcia_sockets; iter; iter = iter->next)
2727 term_printf("%s: %s\n", iter->socket->slot_string,
2728 iter->socket->attached ? iter->socket->card_string :
2729 "Empty");
2730}
2731
2732/***********************************************************/
ths2ff89792007-06-21 23:34:19 +00002733/* dumb display */
2734
2735static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
2736{
2737}
2738
2739static void dumb_resize(DisplayState *ds, int w, int h)
2740{
2741}
2742
ths2ff89792007-06-21 23:34:19 +00002743static void dumb_display_init(DisplayState *ds)
2744{
2745 ds->data = NULL;
2746 ds->linesize = 0;
2747 ds->depth = 0;
2748 ds->dpy_update = dumb_update;
2749 ds->dpy_resize = dumb_resize;
aliguori2ad1a432008-10-31 20:34:40 +00002750 ds->dpy_refresh = NULL;
2751 ds->gui_timer_interval = 0;
aliguoribcfad702008-08-21 20:08:55 +00002752 ds->idle = 1;
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 +00002758#define MAX_IO_HANDLERS 64
2759
2760typedef struct IOHandlerRecord {
2761 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00002762 IOCanRWHandler *fd_read_poll;
2763 IOHandler *fd_read;
2764 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00002765 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00002766 void *opaque;
2767 /* temporary data */
2768 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00002769 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00002770} IOHandlerRecord;
2771
bellard8a7ddc32004-03-31 19:00:16 +00002772static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00002773
bellard7c9d8e02005-11-15 22:16:05 +00002774/* XXX: fd_read_poll should be suppressed, but an API change is
2775 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00002776int qemu_set_fd_handler2(int fd,
2777 IOCanRWHandler *fd_read_poll,
2778 IOHandler *fd_read,
2779 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002780 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00002781{
bellard8a7ddc32004-03-31 19:00:16 +00002782 IOHandlerRecord **pioh, *ioh;
2783
bellard7c9d8e02005-11-15 22:16:05 +00002784 if (!fd_read && !fd_write) {
2785 pioh = &first_io_handler;
2786 for(;;) {
2787 ioh = *pioh;
2788 if (ioh == NULL)
2789 break;
2790 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00002791 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00002792 break;
2793 }
2794 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00002795 }
bellard7c9d8e02005-11-15 22:16:05 +00002796 } else {
2797 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2798 if (ioh->fd == fd)
2799 goto found;
2800 }
2801 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
2802 if (!ioh)
2803 return -1;
2804 ioh->next = first_io_handler;
2805 first_io_handler = ioh;
2806 found:
2807 ioh->fd = fd;
2808 ioh->fd_read_poll = fd_read_poll;
2809 ioh->fd_read = fd_read;
2810 ioh->fd_write = fd_write;
2811 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00002812 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00002813 }
bellard7c9d8e02005-11-15 22:16:05 +00002814 return 0;
2815}
2816
ths5fafdf22007-09-16 21:08:06 +00002817int qemu_set_fd_handler(int fd,
2818 IOHandler *fd_read,
2819 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00002820 void *opaque)
2821{
2822 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00002823}
2824
aliguori56f3a5d2008-10-31 18:07:17 +00002825#ifdef _WIN32
bellard8a7ddc32004-03-31 19:00:16 +00002826/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00002827/* Polling handling */
2828
2829typedef struct PollingEntry {
2830 PollingFunc *func;
2831 void *opaque;
2832 struct PollingEntry *next;
2833} PollingEntry;
2834
2835static PollingEntry *first_polling_entry;
2836
2837int qemu_add_polling_cb(PollingFunc *func, void *opaque)
2838{
2839 PollingEntry **ppe, *pe;
2840 pe = qemu_mallocz(sizeof(PollingEntry));
2841 if (!pe)
2842 return -1;
2843 pe->func = func;
2844 pe->opaque = opaque;
2845 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
2846 *ppe = pe;
2847 return 0;
2848}
2849
2850void qemu_del_polling_cb(PollingFunc *func, void *opaque)
2851{
2852 PollingEntry **ppe, *pe;
2853 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
2854 pe = *ppe;
2855 if (pe->func == func && pe->opaque == opaque) {
2856 *ppe = pe->next;
2857 qemu_free(pe);
2858 break;
2859 }
2860 }
2861}
2862
bellarda18e5242006-06-25 17:18:27 +00002863/***********************************************************/
2864/* Wait objects support */
2865typedef struct WaitObjects {
2866 int num;
2867 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
2868 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
2869 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
2870} WaitObjects;
2871
2872static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00002873
bellarda18e5242006-06-25 17:18:27 +00002874int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2875{
2876 WaitObjects *w = &wait_objects;
2877
2878 if (w->num >= MAXIMUM_WAIT_OBJECTS)
2879 return -1;
2880 w->events[w->num] = handle;
2881 w->func[w->num] = func;
2882 w->opaque[w->num] = opaque;
2883 w->num++;
2884 return 0;
2885}
2886
2887void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2888{
2889 int i, found;
2890 WaitObjects *w = &wait_objects;
2891
2892 found = 0;
2893 for (i = 0; i < w->num; i++) {
2894 if (w->events[i] == handle)
2895 found = 1;
2896 if (found) {
2897 w->events[i] = w->events[i + 1];
2898 w->func[i] = w->func[i + 1];
2899 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00002900 }
bellarda18e5242006-06-25 17:18:27 +00002901 }
2902 if (found)
2903 w->num--;
2904}
2905#endif
2906
bellard8a7ddc32004-03-31 19:00:16 +00002907/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00002908/* ram save/restore */
2909
bellard8a7ddc32004-03-31 19:00:16 +00002910static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
2911{
2912 int v;
2913
2914 v = qemu_get_byte(f);
2915 switch(v) {
2916 case 0:
2917 if (qemu_get_buffer(f, buf, len) != len)
2918 return -EIO;
2919 break;
2920 case 1:
2921 v = qemu_get_byte(f);
2922 memset(buf, v, len);
2923 break;
2924 default:
2925 return -EINVAL;
2926 }
aliguori871d2f02008-10-13 03:07:56 +00002927
2928 if (qemu_file_has_error(f))
2929 return -EIO;
2930
bellard8a7ddc32004-03-31 19:00:16 +00002931 return 0;
2932}
2933
bellardc88676f2006-08-06 13:36:11 +00002934static int ram_load_v1(QEMUFile *f, void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00002935{
aurel3200f82b82008-04-27 21:12:55 +00002936 int ret;
2937 ram_addr_t i;
bellard8a7ddc32004-03-31 19:00:16 +00002938
bellard8a7ddc32004-03-31 19:00:16 +00002939 if (qemu_get_be32(f) != phys_ram_size)
2940 return -EINVAL;
2941 for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
2942 ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
2943 if (ret)
2944 return ret;
2945 }
2946 return 0;
2947}
2948
bellardc88676f2006-08-06 13:36:11 +00002949#define BDRV_HASH_BLOCK_SIZE 1024
2950#define IOBUF_SIZE 4096
2951#define RAM_CBLOCK_MAGIC 0xfabe
2952
bellardc88676f2006-08-06 13:36:11 +00002953typedef struct RamDecompressState {
2954 z_stream zstream;
2955 QEMUFile *f;
2956 uint8_t buf[IOBUF_SIZE];
2957} RamDecompressState;
2958
2959static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
2960{
2961 int ret;
2962 memset(s, 0, sizeof(*s));
2963 s->f = f;
2964 ret = inflateInit(&s->zstream);
2965 if (ret != Z_OK)
2966 return -1;
2967 return 0;
2968}
2969
2970static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
2971{
2972 int ret, clen;
2973
2974 s->zstream.avail_out = len;
2975 s->zstream.next_out = buf;
2976 while (s->zstream.avail_out > 0) {
2977 if (s->zstream.avail_in == 0) {
2978 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
2979 return -1;
2980 clen = qemu_get_be16(s->f);
2981 if (clen > IOBUF_SIZE)
2982 return -1;
2983 qemu_get_buffer(s->f, s->buf, clen);
2984 s->zstream.avail_in = clen;
2985 s->zstream.next_in = s->buf;
2986 }
2987 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
2988 if (ret != Z_OK && ret != Z_STREAM_END) {
2989 return -1;
2990 }
2991 }
2992 return 0;
2993}
2994
2995static void ram_decompress_close(RamDecompressState *s)
2996{
2997 inflateEnd(&s->zstream);
2998}
2999
aliguori475e4272008-10-06 20:21:51 +00003000#define RAM_SAVE_FLAG_FULL 0x01
3001#define RAM_SAVE_FLAG_COMPRESS 0x02
3002#define RAM_SAVE_FLAG_MEM_SIZE 0x04
3003#define RAM_SAVE_FLAG_PAGE 0x08
3004#define RAM_SAVE_FLAG_EOS 0x10
3005
3006static int is_dup_page(uint8_t *page, uint8_t ch)
bellardc88676f2006-08-06 13:36:11 +00003007{
aliguori475e4272008-10-06 20:21:51 +00003008 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
3009 uint32_t *array = (uint32_t *)page;
3010 int i;
ths3b46e622007-09-17 08:09:54 +00003011
aliguori475e4272008-10-06 20:21:51 +00003012 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
3013 if (array[i] != val)
3014 return 0;
bellardc88676f2006-08-06 13:36:11 +00003015 }
aliguori475e4272008-10-06 20:21:51 +00003016
3017 return 1;
bellardc88676f2006-08-06 13:36:11 +00003018}
3019
aliguori475e4272008-10-06 20:21:51 +00003020static int ram_save_block(QEMUFile *f)
3021{
3022 static ram_addr_t current_addr = 0;
3023 ram_addr_t saved_addr = current_addr;
3024 ram_addr_t addr = 0;
3025 int found = 0;
3026
3027 while (addr < phys_ram_size) {
3028 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
3029 uint8_t ch;
3030
3031 cpu_physical_memory_reset_dirty(current_addr,
3032 current_addr + TARGET_PAGE_SIZE,
3033 MIGRATION_DIRTY_FLAG);
3034
3035 ch = *(phys_ram_base + current_addr);
3036
3037 if (is_dup_page(phys_ram_base + current_addr, ch)) {
3038 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
3039 qemu_put_byte(f, ch);
3040 } else {
3041 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
3042 qemu_put_buffer(f, phys_ram_base + current_addr, TARGET_PAGE_SIZE);
3043 }
3044
3045 found = 1;
3046 break;
3047 }
3048 addr += TARGET_PAGE_SIZE;
3049 current_addr = (saved_addr + addr) % phys_ram_size;
3050 }
3051
3052 return found;
3053}
3054
3055static ram_addr_t ram_save_threshold = 10;
3056
3057static ram_addr_t ram_save_remaining(void)
3058{
3059 ram_addr_t addr;
3060 ram_addr_t count = 0;
3061
3062 for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
3063 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
3064 count++;
3065 }
3066
3067 return count;
3068}
3069
3070static int ram_save_live(QEMUFile *f, int stage, void *opaque)
3071{
3072 ram_addr_t addr;
3073
3074 if (stage == 1) {
3075 /* Make sure all dirty bits are set */
3076 for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
3077 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
3078 cpu_physical_memory_set_dirty(addr);
3079 }
3080
3081 /* Enable dirty memory tracking */
3082 cpu_physical_memory_set_dirty_tracking(1);
3083
3084 qemu_put_be64(f, phys_ram_size | RAM_SAVE_FLAG_MEM_SIZE);
3085 }
3086
3087 while (!qemu_file_rate_limit(f)) {
3088 int ret;
3089
3090 ret = ram_save_block(f);
3091 if (ret == 0) /* no more blocks */
3092 break;
3093 }
3094
3095 /* try transferring iterative blocks of memory */
3096
3097 if (stage == 3) {
3098 cpu_physical_memory_set_dirty_tracking(0);
3099
3100 /* flush all remaining blocks regardless of rate limiting */
3101 while (ram_save_block(f) != 0);
3102 }
3103
3104 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
3105
3106 return (stage == 2) && (ram_save_remaining() < ram_save_threshold);
3107}
3108
3109static int ram_load_dead(QEMUFile *f, void *opaque)
bellardc88676f2006-08-06 13:36:11 +00003110{
3111 RamDecompressState s1, *s = &s1;
3112 uint8_t buf[10];
aurel3200f82b82008-04-27 21:12:55 +00003113 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00003114
bellardc88676f2006-08-06 13:36:11 +00003115 if (ram_decompress_open(s, f) < 0)
3116 return -EINVAL;
3117 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
3118 if (ram_decompress_buf(s, buf, 1) < 0) {
3119 fprintf(stderr, "Error while reading ram block header\n");
3120 goto error;
3121 }
3122 if (buf[0] == 0) {
3123 if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
aurel3200f82b82008-04-27 21:12:55 +00003124 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
bellardc88676f2006-08-06 13:36:11 +00003125 goto error;
3126 }
aliguori475e4272008-10-06 20:21:51 +00003127 } else {
bellardc88676f2006-08-06 13:36:11 +00003128 error:
3129 printf("Error block header\n");
3130 return -EINVAL;
3131 }
3132 }
3133 ram_decompress_close(s);
aliguori475e4272008-10-06 20:21:51 +00003134
3135 return 0;
3136}
3137
3138static int ram_load(QEMUFile *f, void *opaque, int version_id)
3139{
3140 ram_addr_t addr;
3141 int flags;
3142
3143 if (version_id == 1)
3144 return ram_load_v1(f, opaque);
3145
3146 if (version_id == 2) {
3147 if (qemu_get_be32(f) != phys_ram_size)
3148 return -EINVAL;
3149 return ram_load_dead(f, opaque);
3150 }
3151
3152 if (version_id != 3)
3153 return -EINVAL;
3154
3155 do {
3156 addr = qemu_get_be64(f);
3157
3158 flags = addr & ~TARGET_PAGE_MASK;
3159 addr &= TARGET_PAGE_MASK;
3160
3161 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
3162 if (addr != phys_ram_size)
3163 return -EINVAL;
3164 }
3165
3166 if (flags & RAM_SAVE_FLAG_FULL) {
3167 if (ram_load_dead(f, opaque) < 0)
3168 return -EINVAL;
3169 }
3170
3171 if (flags & RAM_SAVE_FLAG_COMPRESS) {
3172 uint8_t ch = qemu_get_byte(f);
3173 memset(phys_ram_base + addr, ch, TARGET_PAGE_SIZE);
3174 } else if (flags & RAM_SAVE_FLAG_PAGE)
3175 qemu_get_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE);
3176 } while (!(flags & RAM_SAVE_FLAG_EOS));
3177
bellardc88676f2006-08-06 13:36:11 +00003178 return 0;
3179}
3180
aliguori9e472e12008-10-08 19:50:24 +00003181void qemu_service_io(void)
3182{
3183 CPUState *env = cpu_single_env;
3184 if (env) {
3185 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
3186#ifdef USE_KQEMU
3187 if (env->kqemu_enabled) {
3188 kqemu_cpu_interrupt(env);
3189 }
3190#endif
3191 }
3192}
3193
bellard8a7ddc32004-03-31 19:00:16 +00003194/***********************************************************/
bellard83f64092006-08-01 16:21:11 +00003195/* bottom halves (can be seen as timers which expire ASAP) */
3196
3197struct QEMUBH {
3198 QEMUBHFunc *cb;
3199 void *opaque;
3200 int scheduled;
aliguori1b435b12008-10-31 17:24:21 +00003201 int idle;
3202 int deleted;
bellard83f64092006-08-01 16:21:11 +00003203 QEMUBH *next;
3204};
3205
3206static QEMUBH *first_bh = NULL;
3207
3208QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
3209{
3210 QEMUBH *bh;
3211 bh = qemu_mallocz(sizeof(QEMUBH));
3212 if (!bh)
3213 return NULL;
3214 bh->cb = cb;
3215 bh->opaque = opaque;
aliguori1b435b12008-10-31 17:24:21 +00003216 bh->next = first_bh;
3217 first_bh = bh;
bellard83f64092006-08-01 16:21:11 +00003218 return bh;
3219}
3220
bellard6eb57332006-08-06 09:51:25 +00003221int qemu_bh_poll(void)
bellard83f64092006-08-01 16:21:11 +00003222{
aliguori1b435b12008-10-31 17:24:21 +00003223 QEMUBH *bh, **bhp;
bellard6eb57332006-08-06 09:51:25 +00003224 int ret;
bellard83f64092006-08-01 16:21:11 +00003225
bellard6eb57332006-08-06 09:51:25 +00003226 ret = 0;
aliguori1b435b12008-10-31 17:24:21 +00003227 for (bh = first_bh; bh; bh = bh->next) {
3228 if (!bh->deleted && bh->scheduled) {
3229 bh->scheduled = 0;
3230 if (!bh->idle)
3231 ret = 1;
3232 bh->idle = 0;
3233 bh->cb(bh->opaque);
3234 }
bellard83f64092006-08-01 16:21:11 +00003235 }
aliguori1b435b12008-10-31 17:24:21 +00003236
3237 /* remove deleted bhs */
3238 bhp = &first_bh;
3239 while (*bhp) {
3240 bh = *bhp;
3241 if (bh->deleted) {
3242 *bhp = bh->next;
3243 qemu_free(bh);
3244 } else
3245 bhp = &bh->next;
3246 }
3247
bellard6eb57332006-08-06 09:51:25 +00003248 return ret;
bellard83f64092006-08-01 16:21:11 +00003249}
3250
aliguori1b435b12008-10-31 17:24:21 +00003251void qemu_bh_schedule_idle(QEMUBH *bh)
3252{
3253 if (bh->scheduled)
3254 return;
3255 bh->scheduled = 1;
3256 bh->idle = 1;
3257}
3258
bellard83f64092006-08-01 16:21:11 +00003259void qemu_bh_schedule(QEMUBH *bh)
3260{
3261 CPUState *env = cpu_single_env;
3262 if (bh->scheduled)
3263 return;
3264 bh->scheduled = 1;
aliguori1b435b12008-10-31 17:24:21 +00003265 bh->idle = 0;
bellard83f64092006-08-01 16:21:11 +00003266 /* stop the currently executing CPU to execute the BH ASAP */
3267 if (env) {
3268 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
3269 }
3270}
3271
3272void qemu_bh_cancel(QEMUBH *bh)
3273{
aliguori1b435b12008-10-31 17:24:21 +00003274 bh->scheduled = 0;
bellard83f64092006-08-01 16:21:11 +00003275}
3276
3277void qemu_bh_delete(QEMUBH *bh)
3278{
aliguori1b435b12008-10-31 17:24:21 +00003279 bh->scheduled = 0;
3280 bh->deleted = 1;
bellard83f64092006-08-01 16:21:11 +00003281}
3282
aliguori56f3a5d2008-10-31 18:07:17 +00003283static void qemu_bh_update_timeout(int *timeout)
3284{
3285 QEMUBH *bh;
3286
3287 for (bh = first_bh; bh; bh = bh->next) {
3288 if (!bh->deleted && bh->scheduled) {
3289 if (bh->idle) {
3290 /* idle bottom halves will be polled at least
3291 * every 10ms */
3292 *timeout = MIN(10, *timeout);
3293 } else {
3294 /* non-idle bottom halves will be executed
3295 * immediately */
3296 *timeout = 0;
3297 break;
3298 }
3299 }
3300 }
3301}
3302
bellard83f64092006-08-01 16:21:11 +00003303/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00003304/* machine registration */
3305
blueswir1bdaf78e2008-10-04 07:24:27 +00003306static QEMUMachine *first_machine = NULL;
bellardcc1daa42005-06-05 14:49:17 +00003307
3308int qemu_register_machine(QEMUMachine *m)
3309{
3310 QEMUMachine **pm;
3311 pm = &first_machine;
3312 while (*pm != NULL)
3313 pm = &(*pm)->next;
3314 m->next = NULL;
3315 *pm = m;
3316 return 0;
3317}
3318
pbrook9596ebb2007-11-18 01:44:38 +00003319static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00003320{
3321 QEMUMachine *m;
3322
3323 for(m = first_machine; m != NULL; m = m->next) {
3324 if (!strcmp(m->name, name))
3325 return m;
3326 }
3327 return NULL;
3328}
3329
3330/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00003331/* main execution loop */
3332
pbrook9596ebb2007-11-18 01:44:38 +00003333static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00003334{
ths740733b2007-06-08 01:57:56 +00003335 DisplayState *ds = opaque;
3336 ds->dpy_refresh(ds);
aurel32f442e082008-03-13 19:20:33 +00003337 qemu_mod_timer(ds->gui_timer,
3338 (ds->gui_timer_interval ?
3339 ds->gui_timer_interval :
3340 GUI_REFRESH_INTERVAL)
3341 + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00003342}
3343
bellard0bd48852005-11-11 00:00:47 +00003344struct vm_change_state_entry {
3345 VMChangeStateHandler *cb;
3346 void *opaque;
3347 LIST_ENTRY (vm_change_state_entry) entries;
3348};
3349
3350static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
3351
3352VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
3353 void *opaque)
3354{
3355 VMChangeStateEntry *e;
3356
3357 e = qemu_mallocz(sizeof (*e));
3358 if (!e)
3359 return NULL;
3360
3361 e->cb = cb;
3362 e->opaque = opaque;
3363 LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
3364 return e;
3365}
3366
3367void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
3368{
3369 LIST_REMOVE (e, entries);
3370 qemu_free (e);
3371}
3372
3373static void vm_state_notify(int running)
3374{
3375 VMChangeStateEntry *e;
3376
3377 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
3378 e->cb(e->opaque, running);
3379 }
3380}
3381
bellard8a7ddc32004-03-31 19:00:16 +00003382/* XXX: support several handlers */
bellard0bd48852005-11-11 00:00:47 +00003383static VMStopHandler *vm_stop_cb;
3384static void *vm_stop_opaque;
bellard8a7ddc32004-03-31 19:00:16 +00003385
3386int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
3387{
3388 vm_stop_cb = cb;
3389 vm_stop_opaque = opaque;
3390 return 0;
3391}
3392
3393void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
3394{
3395 vm_stop_cb = NULL;
3396}
3397
3398void vm_start(void)
3399{
3400 if (!vm_running) {
3401 cpu_enable_ticks();
3402 vm_running = 1;
bellard0bd48852005-11-11 00:00:47 +00003403 vm_state_notify(1);
thsefe75412007-08-24 01:36:32 +00003404 qemu_rearm_alarm_timer(alarm_timer);
bellard8a7ddc32004-03-31 19:00:16 +00003405 }
3406}
3407
ths5fafdf22007-09-16 21:08:06 +00003408void vm_stop(int reason)
bellard8a7ddc32004-03-31 19:00:16 +00003409{
3410 if (vm_running) {
3411 cpu_disable_ticks();
3412 vm_running = 0;
3413 if (reason != 0) {
3414 if (vm_stop_cb) {
3415 vm_stop_cb(vm_stop_opaque, reason);
3416 }
3417 }
bellard0bd48852005-11-11 00:00:47 +00003418 vm_state_notify(0);
bellard8a7ddc32004-03-31 19:00:16 +00003419 }
3420}
3421
bellardbb0c6722004-06-20 12:37:32 +00003422/* reset/shutdown handler */
3423
3424typedef struct QEMUResetEntry {
3425 QEMUResetHandler *func;
3426 void *opaque;
3427 struct QEMUResetEntry *next;
3428} QEMUResetEntry;
3429
3430static QEMUResetEntry *first_reset_entry;
3431static int reset_requested;
3432static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00003433static int powerdown_requested;
bellardbb0c6722004-06-20 12:37:32 +00003434
aurel32cf7a2fe2008-03-18 06:53:05 +00003435int qemu_shutdown_requested(void)
3436{
3437 int r = shutdown_requested;
3438 shutdown_requested = 0;
3439 return r;
3440}
3441
3442int qemu_reset_requested(void)
3443{
3444 int r = reset_requested;
3445 reset_requested = 0;
3446 return r;
3447}
3448
3449int qemu_powerdown_requested(void)
3450{
3451 int r = powerdown_requested;
3452 powerdown_requested = 0;
3453 return r;
3454}
3455
bellardbb0c6722004-06-20 12:37:32 +00003456void qemu_register_reset(QEMUResetHandler *func, void *opaque)
3457{
3458 QEMUResetEntry **pre, *re;
3459
3460 pre = &first_reset_entry;
3461 while (*pre != NULL)
3462 pre = &(*pre)->next;
3463 re = qemu_mallocz(sizeof(QEMUResetEntry));
3464 re->func = func;
3465 re->opaque = opaque;
3466 re->next = NULL;
3467 *pre = re;
3468}
3469
aurel32cf7a2fe2008-03-18 06:53:05 +00003470void qemu_system_reset(void)
bellardbb0c6722004-06-20 12:37:32 +00003471{
3472 QEMUResetEntry *re;
3473
3474 /* reset all devices */
3475 for(re = first_reset_entry; re != NULL; re = re->next) {
3476 re->func(re->opaque);
3477 }
3478}
3479
3480void qemu_system_reset_request(void)
3481{
bellardd1beab82006-10-02 19:44:22 +00003482 if (no_reboot) {
3483 shutdown_requested = 1;
3484 } else {
3485 reset_requested = 1;
3486 }
bellard6a00d602005-11-21 23:25:50 +00003487 if (cpu_single_env)
3488 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00003489}
3490
3491void qemu_system_shutdown_request(void)
3492{
3493 shutdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00003494 if (cpu_single_env)
3495 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00003496}
3497
bellard34751872005-07-02 14:31:34 +00003498void qemu_system_powerdown_request(void)
3499{
3500 powerdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00003501 if (cpu_single_env)
3502 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00003503}
3504
ths877cf882007-04-18 18:11:47 +00003505#ifdef _WIN32
aliguori56f3a5d2008-10-31 18:07:17 +00003506void host_main_loop_wait(int *timeout)
3507{
3508 int ret, ret2, i;
bellardf3311102006-04-12 20:21:17 +00003509 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00003510
bellardf3311102006-04-12 20:21:17 +00003511
3512 /* XXX: need to suppress polling by better using win32 events */
3513 ret = 0;
3514 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
3515 ret |= pe->func(pe->opaque);
3516 }
thse6b1e552007-04-18 17:56:02 +00003517 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00003518 int err;
3519 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00003520
aliguori56f3a5d2008-10-31 18:07:17 +00003521 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
bellarda18e5242006-06-25 17:18:27 +00003522 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
3523 if (w->func[ret - WAIT_OBJECT_0])
3524 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00003525
ths5fafdf22007-09-16 21:08:06 +00003526 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00003527 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00003528
thse6b1e552007-04-18 17:56:02 +00003529 /* Check if event is signaled */
3530 ret2 = WaitForSingleObject(w->events[i], 0);
3531 if(ret2 == WAIT_OBJECT_0) {
3532 if (w->func[i])
3533 w->func[i](w->opaque[i]);
3534 } else if (ret2 == WAIT_TIMEOUT) {
3535 } else {
3536 err = GetLastError();
3537 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00003538 }
3539 }
bellarda18e5242006-06-25 17:18:27 +00003540 } else if (ret == WAIT_TIMEOUT) {
3541 } else {
3542 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00003543 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00003544 }
bellardf3311102006-04-12 20:21:17 +00003545 }
aliguori56f3a5d2008-10-31 18:07:17 +00003546
3547 *timeout = 0;
3548}
3549#else
3550void host_main_loop_wait(int *timeout)
3551{
3552}
bellardfd1dff42006-02-01 21:29:26 +00003553#endif
aliguori56f3a5d2008-10-31 18:07:17 +00003554
3555void main_loop_wait(int timeout)
3556{
3557 IOHandlerRecord *ioh;
3558 fd_set rfds, wfds, xfds;
3559 int ret, nfds;
3560 struct timeval tv;
3561
3562 qemu_bh_update_timeout(&timeout);
3563
3564 host_main_loop_wait(&timeout);
3565
bellardfd1dff42006-02-01 21:29:26 +00003566 /* poll any events */
3567 /* XXX: separate device handlers from system ones */
aliguori6abfbd72008-11-05 20:49:37 +00003568 nfds = -1;
bellardfd1dff42006-02-01 21:29:26 +00003569 FD_ZERO(&rfds);
3570 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00003571 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00003572 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00003573 if (ioh->deleted)
3574 continue;
bellardfd1dff42006-02-01 21:29:26 +00003575 if (ioh->fd_read &&
3576 (!ioh->fd_read_poll ||
3577 ioh->fd_read_poll(ioh->opaque) != 0)) {
3578 FD_SET(ioh->fd, &rfds);
3579 if (ioh->fd > nfds)
3580 nfds = ioh->fd;
3581 }
3582 if (ioh->fd_write) {
3583 FD_SET(ioh->fd, &wfds);
3584 if (ioh->fd > nfds)
3585 nfds = ioh->fd;
3586 }
3587 }
ths3b46e622007-09-17 08:09:54 +00003588
aliguori56f3a5d2008-10-31 18:07:17 +00003589 tv.tv_sec = timeout / 1000;
3590 tv.tv_usec = (timeout % 1000) * 1000;
3591
bellarde0356492006-05-01 13:33:02 +00003592#if defined(CONFIG_SLIRP)
aliguori63a01ef2008-10-31 19:10:00 +00003593 if (slirp_is_inited()) {
bellarde0356492006-05-01 13:33:02 +00003594 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
3595 }
3596#endif
3597 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
bellardfd1dff42006-02-01 21:29:26 +00003598 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00003599 IOHandlerRecord **pioh;
3600
3601 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00003602 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003603 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00003604 }
ths6ab43fd2007-08-25 01:34:19 +00003605 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00003606 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00003607 }
3608 }
thscafffd42007-02-28 21:59:44 +00003609
3610 /* remove deleted IO handlers */
3611 pioh = &first_io_handler;
3612 while (*pioh) {
3613 ioh = *pioh;
3614 if (ioh->deleted) {
3615 *pioh = ioh->next;
3616 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00003617 } else
thscafffd42007-02-28 21:59:44 +00003618 pioh = &ioh->next;
3619 }
bellardfd1dff42006-02-01 21:29:26 +00003620 }
bellarde0356492006-05-01 13:33:02 +00003621#if defined(CONFIG_SLIRP)
aliguori63a01ef2008-10-31 19:10:00 +00003622 if (slirp_is_inited()) {
bellarde0356492006-05-01 13:33:02 +00003623 if (ret < 0) {
3624 FD_ZERO(&rfds);
3625 FD_ZERO(&wfds);
3626 FD_ZERO(&xfds);
3627 }
3628 slirp_select_poll(&rfds, &wfds, &xfds);
3629 }
3630#endif
bellardc20709a2004-04-21 23:27:19 +00003631
pbrook423f0742007-05-23 00:06:54 +00003632 /* Check bottom-halves last in case any of the earlier events triggered
3633 them. */
3634 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00003635
bellard5905b2e2004-08-01 21:53:26 +00003636}
3637
pbrook9596ebb2007-11-18 01:44:38 +00003638static int main_loop(void)
bellard5905b2e2004-08-01 21:53:26 +00003639{
3640 int ret, timeout;
bellard89bfc102006-02-08 22:46:31 +00003641#ifdef CONFIG_PROFILER
3642 int64_t ti;
3643#endif
bellard6a00d602005-11-21 23:25:50 +00003644 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00003645
bellard6a00d602005-11-21 23:25:50 +00003646 cur_cpu = first_cpu;
balrogee5605e2007-12-03 03:01:40 +00003647 next_cpu = cur_cpu->next_cpu ?: first_cpu;
bellard5905b2e2004-08-01 21:53:26 +00003648 for(;;) {
3649 if (vm_running) {
bellard15a76442005-11-23 21:01:03 +00003650
bellard15a76442005-11-23 21:01:03 +00003651 for(;;) {
3652 /* get next cpu */
balrogee5605e2007-12-03 03:01:40 +00003653 env = next_cpu;
bellard89bfc102006-02-08 22:46:31 +00003654#ifdef CONFIG_PROFILER
3655 ti = profile_getclock();
3656#endif
pbrook2e70f6e2008-06-29 01:03:05 +00003657 if (use_icount) {
3658 int64_t count;
3659 int decr;
3660 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3661 env->icount_decr.u16.low = 0;
3662 env->icount_extra = 0;
3663 count = qemu_next_deadline();
3664 count = (count + (1 << icount_time_shift) - 1)
3665 >> icount_time_shift;
3666 qemu_icount += count;
3667 decr = (count > 0xffff) ? 0xffff : count;
3668 count -= decr;
3669 env->icount_decr.u16.low = decr;
3670 env->icount_extra = count;
3671 }
bellard6a00d602005-11-21 23:25:50 +00003672 ret = cpu_exec(env);
bellard89bfc102006-02-08 22:46:31 +00003673#ifdef CONFIG_PROFILER
3674 qemu_time += profile_getclock() - ti;
3675#endif
pbrook2e70f6e2008-06-29 01:03:05 +00003676 if (use_icount) {
3677 /* Fold pending instructions back into the
3678 instruction counter, and clear the interrupt flag. */
3679 qemu_icount -= (env->icount_decr.u16.low
3680 + env->icount_extra);
3681 env->icount_decr.u32 = 0;
3682 env->icount_extra = 0;
3683 }
balrogee5605e2007-12-03 03:01:40 +00003684 next_cpu = env->next_cpu ?: first_cpu;
aurel3295b01002008-04-04 17:16:35 +00003685 if (event_pending && likely(ret != EXCP_DEBUG)) {
balrogee5605e2007-12-03 03:01:40 +00003686 ret = EXCP_INTERRUPT;
3687 event_pending = 0;
3688 break;
3689 }
pbrookbd967e02007-03-11 18:54:57 +00003690 if (ret == EXCP_HLT) {
3691 /* Give the next CPU a chance to run. */
3692 cur_cpu = env;
3693 continue;
3694 }
bellard15a76442005-11-23 21:01:03 +00003695 if (ret != EXCP_HALTED)
3696 break;
3697 /* all CPUs are halted ? */
pbrookbd967e02007-03-11 18:54:57 +00003698 if (env == cur_cpu)
bellard15a76442005-11-23 21:01:03 +00003699 break;
bellard15a76442005-11-23 21:01:03 +00003700 }
3701 cur_cpu = env;
3702
bellard5905b2e2004-08-01 21:53:26 +00003703 if (shutdown_requested) {
bellard34751872005-07-02 14:31:34 +00003704 ret = EXCP_INTERRUPT;
aurel32b2f76162008-04-11 21:35:52 +00003705 if (no_shutdown) {
3706 vm_stop(0);
3707 no_shutdown = 0;
3708 }
3709 else
3710 break;
bellard5905b2e2004-08-01 21:53:26 +00003711 }
3712 if (reset_requested) {
3713 reset_requested = 0;
3714 qemu_system_reset();
bellard34751872005-07-02 14:31:34 +00003715 ret = EXCP_INTERRUPT;
3716 }
3717 if (powerdown_requested) {
3718 powerdown_requested = 0;
3719 qemu_system_powerdown();
3720 ret = EXCP_INTERRUPT;
bellard5905b2e2004-08-01 21:53:26 +00003721 }
aurel3295b01002008-04-04 17:16:35 +00003722 if (unlikely(ret == EXCP_DEBUG)) {
bellard5905b2e2004-08-01 21:53:26 +00003723 vm_stop(EXCP_DEBUG);
3724 }
pbrookbd967e02007-03-11 18:54:57 +00003725 /* If all cpus are halted then wait until the next IRQ */
bellard5905b2e2004-08-01 21:53:26 +00003726 /* XXX: use timeout computed from timers */
pbrook2e70f6e2008-06-29 01:03:05 +00003727 if (ret == EXCP_HALTED) {
3728 if (use_icount) {
3729 int64_t add;
3730 int64_t delta;
3731 /* Advance virtual time to the next event. */
3732 if (use_icount == 1) {
3733 /* When not using an adaptive execution frequency
3734 we tend to get badly out of sync with real time,
thsbf20dc02008-06-30 17:22:19 +00003735 so just delay for a reasonable amount of time. */
pbrook2e70f6e2008-06-29 01:03:05 +00003736 delta = 0;
3737 } else {
3738 delta = cpu_get_icount() - cpu_get_clock();
3739 }
3740 if (delta > 0) {
3741 /* If virtual time is ahead of real time then just
3742 wait for IO. */
3743 timeout = (delta / 1000000) + 1;
3744 } else {
3745 /* Wait for either IO to occur or the next
3746 timer event. */
3747 add = qemu_next_deadline();
3748 /* We advance the timer before checking for IO.
3749 Limit the amount we advance so that early IO
3750 activity won't get the guest too far ahead. */
3751 if (add > 10000000)
3752 add = 10000000;
3753 delta += add;
3754 add = (add + (1 << icount_time_shift) - 1)
3755 >> icount_time_shift;
3756 qemu_icount += add;
3757 timeout = delta / 1000000;
3758 if (timeout < 0)
3759 timeout = 0;
3760 }
3761 } else {
aliguori0a1af392008-10-31 18:40:25 +00003762 timeout = 5000;
pbrook2e70f6e2008-06-29 01:03:05 +00003763 }
3764 } else {
bellard5905b2e2004-08-01 21:53:26 +00003765 timeout = 0;
pbrook2e70f6e2008-06-29 01:03:05 +00003766 }
bellard5905b2e2004-08-01 21:53:26 +00003767 } else {
blueswir198448f52008-09-30 18:16:09 +00003768 if (shutdown_requested) {
3769 ret = EXCP_INTERRUPT;
aliguori5b08fc12008-08-21 20:08:03 +00003770 break;
blueswir198448f52008-09-30 18:16:09 +00003771 }
aliguori0a1af392008-10-31 18:40:25 +00003772 timeout = 5000;
bellard5905b2e2004-08-01 21:53:26 +00003773 }
bellard89bfc102006-02-08 22:46:31 +00003774#ifdef CONFIG_PROFILER
3775 ti = profile_getclock();
3776#endif
bellard5905b2e2004-08-01 21:53:26 +00003777 main_loop_wait(timeout);
bellard89bfc102006-02-08 22:46:31 +00003778#ifdef CONFIG_PROFILER
3779 dev_time += profile_getclock() - ti;
3780#endif
bellardb4608c02003-06-27 17:34:32 +00003781 }
bellard34865132003-10-05 14:28:56 +00003782 cpu_disable_ticks();
3783 return ret;
bellardb4608c02003-06-27 17:34:32 +00003784}
3785
ths15f82202007-06-29 23:26:08 +00003786static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00003787{
bellard68d0f702008-01-06 17:21:48 +00003788 printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
bellard0db63472003-10-27 21:37:46 +00003789 "usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00003790 "\n"
bellarda20dd502003-09-30 21:07:02 +00003791 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00003792 "\n"
bellarda20dd502003-09-30 21:07:02 +00003793 "Standard options:\n"
bellardcc1daa42005-06-05 14:49:17 +00003794 "-M machine select emulated machine (-M ? for list)\n"
pbrook5adb4832007-03-08 03:15:18 +00003795 "-cpu cpu select CPU (-cpu ? for list)\n"
bellardc45886d2004-01-05 00:02:06 +00003796 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
bellard36b486b2003-11-11 13:36:08 +00003797 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
3798 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
bellardc4b1fcc2004-03-14 21:44:30 +00003799 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
aurel32a1620fa2008-04-29 05:58:01 +00003800 "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
3801 " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
aliguori9f7965c2008-10-14 14:42:54 +00003802 " [,cache=writethrough|writeback|none][,format=f]\n"
thse4bcb142007-12-02 04:51:10 +00003803 " use 'file' as a drive image\n"
balrog3e3d5812007-04-30 02:09:25 +00003804 "-mtdblock file use 'file' as on-board Flash memory image\n"
pbrooka1bb27b2007-04-06 16:49:48 +00003805 "-sd file use 'file' as SecureDigital card image\n"
j_mayer86f55662007-04-24 06:52:59 +00003806 "-pflash file use 'file' as a parallel flash image\n"
thseec85c22007-01-05 17:41:07 +00003807 "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
ths667acca2006-12-11 02:08:05 +00003808 "-snapshot write to temporary files instead of disk image files\n"
3809#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00003810 "-no-frame open SDL window without a frame and window decorations\n"
ths3780e192007-06-21 21:08:02 +00003811 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
ths667acca2006-12-11 02:08:05 +00003812 "-no-quit disable SDL window close capability\n"
3813#endif
bellard52ca8d62006-06-14 16:03:05 +00003814#ifdef TARGET_I386
3815 "-no-fd-bootchk disable boot signature checking for floppy disks\n"
3816#endif
bellarda00bad72004-05-22 21:39:06 +00003817 "-m megs set virtual RAM size to megs MB [default=%d]\n"
bellard91fc2112005-12-18 19:09:37 +00003818 "-smp n set the number of CPUs to 'n' [default=1]\n"
bellardc4b1fcc2004-03-14 21:44:30 +00003819 "-nographic disable graphical output and redirect serial I/Os to console\n"
balroga171fe32007-04-30 01:48:07 +00003820 "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
bellard4ca00742004-12-12 22:20:04 +00003821#ifndef _WIN32
ths667acca2006-12-11 02:08:05 +00003822 "-k language use keyboard layout (for example \"fr\" for French)\n"
bellard4ca00742004-12-12 22:20:04 +00003823#endif
bellard1d14ffa2005-10-30 18:58:22 +00003824#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00003825 "-audio-help print list of audio drivers and their options\n"
bellardc0fe3822005-11-05 18:55:28 +00003826 "-soundhw c1,... enable audio support\n"
3827 " and only specified sound cards (comma separated list)\n"
3828 " use -soundhw ? to get the list of supported cards\n"
bellard6a36d842005-12-18 20:34:32 +00003829 " use -soundhw all to enable all of them\n"
bellard1d14ffa2005-10-30 18:58:22 +00003830#endif
malc3893c122008-09-28 00:42:05 +00003831 "-vga [std|cirrus|vmware]\n"
3832 " select video card type\n"
bellard89980282004-06-03 14:04:03 +00003833 "-localtime set the real time clock to local time [default=utc]\n"
bellardd63d3072004-10-03 13:29:03 +00003834 "-full-screen start in full screen\n"
bellarda09db212005-04-30 16:10:35 +00003835#ifdef TARGET_I386
3836 "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
3837#endif
bellardb389dbf2005-11-06 16:49:55 +00003838 "-usb enable the USB driver (will be the default soon)\n"
3839 "-usbdevice name add the host or guest USB device 'name'\n"
bellard6f7e9ae2005-03-13 09:43:36 +00003840#if defined(TARGET_PPC) || defined(TARGET_SPARC)
3841 "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
bellardbb0c6722004-06-20 12:37:32 +00003842#endif
thsc35734b2007-03-19 15:17:08 +00003843 "-name string set the name of the guest\n"
blueswir18fcb1b92008-09-18 18:29:08 +00003844 "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
bellarda20dd502003-09-30 21:07:02 +00003845 "\n"
bellardc4b1fcc2004-03-14 21:44:30 +00003846 "Network options:\n"
pbrooka41b2ff2006-02-05 04:14:41 +00003847 "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
bellard7c9d8e02005-11-15 22:16:05 +00003848 " create a new Network Interface Card and connect it to VLAN 'n'\n"
bellardc20709a2004-04-21 23:27:19 +00003849#ifdef CONFIG_SLIRP
pbrook115defd2006-04-16 11:06:58 +00003850 "-net user[,vlan=n][,hostname=host]\n"
3851 " connect the user mode network stack to VLAN 'n' and send\n"
3852 " hostname 'host' to DHCP clients\n"
bellard7c9d8e02005-11-15 22:16:05 +00003853#endif
bellard7fb843f2006-02-01 23:06:55 +00003854#ifdef _WIN32
3855 "-net tap[,vlan=n],ifname=name\n"
3856 " connect the host TAP network interface to VLAN 'n'\n"
3857#else
thsb46a8902007-10-21 23:20:45 +00003858 "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
3859 " connect the host TAP network interface to VLAN 'n' and use the\n"
3860 " network scripts 'file' (default=%s)\n"
3861 " and 'dfile' (default=%s);\n"
3862 " use '[down]script=no' to disable script execution;\n"
bellard7c9d8e02005-11-15 22:16:05 +00003863 " use 'fd=h' to connect to an already opened TAP interface\n"
bellard7fb843f2006-02-01 23:06:55 +00003864#endif
bellard6a00d602005-11-21 23:25:50 +00003865 "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
bellard7c9d8e02005-11-15 22:16:05 +00003866 " connect the vlan 'n' to another VLAN using a socket connection\n"
bellard3d830452005-12-18 16:36:49 +00003867 "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
3868 " connect the vlan 'n' to multicast maddr and port\n"
ths8a16d272008-07-19 09:56:24 +00003869#ifdef CONFIG_VDE
3870 "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
3871 " connect the vlan 'n' to port 'n' of a vde switch running\n"
3872 " on host and listening for incoming connections on 'socketpath'.\n"
3873 " Use group 'groupname' and mode 'octalmode' to change default\n"
3874 " ownership and permissions for communication port.\n"
3875#endif
bellard7c9d8e02005-11-15 22:16:05 +00003876 "-net none use it alone to have zero network devices; if no -net option\n"
3877 " is provided, the default is '-net nic -net user'\n"
3878 "\n"
balrogdc72ac12008-11-09 00:04:26 +00003879 "-bt hci,null Dumb bluetooth HCI - doesn't respond to commands\n"
3880 "-bt hci,host[:id]\n"
3881 " Use host's HCI with the given name\n"
3882 "-bt hci[,vlan=n]\n"
3883 " Emulate a standard HCI in virtual scatternet 'n'\n"
3884 "-bt vhci[,vlan=n]\n"
3885 " Add host computer to virtual scatternet 'n' using VHCI\n"
3886 "-bt device:dev[,vlan=n]\n"
3887 " Emulate a bluetooth device 'dev' in scatternet 'n'\n"
3888 "\n"
bellard7c9d8e02005-11-15 22:16:05 +00003889#ifdef CONFIG_SLIRP
ths0db11372007-02-20 00:12:07 +00003890 "-tftp dir allow tftp access to files in dir [-net user]\n"
ths47d5d012007-02-20 00:05:08 +00003891 "-bootp file advertise file in BOOTP replies\n"
bellard7c9d8e02005-11-15 22:16:05 +00003892#ifndef _WIN32
3893 "-smb dir allow SMB access to files in 'dir' [-net user]\n"
bellardc94c8d62004-09-13 21:37:34 +00003894#endif
bellard9bf05442004-08-25 22:12:49 +00003895 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
bellard7c9d8e02005-11-15 22:16:05 +00003896 " redirect TCP or UDP connections from host to guest [-net user]\n"
bellardc20709a2004-04-21 23:27:19 +00003897#endif
bellardc4b1fcc2004-03-14 21:44:30 +00003898 "\n"
3899 "Linux boot specific:\n"
bellarda20dd502003-09-30 21:07:02 +00003900 "-kernel bzImage use 'bzImage' as kernel image\n"
3901 "-append cmdline use 'cmdline' as kernel command line\n"
3902 "-initrd file use 'file' as initial ram disk\n"
bellardfc01f7e2003-06-30 10:03:06 +00003903 "\n"
bellard330d0412003-07-26 18:11:40 +00003904 "Debug/Expert options:\n"
bellard82c643f2004-07-14 17:28:13 +00003905 "-monitor dev redirect the monitor to char device 'dev'\n"
3906 "-serial dev redirect the serial port to char device 'dev'\n"
bellard6508fe52005-01-15 12:02:56 +00003907 "-parallel dev redirect the parallel port to char device 'dev'\n"
bellardf7cce892004-12-08 22:21:25 +00003908 "-pidfile file Write PID to 'file'\n"
bellardcd6f1162004-05-13 22:02:20 +00003909 "-S freeze CPU at startup (use 'c' to start execution)\n"
pbrookcfc34752007-02-22 01:48:01 +00003910 "-s wait gdb connection to port\n"
3911 "-p port set gdb connection port [default=%s]\n"
bellardf193c792004-03-21 17:06:25 +00003912 "-d item1,... output log to %s (use -d ? for a list of log items)\n"
bellard46d47672004-11-16 01:45:27 +00003913 "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
3914 " translation (t=none or lba) (usually qemu can guess them)\n"
bellard87b47352006-08-17 17:22:54 +00003915 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
bellardd993e022005-02-10 22:00:06 +00003916#ifdef USE_KQEMU
bellard6515b202006-05-03 22:02:44 +00003917 "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
bellardd993e022005-02-10 22:00:06 +00003918 "-no-kqemu disable KQEMU kernel module usage\n"
3919#endif
aliguori7ba1e612008-11-05 16:04:33 +00003920#ifdef CONFIG_KVM
3921 "-enable-kvm enable KVM full virtualization support\n"
3922#endif
bellardbb0c6722004-06-20 12:37:32 +00003923#ifdef TARGET_I386
bellard6515b202006-05-03 22:02:44 +00003924 "-no-acpi disable ACPI\n"
bellardbb0c6722004-06-20 12:37:32 +00003925#endif
balrog4d3b6f62008-02-10 16:33:14 +00003926#ifdef CONFIG_CURSES
3927 "-curses use a curses/ncurses interface instead of SDL\n"
3928#endif
bellardd1beab82006-10-02 19:44:22 +00003929 "-no-reboot exit instead of rebooting\n"
aurel32b2f76162008-04-11 21:35:52 +00003930 "-no-shutdown stop before shutdown\n"
aurel32a8080002008-05-10 23:28:26 +00003931 "-loadvm [tag|id] start right away with a saved state (loadvm in monitor)\n"
bellard24236862006-04-30 21:28:36 +00003932 "-vnc display start a VNC server on display\n"
ths71e3ceb2006-12-22 02:11:31 +00003933#ifndef _WIN32
3934 "-daemonize daemonize QEMU after initializing\n"
3935#endif
ths9ae02552007-01-05 17:39:04 +00003936 "-option-rom rom load a file, rom, into the option ROM space\n"
blueswir166508602007-05-01 14:16:52 +00003937#ifdef TARGET_SPARC
3938 "-prom-env variable=value set OpenBIOS nvram variables\n"
3939#endif
thsf3dcfad2007-08-24 01:26:02 +00003940 "-clock force the use of the given methods for timer alarm.\n"
aurel323adda042008-03-09 23:43:49 +00003941 " To see what timers are available use -clock ?\n"
bellardbce61842008-02-01 22:18:51 +00003942 "-startdate select initial date of the clock\n"
pbrook2e70f6e2008-06-29 01:03:05 +00003943 "-icount [N|auto]\n"
pbrookdd5d6fe2008-06-29 10:43:16 +00003944 " Enable virtual instruction counter with 2^N clock ticks per instruction\n"
bellard0824d6f2003-06-24 13:42:40 +00003945 "\n"
bellard82c643f2004-07-14 17:28:13 +00003946 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00003947 "ctrl-alt-f toggle full screen\n"
3948 "ctrl-alt-n switch to virtual console 'n'\n"
3949 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00003950 "\n"
3951 "When using -nographic, press 'ctrl-a h' to get some help.\n"
3952 ,
bellard0db63472003-10-27 21:37:46 +00003953 "qemu",
bellarda00bad72004-05-22 21:39:06 +00003954 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00003955#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00003956 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00003957 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00003958#endif
bellard6e44ba72004-01-18 21:56:49 +00003959 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00003960 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00003961 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00003962}
3963
bellardcd6f1162004-05-13 22:02:20 +00003964#define HAS_ARG 0x0001
3965
3966enum {
3967 QEMU_OPTION_h,
3968
bellardcc1daa42005-06-05 14:49:17 +00003969 QEMU_OPTION_M,
j_mayer94fc95c2007-03-05 19:44:02 +00003970 QEMU_OPTION_cpu,
bellardcd6f1162004-05-13 22:02:20 +00003971 QEMU_OPTION_fda,
3972 QEMU_OPTION_fdb,
3973 QEMU_OPTION_hda,
3974 QEMU_OPTION_hdb,
3975 QEMU_OPTION_hdc,
3976 QEMU_OPTION_hdd,
thse4bcb142007-12-02 04:51:10 +00003977 QEMU_OPTION_drive,
bellardcd6f1162004-05-13 22:02:20 +00003978 QEMU_OPTION_cdrom,
balrog3e3d5812007-04-30 02:09:25 +00003979 QEMU_OPTION_mtdblock,
pbrooka1bb27b2007-04-06 16:49:48 +00003980 QEMU_OPTION_sd,
j_mayer86f55662007-04-24 06:52:59 +00003981 QEMU_OPTION_pflash,
bellardcd6f1162004-05-13 22:02:20 +00003982 QEMU_OPTION_boot,
3983 QEMU_OPTION_snapshot,
bellard52ca8d62006-06-14 16:03:05 +00003984#ifdef TARGET_I386
3985 QEMU_OPTION_no_fd_bootchk,
3986#endif
bellardcd6f1162004-05-13 22:02:20 +00003987 QEMU_OPTION_m,
3988 QEMU_OPTION_nographic,
balroga171fe32007-04-30 01:48:07 +00003989 QEMU_OPTION_portrait,
bellard1d14ffa2005-10-30 18:58:22 +00003990#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00003991 QEMU_OPTION_audio_help,
3992 QEMU_OPTION_soundhw,
3993#endif
bellardcd6f1162004-05-13 22:02:20 +00003994
bellard7c9d8e02005-11-15 22:16:05 +00003995 QEMU_OPTION_net,
bellardc7f74642004-08-24 21:57:12 +00003996 QEMU_OPTION_tftp,
ths47d5d012007-02-20 00:05:08 +00003997 QEMU_OPTION_bootp,
bellard9d728e82004-09-05 23:09:03 +00003998 QEMU_OPTION_smb,
bellard9bf05442004-08-25 22:12:49 +00003999 QEMU_OPTION_redir,
balrogdc72ac12008-11-09 00:04:26 +00004000 QEMU_OPTION_bt,
bellardcd6f1162004-05-13 22:02:20 +00004001
4002 QEMU_OPTION_kernel,
4003 QEMU_OPTION_append,
4004 QEMU_OPTION_initrd,
4005
4006 QEMU_OPTION_S,
4007 QEMU_OPTION_s,
4008 QEMU_OPTION_p,
4009 QEMU_OPTION_d,
4010 QEMU_OPTION_hdachs,
4011 QEMU_OPTION_L,
j_mayer1192dad2007-10-05 13:08:35 +00004012 QEMU_OPTION_bios,
bellard3d11d0e2004-12-12 16:56:30 +00004013 QEMU_OPTION_k,
bellardee22c2f2004-06-03 12:49:50 +00004014 QEMU_OPTION_localtime,
bellarde9b137c2004-06-21 16:46:10 +00004015 QEMU_OPTION_g,
malc3893c122008-09-28 00:42:05 +00004016 QEMU_OPTION_vga,
ths20d8a3e2007-02-18 17:04:49 +00004017 QEMU_OPTION_echr,
bellard82c643f2004-07-14 17:28:13 +00004018 QEMU_OPTION_monitor,
4019 QEMU_OPTION_serial,
bellard6508fe52005-01-15 12:02:56 +00004020 QEMU_OPTION_parallel,
bellardd63d3072004-10-03 13:29:03 +00004021 QEMU_OPTION_loadvm,
4022 QEMU_OPTION_full_screen,
ths43523e92007-02-18 18:19:32 +00004023 QEMU_OPTION_no_frame,
ths3780e192007-06-21 21:08:02 +00004024 QEMU_OPTION_alt_grab,
ths667acca2006-12-11 02:08:05 +00004025 QEMU_OPTION_no_quit,
bellardf7cce892004-12-08 22:21:25 +00004026 QEMU_OPTION_pidfile,
bellardd993e022005-02-10 22:00:06 +00004027 QEMU_OPTION_no_kqemu,
bellard89bfc102006-02-08 22:46:31 +00004028 QEMU_OPTION_kernel_kqemu,
aliguori7ba1e612008-11-05 16:04:33 +00004029 QEMU_OPTION_enable_kvm,
bellarda09db212005-04-30 16:10:35 +00004030 QEMU_OPTION_win2k_hack,
bellardbb36d472005-11-05 14:22:28 +00004031 QEMU_OPTION_usb,
bellarda594cfb2005-11-06 16:13:29 +00004032 QEMU_OPTION_usbdevice,
bellard6a00d602005-11-21 23:25:50 +00004033 QEMU_OPTION_smp,
bellard24236862006-04-30 21:28:36 +00004034 QEMU_OPTION_vnc,
bellard6515b202006-05-03 22:02:44 +00004035 QEMU_OPTION_no_acpi,
balrog4d3b6f62008-02-10 16:33:14 +00004036 QEMU_OPTION_curses,
bellardd1beab82006-10-02 19:44:22 +00004037 QEMU_OPTION_no_reboot,
aurel32b2f76162008-04-11 21:35:52 +00004038 QEMU_OPTION_no_shutdown,
balrog9467cd42007-05-01 01:34:14 +00004039 QEMU_OPTION_show_cursor,
ths71e3ceb2006-12-22 02:11:31 +00004040 QEMU_OPTION_daemonize,
ths9ae02552007-01-05 17:39:04 +00004041 QEMU_OPTION_option_rom,
thsc35734b2007-03-19 15:17:08 +00004042 QEMU_OPTION_semihosting,
4043 QEMU_OPTION_name,
blueswir166508602007-05-01 14:16:52 +00004044 QEMU_OPTION_prom_env,
balrog2b8f2d42007-07-27 22:08:46 +00004045 QEMU_OPTION_old_param,
thsf3dcfad2007-08-24 01:26:02 +00004046 QEMU_OPTION_clock,
bellard7e0af5d02007-11-07 16:24:33 +00004047 QEMU_OPTION_startdate,
bellard26a5f132008-05-28 12:30:31 +00004048 QEMU_OPTION_tb_size,
pbrook2e70f6e2008-06-29 01:03:05 +00004049 QEMU_OPTION_icount,
blueswir18fcb1b92008-09-18 18:29:08 +00004050 QEMU_OPTION_uuid,
aliguori5bb79102008-10-13 03:12:02 +00004051 QEMU_OPTION_incoming,
bellardcd6f1162004-05-13 22:02:20 +00004052};
4053
4054typedef struct QEMUOption {
4055 const char *name;
4056 int flags;
4057 int index;
4058} QEMUOption;
4059
blueswir1dbed7e42008-10-01 19:38:09 +00004060static const QEMUOption qemu_options[] = {
bellardcd6f1162004-05-13 22:02:20 +00004061 { "h", 0, QEMU_OPTION_h },
pbrook64423fb2007-01-27 17:11:41 +00004062 { "help", 0, QEMU_OPTION_h },
bellardcd6f1162004-05-13 22:02:20 +00004063
bellardcc1daa42005-06-05 14:49:17 +00004064 { "M", HAS_ARG, QEMU_OPTION_M },
j_mayer94fc95c2007-03-05 19:44:02 +00004065 { "cpu", HAS_ARG, QEMU_OPTION_cpu },
bellardcd6f1162004-05-13 22:02:20 +00004066 { "fda", HAS_ARG, QEMU_OPTION_fda },
4067 { "fdb", HAS_ARG, QEMU_OPTION_fdb },
4068 { "hda", HAS_ARG, QEMU_OPTION_hda },
4069 { "hdb", HAS_ARG, QEMU_OPTION_hdb },
4070 { "hdc", HAS_ARG, QEMU_OPTION_hdc },
4071 { "hdd", HAS_ARG, QEMU_OPTION_hdd },
thse4bcb142007-12-02 04:51:10 +00004072 { "drive", HAS_ARG, QEMU_OPTION_drive },
bellardcd6f1162004-05-13 22:02:20 +00004073 { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
balrog3e3d5812007-04-30 02:09:25 +00004074 { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
pbrooka1bb27b2007-04-06 16:49:48 +00004075 { "sd", HAS_ARG, QEMU_OPTION_sd },
j_mayer86f55662007-04-24 06:52:59 +00004076 { "pflash", HAS_ARG, QEMU_OPTION_pflash },
bellardcd6f1162004-05-13 22:02:20 +00004077 { "boot", HAS_ARG, QEMU_OPTION_boot },
4078 { "snapshot", 0, QEMU_OPTION_snapshot },
bellard52ca8d62006-06-14 16:03:05 +00004079#ifdef TARGET_I386
4080 { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
4081#endif
bellardcd6f1162004-05-13 22:02:20 +00004082 { "m", HAS_ARG, QEMU_OPTION_m },
4083 { "nographic", 0, QEMU_OPTION_nographic },
balroga171fe32007-04-30 01:48:07 +00004084 { "portrait", 0, QEMU_OPTION_portrait },
bellard3d11d0e2004-12-12 16:56:30 +00004085 { "k", HAS_ARG, QEMU_OPTION_k },
bellard1d14ffa2005-10-30 18:58:22 +00004086#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00004087 { "audio-help", 0, QEMU_OPTION_audio_help },
4088 { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
4089#endif
bellardcd6f1162004-05-13 22:02:20 +00004090
bellard7c9d8e02005-11-15 22:16:05 +00004091 { "net", HAS_ARG, QEMU_OPTION_net},
bellard158156d2004-05-17 21:13:42 +00004092#ifdef CONFIG_SLIRP
bellardc7f74642004-08-24 21:57:12 +00004093 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
ths47d5d012007-02-20 00:05:08 +00004094 { "bootp", HAS_ARG, QEMU_OPTION_bootp },
bellardc94c8d62004-09-13 21:37:34 +00004095#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00004096 { "smb", HAS_ARG, QEMU_OPTION_smb },
bellardc94c8d62004-09-13 21:37:34 +00004097#endif
bellard9bf05442004-08-25 22:12:49 +00004098 { "redir", HAS_ARG, QEMU_OPTION_redir },
bellard158156d2004-05-17 21:13:42 +00004099#endif
balrogdc72ac12008-11-09 00:04:26 +00004100 { "bt", HAS_ARG, QEMU_OPTION_bt },
bellardcd6f1162004-05-13 22:02:20 +00004101
4102 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
4103 { "append", HAS_ARG, QEMU_OPTION_append },
4104 { "initrd", HAS_ARG, QEMU_OPTION_initrd },
4105
4106 { "S", 0, QEMU_OPTION_S },
4107 { "s", 0, QEMU_OPTION_s },
4108 { "p", HAS_ARG, QEMU_OPTION_p },
4109 { "d", HAS_ARG, QEMU_OPTION_d },
4110 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
4111 { "L", HAS_ARG, QEMU_OPTION_L },
j_mayer1192dad2007-10-05 13:08:35 +00004112 { "bios", HAS_ARG, QEMU_OPTION_bios },
bellardd993e022005-02-10 22:00:06 +00004113#ifdef USE_KQEMU
4114 { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
bellard89bfc102006-02-08 22:46:31 +00004115 { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
bellardd993e022005-02-10 22:00:06 +00004116#endif
aliguori7ba1e612008-11-05 16:04:33 +00004117#ifdef CONFIG_KVM
4118 { "enable-kvm", 0, QEMU_OPTION_enable_kvm },
4119#endif
bellard6f7e9ae2005-03-13 09:43:36 +00004120#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00004121 { "g", 1, QEMU_OPTION_g },
bellard77d4bc32004-05-26 22:13:53 +00004122#endif
bellardee22c2f2004-06-03 12:49:50 +00004123 { "localtime", 0, QEMU_OPTION_localtime },
malc3893c122008-09-28 00:42:05 +00004124 { "vga", HAS_ARG, QEMU_OPTION_vga },
balrog8b6e0722007-06-22 08:23:44 +00004125 { "echr", HAS_ARG, QEMU_OPTION_echr },
4126 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
4127 { "serial", HAS_ARG, QEMU_OPTION_serial },
4128 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
bellardd63d3072004-10-03 13:29:03 +00004129 { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
4130 { "full-screen", 0, QEMU_OPTION_full_screen },
ths667acca2006-12-11 02:08:05 +00004131#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00004132 { "no-frame", 0, QEMU_OPTION_no_frame },
ths3780e192007-06-21 21:08:02 +00004133 { "alt-grab", 0, QEMU_OPTION_alt_grab },
ths667acca2006-12-11 02:08:05 +00004134 { "no-quit", 0, QEMU_OPTION_no_quit },
4135#endif
bellardf7cce892004-12-08 22:21:25 +00004136 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
bellarda09db212005-04-30 16:10:35 +00004137 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
bellarda594cfb2005-11-06 16:13:29 +00004138 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
bellard6a00d602005-11-21 23:25:50 +00004139 { "smp", HAS_ARG, QEMU_OPTION_smp },
bellard24236862006-04-30 21:28:36 +00004140 { "vnc", HAS_ARG, QEMU_OPTION_vnc },
balrog4d3b6f62008-02-10 16:33:14 +00004141#ifdef CONFIG_CURSES
4142 { "curses", 0, QEMU_OPTION_curses },
4143#endif
blueswir18fcb1b92008-09-18 18:29:08 +00004144 { "uuid", HAS_ARG, QEMU_OPTION_uuid },
ths96d30e42007-01-07 20:42:14 +00004145
bellard1f042752004-06-05 13:46:47 +00004146 /* temporary options */
bellarda594cfb2005-11-06 16:13:29 +00004147 { "usb", 0, QEMU_OPTION_usb },
bellard6515b202006-05-03 22:02:44 +00004148 { "no-acpi", 0, QEMU_OPTION_no_acpi },
bellardd1beab82006-10-02 19:44:22 +00004149 { "no-reboot", 0, QEMU_OPTION_no_reboot },
aurel32b2f76162008-04-11 21:35:52 +00004150 { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
balrog9467cd42007-05-01 01:34:14 +00004151 { "show-cursor", 0, QEMU_OPTION_show_cursor },
ths71e3ceb2006-12-22 02:11:31 +00004152 { "daemonize", 0, QEMU_OPTION_daemonize },
ths9ae02552007-01-05 17:39:04 +00004153 { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
pbrooka87295e2007-05-26 15:09:38 +00004154#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00004155 { "semihosting", 0, QEMU_OPTION_semihosting },
4156#endif
thsc35734b2007-03-19 15:17:08 +00004157 { "name", HAS_ARG, QEMU_OPTION_name },
blueswir166508602007-05-01 14:16:52 +00004158#if defined(TARGET_SPARC)
4159 { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
4160#endif
balrog2b8f2d42007-07-27 22:08:46 +00004161#if defined(TARGET_ARM)
4162 { "old-param", 0, QEMU_OPTION_old_param },
4163#endif
thsf3dcfad2007-08-24 01:26:02 +00004164 { "clock", HAS_ARG, QEMU_OPTION_clock },
bellard7e0af5d02007-11-07 16:24:33 +00004165 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
bellard26a5f132008-05-28 12:30:31 +00004166 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
pbrook2e70f6e2008-06-29 01:03:05 +00004167 { "icount", HAS_ARG, QEMU_OPTION_icount },
aliguori5bb79102008-10-13 03:12:02 +00004168 { "incoming", HAS_ARG, QEMU_OPTION_incoming },
bellardcd6f1162004-05-13 22:02:20 +00004169 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00004170};
4171
bellard5905b2e2004-08-01 21:53:26 +00004172/* password input */
4173
balrog2bac6012007-04-30 01:34:31 +00004174int qemu_key_check(BlockDriverState *bs, const char *name)
4175{
4176 char password[256];
4177 int i;
4178
4179 if (!bdrv_is_encrypted(bs))
4180 return 0;
4181
4182 term_printf("%s is encrypted.\n", name);
4183 for(i = 0; i < 3; i++) {
4184 monitor_readline("Password: ", 1, password, sizeof(password));
4185 if (bdrv_set_key(bs, password) == 0)
4186 return 0;
4187 term_printf("invalid password\n");
4188 }
4189 return -EPERM;
4190}
4191
aliguori83ab7952008-08-19 14:44:22 +00004192static BlockDriverState *get_bdrv(int index)
4193{
4194 if (index > nb_drives)
4195 return NULL;
4196 return drives_table[index].bdrv;
4197}
4198
bellard5905b2e2004-08-01 21:53:26 +00004199static void read_passwords(void)
4200{
4201 BlockDriverState *bs;
balrog2bac6012007-04-30 01:34:31 +00004202 int i;
bellard5905b2e2004-08-01 21:53:26 +00004203
aliguori83ab7952008-08-19 14:44:22 +00004204 for(i = 0; i < 6; i++) {
4205 bs = get_bdrv(i);
4206 if (bs)
4207 qemu_key_check(bs, bdrv_get_device_name(bs));
bellard5905b2e2004-08-01 21:53:26 +00004208 }
4209}
4210
bellard1d14ffa2005-10-30 18:58:22 +00004211#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00004212struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00004213#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00004214#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00004215 {
4216 "pcspk",
4217 "PC speaker",
4218 0,
4219 1,
4220 { .init_isa = pcspk_audio_init }
4221 },
4222#endif
bellard6a36d842005-12-18 20:34:32 +00004223 {
4224 "sb16",
4225 "Creative Sound Blaster 16",
4226 0,
4227 1,
4228 { .init_isa = SB16_init }
4229 },
4230
malccc53d262008-06-13 10:48:22 +00004231#ifdef CONFIG_CS4231A
4232 {
4233 "cs4231a",
4234 "CS4231A",
4235 0,
4236 1,
4237 { .init_isa = cs4231a_init }
4238 },
4239#endif
4240
bellard6a36d842005-12-18 20:34:32 +00004241#ifdef CONFIG_ADLIB
4242 {
4243 "adlib",
4244#ifdef HAS_YMF262
4245 "Yamaha YMF262 (OPL3)",
4246#else
4247 "Yamaha YM3812 (OPL2)",
4248#endif
4249 0,
4250 1,
4251 { .init_isa = Adlib_init }
4252 },
4253#endif
4254
4255#ifdef CONFIG_GUS
4256 {
4257 "gus",
4258 "Gravis Ultrasound GF1",
4259 0,
4260 1,
4261 { .init_isa = GUS_init }
4262 },
4263#endif
4264
balroge5c9a132008-01-14 04:27:55 +00004265#ifdef CONFIG_AC97
4266 {
4267 "ac97",
4268 "Intel 82801AA AC97 Audio",
4269 0,
4270 0,
4271 { .init_pci = ac97_init }
4272 },
4273#endif
4274
bellard6a36d842005-12-18 20:34:32 +00004275 {
4276 "es1370",
4277 "ENSONIQ AudioPCI ES1370",
4278 0,
4279 0,
4280 { .init_pci = es1370_init }
4281 },
balrogb00052e2007-04-30 02:22:06 +00004282#endif
bellard6a36d842005-12-18 20:34:32 +00004283
4284 { NULL, NULL, 0, 0, { NULL } }
4285};
4286
bellard1d14ffa2005-10-30 18:58:22 +00004287static void select_soundhw (const char *optarg)
4288{
bellard6a36d842005-12-18 20:34:32 +00004289 struct soundhw *c;
4290
bellard1d14ffa2005-10-30 18:58:22 +00004291 if (*optarg == '?') {
4292 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00004293
bellard1d14ffa2005-10-30 18:58:22 +00004294 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00004295 for (c = soundhw; c->name; ++c) {
4296 printf ("%-11s %s\n", c->name, c->descr);
4297 }
4298 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00004299 exit (*optarg != '?');
4300 }
4301 else {
bellard6a36d842005-12-18 20:34:32 +00004302 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00004303 const char *p;
4304 char *e;
4305 int bad_card = 0;
4306
bellard6a36d842005-12-18 20:34:32 +00004307 if (!strcmp (optarg, "all")) {
4308 for (c = soundhw; c->name; ++c) {
4309 c->enabled = 1;
4310 }
4311 return;
4312 }
bellard1d14ffa2005-10-30 18:58:22 +00004313
bellard6a36d842005-12-18 20:34:32 +00004314 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00004315 while (*p) {
4316 e = strchr (p, ',');
4317 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00004318
4319 for (c = soundhw; c->name; ++c) {
4320 if (!strncmp (c->name, p, l)) {
4321 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00004322 break;
4323 }
4324 }
bellard6a36d842005-12-18 20:34:32 +00004325
4326 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00004327 if (l > 80) {
4328 fprintf (stderr,
4329 "Unknown sound card name (too big to show)\n");
4330 }
4331 else {
4332 fprintf (stderr, "Unknown sound card name `%.*s'\n",
4333 (int) l, p);
4334 }
4335 bad_card = 1;
4336 }
4337 p += l + (e != NULL);
4338 }
4339
4340 if (bad_card)
4341 goto show_valid_cards;
4342 }
4343}
4344#endif
4345
malc3893c122008-09-28 00:42:05 +00004346static void select_vgahw (const char *p)
4347{
4348 const char *opts;
4349
4350 if (strstart(p, "std", &opts)) {
4351 cirrus_vga_enabled = 0;
4352 vmsvga_enabled = 0;
4353 } else if (strstart(p, "cirrus", &opts)) {
4354 cirrus_vga_enabled = 1;
4355 vmsvga_enabled = 0;
4356 } else if (strstart(p, "vmware", &opts)) {
4357 cirrus_vga_enabled = 0;
4358 vmsvga_enabled = 1;
4359 } else {
4360 invalid_vga:
4361 fprintf(stderr, "Unknown vga type: %s\n", p);
4362 exit(1);
4363 }
malccb5a7aa2008-09-28 00:42:12 +00004364 while (*opts) {
4365 const char *nextopt;
4366
4367 if (strstart(opts, ",retrace=", &nextopt)) {
4368 opts = nextopt;
4369 if (strstart(opts, "dumb", &nextopt))
4370 vga_retrace_method = VGA_RETRACE_DUMB;
4371 else if (strstart(opts, "precise", &nextopt))
4372 vga_retrace_method = VGA_RETRACE_PRECISE;
4373 else goto invalid_vga;
4374 } else goto invalid_vga;
4375 opts = nextopt;
4376 }
malc3893c122008-09-28 00:42:05 +00004377}
4378
bellard3587d7e2006-06-26 20:03:44 +00004379#ifdef _WIN32
4380static BOOL WINAPI qemu_ctrl_handler(DWORD type)
4381{
4382 exit(STATUS_CONTROL_C_EXIT);
4383 return TRUE;
4384}
4385#endif
4386
blueswir18fcb1b92008-09-18 18:29:08 +00004387static int qemu_uuid_parse(const char *str, uint8_t *uuid)
4388{
4389 int ret;
4390
4391 if(strlen(str) != 36)
4392 return -1;
4393
4394 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
4395 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
4396 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
4397
4398 if(ret != 16)
4399 return -1;
4400
4401 return 0;
4402}
4403
bellard7c9d8e02005-11-15 22:16:05 +00004404#define MAX_NET_CLIENTS 32
bellardc20709a2004-04-21 23:27:19 +00004405
aliguori5b08fc12008-08-21 20:08:03 +00004406#ifndef _WIN32
4407
4408static void termsig_handler(int signal)
4409{
4410 qemu_system_shutdown_request();
4411}
4412
blueswir16f9e3802008-09-09 18:56:59 +00004413static void termsig_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00004414{
4415 struct sigaction act;
4416
4417 memset(&act, 0, sizeof(act));
4418 act.sa_handler = termsig_handler;
4419 sigaction(SIGINT, &act, NULL);
4420 sigaction(SIGHUP, &act, NULL);
4421 sigaction(SIGTERM, &act, NULL);
4422}
4423
4424#endif
4425
bellard0824d6f2003-06-24 13:42:40 +00004426int main(int argc, char **argv)
4427{
bellard67b915a2004-03-31 23:37:16 +00004428#ifdef CONFIG_GDBSTUB
pbrookcfc34752007-02-22 01:48:01 +00004429 int use_gdbstub;
4430 const char *gdbstub_port;
bellard67b915a2004-03-31 23:37:16 +00004431#endif
j_mayer28c5af52007-11-11 01:50:45 +00004432 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00004433 int i;
j_mayer28c5af52007-11-11 01:50:45 +00004434 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00004435 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00004436 const char *kernel_filename, *kernel_cmdline;
j_mayer28c5af52007-11-11 01:50:45 +00004437 const char *boot_devices = "";
bellard313aa562003-08-10 21:52:11 +00004438 DisplayState *ds = &display_state;
bellard46d47672004-11-16 01:45:27 +00004439 int cyls, heads, secs, translation;
pbrookfd5f3932008-03-26 20:55:43 +00004440 const char *net_clients[MAX_NET_CLIENTS];
bellard7c9d8e02005-11-15 22:16:05 +00004441 int nb_net_clients;
balrogdc72ac12008-11-09 00:04:26 +00004442 const char *bt_opts[MAX_BT_CMDLINE];
4443 int nb_bt_opts;
thse4bcb142007-12-02 04:51:10 +00004444 int hda_index;
bellardcd6f1162004-05-13 22:02:20 +00004445 int optind;
4446 const char *r, *optarg;
bellard82c643f2004-07-14 17:28:13 +00004447 CharDriverState *monitor_hd;
pbrookfd5f3932008-03-26 20:55:43 +00004448 const char *monitor_device;
4449 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00004450 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00004451 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00004452 int parallel_device_index;
bellardd63d3072004-10-03 13:29:03 +00004453 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00004454 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00004455 const char *cpu_model;
pbrookfd5f3932008-03-26 20:55:43 +00004456 const char *usb_devices[MAX_USB_CMDLINE];
bellarda594cfb2005-11-06 16:13:29 +00004457 int usb_devices_index;
ths71e3ceb2006-12-22 02:11:31 +00004458 int fds[2];
bellard26a5f132008-05-28 12:30:31 +00004459 int tb_size;
ths93815bc2007-03-19 15:58:31 +00004460 const char *pid_file = NULL;
blueswir141bd6392008-10-05 09:56:21 +00004461 int autostart;
aliguori5bb79102008-10-13 03:12:02 +00004462 const char *incoming = NULL;
bellard0bd48852005-11-11 00:00:47 +00004463
4464 LIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00004465#ifndef _WIN32
4466 {
4467 struct sigaction act;
4468 sigfillset(&act.sa_mask);
4469 act.sa_flags = 0;
4470 act.sa_handler = SIG_IGN;
4471 sigaction(SIGPIPE, &act, NULL);
4472 }
bellard3587d7e2006-06-26 20:03:44 +00004473#else
4474 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00004475 /* Note: cpu_interrupt() is currently not SMP safe, so we force
4476 QEMU to run on a single CPU */
4477 {
4478 HANDLE h;
4479 DWORD mask, smask;
4480 int i;
4481 h = GetCurrentProcess();
4482 if (GetProcessAffinityMask(h, &mask, &smask)) {
4483 for(i = 0; i < 32; i++) {
4484 if (mask & (1 << i))
4485 break;
4486 }
4487 if (i != 32) {
4488 mask = 1 << i;
4489 SetProcessAffinityMask(h, mask);
4490 }
4491 }
4492 }
bellard67b915a2004-03-31 23:37:16 +00004493#endif
bellardbe995c22006-06-25 16:25:21 +00004494
bellardcc1daa42005-06-05 14:49:17 +00004495 register_machines();
4496 machine = first_machine;
j_mayer94fc95c2007-03-05 19:44:02 +00004497 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00004498 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00004499 ram_size = 0;
bellard313aa562003-08-10 21:52:11 +00004500 vga_ram_size = VGA_RAM_SIZE;
bellard67b915a2004-03-31 23:37:16 +00004501#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00004502 use_gdbstub = 0;
bellardc636bb62007-02-05 20:46:05 +00004503 gdbstub_port = DEFAULT_GDBSTUB_PORT;
bellard67b915a2004-03-31 23:37:16 +00004504#endif
bellard33e39632003-07-06 17:15:21 +00004505 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00004506 nographic = 0;
balrog4d3b6f62008-02-10 16:33:14 +00004507 curses = 0;
bellarda20dd502003-09-30 21:07:02 +00004508 kernel_filename = NULL;
4509 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00004510 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00004511 translation = BIOS_ATA_TRANSLATION_AUTO;
pbrookc60e08d2008-07-01 16:24:38 +00004512 monitor_device = "vc";
bellardc4b1fcc2004-03-14 21:44:30 +00004513
aurel32c75a8232008-05-04 00:50:34 +00004514 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00004515 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004516 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00004517 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004518
aurel32c75a8232008-05-04 00:50:34 +00004519 parallel_devices[0] = "vc:640x480";
bellard6508fe52005-01-15 12:02:56 +00004520 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00004521 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00004522 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00004523
bellarda594cfb2005-11-06 16:13:29 +00004524 usb_devices_index = 0;
ths3b46e622007-09-17 08:09:54 +00004525
bellard7c9d8e02005-11-15 22:16:05 +00004526 nb_net_clients = 0;
balrogdc72ac12008-11-09 00:04:26 +00004527 nb_bt_opts = 0;
thse4bcb142007-12-02 04:51:10 +00004528 nb_drives = 0;
4529 nb_drives_opt = 0;
4530 hda_index = -1;
bellard7c9d8e02005-11-15 22:16:05 +00004531
4532 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00004533
bellard26a5f132008-05-28 12:30:31 +00004534 tb_size = 0;
blueswir141bd6392008-10-05 09:56:21 +00004535 autostart= 1;
4536
bellardcd6f1162004-05-13 22:02:20 +00004537 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00004538 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00004539 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00004540 break;
bellardcd6f1162004-05-13 22:02:20 +00004541 r = argv[optind];
4542 if (r[0] != '-') {
balrog609497a2008-01-14 02:56:53 +00004543 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00004544 } else {
4545 const QEMUOption *popt;
4546
4547 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00004548 /* Treat --foo the same as -foo. */
4549 if (r[1] == '-')
4550 r++;
bellardcd6f1162004-05-13 22:02:20 +00004551 popt = qemu_options;
4552 for(;;) {
4553 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00004554 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00004555 argv[0], r);
4556 exit(1);
4557 }
4558 if (!strcmp(popt->name, r + 1))
4559 break;
4560 popt++;
4561 }
4562 if (popt->flags & HAS_ARG) {
4563 if (optind >= argc) {
4564 fprintf(stderr, "%s: option '%s' requires an argument\n",
4565 argv[0], r);
4566 exit(1);
4567 }
4568 optarg = argv[optind++];
4569 } else {
4570 optarg = NULL;
4571 }
4572
4573 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00004574 case QEMU_OPTION_M:
4575 machine = find_machine(optarg);
4576 if (!machine) {
4577 QEMUMachine *m;
4578 printf("Supported machines are:\n");
4579 for(m = first_machine; m != NULL; m = m->next) {
4580 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00004581 m->name, m->desc,
bellardcc1daa42005-06-05 14:49:17 +00004582 m == first_machine ? " (default)" : "");
4583 }
ths15f82202007-06-29 23:26:08 +00004584 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00004585 }
4586 break;
j_mayer94fc95c2007-03-05 19:44:02 +00004587 case QEMU_OPTION_cpu:
4588 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00004589 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00004590/* XXX: implement xxx_cpu_list for targets that still miss it */
4591#if defined(cpu_list)
4592 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00004593#endif
ths15f82202007-06-29 23:26:08 +00004594 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00004595 } else {
4596 cpu_model = optarg;
4597 }
4598 break;
bellardcd6f1162004-05-13 22:02:20 +00004599 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00004600 initrd_filename = optarg;
4601 break;
bellardcd6f1162004-05-13 22:02:20 +00004602 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00004603 if (cyls == 0)
balrog609497a2008-01-14 02:56:53 +00004604 hda_index = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00004605 else
balrog609497a2008-01-14 02:56:53 +00004606 hda_index = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00004607 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00004608 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00004609 translation == BIOS_ATA_TRANSLATION_LBA ?
4610 ",trans=lba" :
4611 translation == BIOS_ATA_TRANSLATION_NONE ?
4612 ",trans=none" : "");
4613 break;
bellardcd6f1162004-05-13 22:02:20 +00004614 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00004615 case QEMU_OPTION_hdc:
4616 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00004617 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00004618 break;
thse4bcb142007-12-02 04:51:10 +00004619 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00004620 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00004621 break;
balrog3e3d5812007-04-30 02:09:25 +00004622 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00004623 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00004624 break;
pbrooka1bb27b2007-04-06 16:49:48 +00004625 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00004626 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00004627 break;
j_mayer86f55662007-04-24 06:52:59 +00004628 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00004629 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00004630 break;
bellardcd6f1162004-05-13 22:02:20 +00004631 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00004632 snapshot = 1;
4633 break;
bellardcd6f1162004-05-13 22:02:20 +00004634 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00004635 {
bellard330d0412003-07-26 18:11:40 +00004636 const char *p;
4637 p = optarg;
4638 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004639 if (cyls < 1 || cyls > 16383)
4640 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004641 if (*p != ',')
4642 goto chs_fail;
4643 p++;
4644 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004645 if (heads < 1 || heads > 16)
4646 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00004647 if (*p != ',')
4648 goto chs_fail;
4649 p++;
4650 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00004651 if (secs < 1 || secs > 63)
4652 goto chs_fail;
4653 if (*p == ',') {
4654 p++;
4655 if (!strcmp(p, "none"))
4656 translation = BIOS_ATA_TRANSLATION_NONE;
4657 else if (!strcmp(p, "lba"))
4658 translation = BIOS_ATA_TRANSLATION_LBA;
4659 else if (!strcmp(p, "auto"))
4660 translation = BIOS_ATA_TRANSLATION_AUTO;
4661 else
4662 goto chs_fail;
4663 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00004664 chs_fail:
bellard46d47672004-11-16 01:45:27 +00004665 fprintf(stderr, "qemu: invalid physical CHS format\n");
4666 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00004667 }
thse4bcb142007-12-02 04:51:10 +00004668 if (hda_index != -1)
balrog609497a2008-01-14 02:56:53 +00004669 snprintf(drives_opt[hda_index].opt,
4670 sizeof(drives_opt[hda_index].opt),
4671 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
4672 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00004673 translation == BIOS_ATA_TRANSLATION_LBA ?
4674 ",trans=lba" :
4675 translation == BIOS_ATA_TRANSLATION_NONE ?
4676 ",trans=none" : "");
bellard330d0412003-07-26 18:11:40 +00004677 }
4678 break;
bellardcd6f1162004-05-13 22:02:20 +00004679 case QEMU_OPTION_nographic:
bellarda20dd502003-09-30 21:07:02 +00004680 nographic = 1;
4681 break;
balrog4d3b6f62008-02-10 16:33:14 +00004682#ifdef CONFIG_CURSES
4683 case QEMU_OPTION_curses:
4684 curses = 1;
4685 break;
4686#endif
balroga171fe32007-04-30 01:48:07 +00004687 case QEMU_OPTION_portrait:
4688 graphic_rotate = 1;
4689 break;
bellardcd6f1162004-05-13 22:02:20 +00004690 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00004691 kernel_filename = optarg;
4692 break;
bellardcd6f1162004-05-13 22:02:20 +00004693 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00004694 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00004695 break;
bellardcd6f1162004-05-13 22:02:20 +00004696 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00004697 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00004698 break;
bellardcd6f1162004-05-13 22:02:20 +00004699 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00004700 boot_devices = optarg;
4701 /* We just do some generic consistency checks */
4702 {
4703 /* Could easily be extended to 64 devices if needed */
ths60fe76f2007-12-16 03:02:09 +00004704 const char *p;
j_mayer28c5af52007-11-11 01:50:45 +00004705
4706 boot_devices_bitmap = 0;
4707 for (p = boot_devices; *p != '\0'; p++) {
4708 /* Allowed boot devices are:
4709 * a b : floppy disk drives
4710 * c ... f : IDE disk drives
4711 * g ... m : machine implementation dependant drives
4712 * n ... p : network devices
4713 * It's up to each machine implementation to check
4714 * if the given boot devices match the actual hardware
4715 * implementation and firmware features.
4716 */
4717 if (*p < 'a' || *p > 'q') {
4718 fprintf(stderr, "Invalid boot device '%c'\n", *p);
4719 exit(1);
4720 }
4721 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
4722 fprintf(stderr,
4723 "Boot device '%c' was given twice\n",*p);
4724 exit(1);
4725 }
4726 boot_devices_bitmap |= 1 << (*p - 'a');
4727 }
bellard36b486b2003-11-11 13:36:08 +00004728 }
4729 break;
bellardcd6f1162004-05-13 22:02:20 +00004730 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00004731 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00004732 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00004733 break;
bellard52ca8d62006-06-14 16:03:05 +00004734#ifdef TARGET_I386
4735 case QEMU_OPTION_no_fd_bootchk:
4736 fd_bootchk = 0;
4737 break;
4738#endif
bellard7c9d8e02005-11-15 22:16:05 +00004739 case QEMU_OPTION_net:
4740 if (nb_net_clients >= MAX_NET_CLIENTS) {
4741 fprintf(stderr, "qemu: too many network clients\n");
bellardc4b1fcc2004-03-14 21:44:30 +00004742 exit(1);
4743 }
pbrookfd5f3932008-03-26 20:55:43 +00004744 net_clients[nb_net_clients] = optarg;
bellard7c9d8e02005-11-15 22:16:05 +00004745 nb_net_clients++;
bellard702c6512004-04-02 21:21:32 +00004746 break;
bellardc7f74642004-08-24 21:57:12 +00004747#ifdef CONFIG_SLIRP
4748 case QEMU_OPTION_tftp:
bellardc7f74642004-08-24 21:57:12 +00004749 tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00004750 break;
ths47d5d012007-02-20 00:05:08 +00004751 case QEMU_OPTION_bootp:
4752 bootp_filename = optarg;
4753 break;
bellardc94c8d62004-09-13 21:37:34 +00004754#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00004755 case QEMU_OPTION_smb:
4756 net_slirp_smb(optarg);
4757 break;
bellardc94c8d62004-09-13 21:37:34 +00004758#endif
bellard9bf05442004-08-25 22:12:49 +00004759 case QEMU_OPTION_redir:
ths3b46e622007-09-17 08:09:54 +00004760 net_slirp_redir(optarg);
bellard9bf05442004-08-25 22:12:49 +00004761 break;
bellardc7f74642004-08-24 21:57:12 +00004762#endif
balrogdc72ac12008-11-09 00:04:26 +00004763 case QEMU_OPTION_bt:
4764 if (nb_bt_opts >= MAX_BT_CMDLINE) {
4765 fprintf(stderr, "qemu: too many bluetooth options\n");
4766 exit(1);
4767 }
4768 bt_opts[nb_bt_opts++] = optarg;
4769 break;
bellard1d14ffa2005-10-30 18:58:22 +00004770#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00004771 case QEMU_OPTION_audio_help:
4772 AUD_help ();
4773 exit (0);
4774 break;
4775 case QEMU_OPTION_soundhw:
4776 select_soundhw (optarg);
4777 break;
4778#endif
bellardcd6f1162004-05-13 22:02:20 +00004779 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00004780 help(0);
bellardcd6f1162004-05-13 22:02:20 +00004781 break;
aurel3200f82b82008-04-27 21:12:55 +00004782 case QEMU_OPTION_m: {
4783 uint64_t value;
4784 char *ptr;
4785
4786 value = strtoul(optarg, &ptr, 10);
4787 switch (*ptr) {
4788 case 0: case 'M': case 'm':
4789 value <<= 20;
4790 break;
4791 case 'G': case 'g':
4792 value <<= 30;
4793 break;
4794 default:
4795 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00004796 exit(1);
4797 }
aurel3200f82b82008-04-27 21:12:55 +00004798
4799 /* On 32-bit hosts, QEMU is limited by virtual address space */
4800 if (value > (2047 << 20)
4801#ifndef USE_KQEMU
4802 && HOST_LONG_BITS == 32
4803#endif
4804 ) {
4805 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
4806 exit(1);
4807 }
4808 if (value != (uint64_t)(ram_addr_t)value) {
4809 fprintf(stderr, "qemu: ram size too large\n");
4810 exit(1);
4811 }
4812 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00004813 break;
aurel3200f82b82008-04-27 21:12:55 +00004814 }
bellardcd6f1162004-05-13 22:02:20 +00004815 case QEMU_OPTION_d:
4816 {
4817 int mask;
blueswir1c7cd6a32008-10-02 18:27:46 +00004818 const CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00004819
bellardcd6f1162004-05-13 22:02:20 +00004820 mask = cpu_str_to_log_mask(optarg);
4821 if (!mask) {
4822 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00004823 for(item = cpu_log_items; item->mask != 0; item++) {
4824 printf("%-10s %s\n", item->name, item->help);
4825 }
4826 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00004827 }
4828 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00004829 }
bellardcd6f1162004-05-13 22:02:20 +00004830 break;
bellard67b915a2004-03-31 23:37:16 +00004831#ifdef CONFIG_GDBSTUB
bellardcd6f1162004-05-13 22:02:20 +00004832 case QEMU_OPTION_s:
4833 use_gdbstub = 1;
4834 break;
4835 case QEMU_OPTION_p:
pbrookcfc34752007-02-22 01:48:01 +00004836 gdbstub_port = optarg;
bellardcd6f1162004-05-13 22:02:20 +00004837 break;
bellard67b915a2004-03-31 23:37:16 +00004838#endif
bellardcd6f1162004-05-13 22:02:20 +00004839 case QEMU_OPTION_L:
4840 bios_dir = optarg;
4841 break;
j_mayer1192dad2007-10-05 13:08:35 +00004842 case QEMU_OPTION_bios:
4843 bios_name = optarg;
4844 break;
bellardcd6f1162004-05-13 22:02:20 +00004845 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00004846 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00004847 break;
bellard3d11d0e2004-12-12 16:56:30 +00004848 case QEMU_OPTION_k:
4849 keyboard_layout = optarg;
4850 break;
bellardee22c2f2004-06-03 12:49:50 +00004851 case QEMU_OPTION_localtime:
4852 rtc_utc = 0;
4853 break;
malc3893c122008-09-28 00:42:05 +00004854 case QEMU_OPTION_vga:
4855 select_vgahw (optarg);
bellard1bfe8562004-07-08 21:17:50 +00004856 break;
bellarde9b137c2004-06-21 16:46:10 +00004857 case QEMU_OPTION_g:
4858 {
4859 const char *p;
4860 int w, h, depth;
4861 p = optarg;
4862 w = strtol(p, (char **)&p, 10);
4863 if (w <= 0) {
4864 graphic_error:
4865 fprintf(stderr, "qemu: invalid resolution or depth\n");
4866 exit(1);
4867 }
4868 if (*p != 'x')
4869 goto graphic_error;
4870 p++;
4871 h = strtol(p, (char **)&p, 10);
4872 if (h <= 0)
4873 goto graphic_error;
4874 if (*p == 'x') {
4875 p++;
4876 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00004877 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00004878 depth != 24 && depth != 32)
4879 goto graphic_error;
4880 } else if (*p == '\0') {
4881 depth = graphic_depth;
4882 } else {
4883 goto graphic_error;
4884 }
ths3b46e622007-09-17 08:09:54 +00004885
bellarde9b137c2004-06-21 16:46:10 +00004886 graphic_width = w;
4887 graphic_height = h;
4888 graphic_depth = depth;
4889 }
4890 break;
ths20d8a3e2007-02-18 17:04:49 +00004891 case QEMU_OPTION_echr:
4892 {
4893 char *r;
4894 term_escape_char = strtol(optarg, &r, 0);
4895 if (r == optarg)
4896 printf("Bad argument to echr\n");
4897 break;
4898 }
bellard82c643f2004-07-14 17:28:13 +00004899 case QEMU_OPTION_monitor:
pbrookfd5f3932008-03-26 20:55:43 +00004900 monitor_device = optarg;
bellard82c643f2004-07-14 17:28:13 +00004901 break;
4902 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00004903 if (serial_device_index >= MAX_SERIAL_PORTS) {
4904 fprintf(stderr, "qemu: too many serial ports\n");
4905 exit(1);
4906 }
pbrookfd5f3932008-03-26 20:55:43 +00004907 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00004908 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00004909 break;
bellard6508fe52005-01-15 12:02:56 +00004910 case QEMU_OPTION_parallel:
4911 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
4912 fprintf(stderr, "qemu: too many parallel ports\n");
4913 exit(1);
4914 }
pbrookfd5f3932008-03-26 20:55:43 +00004915 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00004916 parallel_device_index++;
4917 break;
bellardd63d3072004-10-03 13:29:03 +00004918 case QEMU_OPTION_loadvm:
4919 loadvm = optarg;
4920 break;
4921 case QEMU_OPTION_full_screen:
4922 full_screen = 1;
4923 break;
ths667acca2006-12-11 02:08:05 +00004924#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00004925 case QEMU_OPTION_no_frame:
4926 no_frame = 1;
4927 break;
ths3780e192007-06-21 21:08:02 +00004928 case QEMU_OPTION_alt_grab:
4929 alt_grab = 1;
4930 break;
ths667acca2006-12-11 02:08:05 +00004931 case QEMU_OPTION_no_quit:
4932 no_quit = 1;
4933 break;
4934#endif
bellardf7cce892004-12-08 22:21:25 +00004935 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00004936 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00004937 break;
bellarda09db212005-04-30 16:10:35 +00004938#ifdef TARGET_I386
4939 case QEMU_OPTION_win2k_hack:
4940 win2k_install_hack = 1;
4941 break;
4942#endif
bellardd993e022005-02-10 22:00:06 +00004943#ifdef USE_KQEMU
4944 case QEMU_OPTION_no_kqemu:
4945 kqemu_allowed = 0;
4946 break;
bellard89bfc102006-02-08 22:46:31 +00004947 case QEMU_OPTION_kernel_kqemu:
4948 kqemu_allowed = 2;
4949 break;
bellardd993e022005-02-10 22:00:06 +00004950#endif
aliguori7ba1e612008-11-05 16:04:33 +00004951#ifdef CONFIG_KVM
4952 case QEMU_OPTION_enable_kvm:
4953 kvm_allowed = 1;
4954#ifdef USE_KQEMU
4955 kqemu_allowed = 0;
4956#endif
4957 break;
4958#endif
bellardbb36d472005-11-05 14:22:28 +00004959 case QEMU_OPTION_usb:
4960 usb_enabled = 1;
4961 break;
bellarda594cfb2005-11-06 16:13:29 +00004962 case QEMU_OPTION_usbdevice:
4963 usb_enabled = 1;
pbrook0d92ed32006-05-21 16:30:15 +00004964 if (usb_devices_index >= MAX_USB_CMDLINE) {
bellarda594cfb2005-11-06 16:13:29 +00004965 fprintf(stderr, "Too many USB devices\n");
4966 exit(1);
4967 }
pbrookfd5f3932008-03-26 20:55:43 +00004968 usb_devices[usb_devices_index] = optarg;
bellarda594cfb2005-11-06 16:13:29 +00004969 usb_devices_index++;
4970 break;
bellard6a00d602005-11-21 23:25:50 +00004971 case QEMU_OPTION_smp:
4972 smp_cpus = atoi(optarg);
aliguorib2097002008-10-07 20:39:39 +00004973 if (smp_cpus < 1) {
bellard6a00d602005-11-21 23:25:50 +00004974 fprintf(stderr, "Invalid number of CPUs\n");
4975 exit(1);
4976 }
4977 break;
bellard24236862006-04-30 21:28:36 +00004978 case QEMU_OPTION_vnc:
ths73fc9742006-12-22 02:09:07 +00004979 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00004980 break;
bellard6515b202006-05-03 22:02:44 +00004981 case QEMU_OPTION_no_acpi:
4982 acpi_enabled = 0;
4983 break;
bellardd1beab82006-10-02 19:44:22 +00004984 case QEMU_OPTION_no_reboot:
4985 no_reboot = 1;
4986 break;
aurel32b2f76162008-04-11 21:35:52 +00004987 case QEMU_OPTION_no_shutdown:
4988 no_shutdown = 1;
4989 break;
balrog9467cd42007-05-01 01:34:14 +00004990 case QEMU_OPTION_show_cursor:
4991 cursor_hide = 0;
4992 break;
blueswir18fcb1b92008-09-18 18:29:08 +00004993 case QEMU_OPTION_uuid:
4994 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
4995 fprintf(stderr, "Fail to parse UUID string."
4996 " Wrong format.\n");
4997 exit(1);
4998 }
4999 break;
ths71e3ceb2006-12-22 02:11:31 +00005000 case QEMU_OPTION_daemonize:
5001 daemonize = 1;
5002 break;
ths9ae02552007-01-05 17:39:04 +00005003 case QEMU_OPTION_option_rom:
5004 if (nb_option_roms >= MAX_OPTION_ROMS) {
5005 fprintf(stderr, "Too many option ROMs\n");
5006 exit(1);
5007 }
5008 option_rom[nb_option_roms] = optarg;
5009 nb_option_roms++;
5010 break;
pbrook8e716212007-01-20 17:12:09 +00005011 case QEMU_OPTION_semihosting:
5012 semihosting_enabled = 1;
5013 break;
thsc35734b2007-03-19 15:17:08 +00005014 case QEMU_OPTION_name:
5015 qemu_name = optarg;
5016 break;
blueswir166508602007-05-01 14:16:52 +00005017#ifdef TARGET_SPARC
5018 case QEMU_OPTION_prom_env:
5019 if (nb_prom_envs >= MAX_PROM_ENVS) {
5020 fprintf(stderr, "Too many prom variables\n");
5021 exit(1);
5022 }
5023 prom_envs[nb_prom_envs] = optarg;
5024 nb_prom_envs++;
5025 break;
5026#endif
balrog2b8f2d42007-07-27 22:08:46 +00005027#ifdef TARGET_ARM
5028 case QEMU_OPTION_old_param:
5029 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00005030 break;
balrog2b8f2d42007-07-27 22:08:46 +00005031#endif
thsf3dcfad2007-08-24 01:26:02 +00005032 case QEMU_OPTION_clock:
5033 configure_alarms(optarg);
5034 break;
bellard7e0af5d02007-11-07 16:24:33 +00005035 case QEMU_OPTION_startdate:
5036 {
5037 struct tm tm;
balrogf6503052008-02-17 11:42:19 +00005038 time_t rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00005039 if (!strcmp(optarg, "now")) {
balrogf6503052008-02-17 11:42:19 +00005040 rtc_date_offset = -1;
bellard7e0af5d02007-11-07 16:24:33 +00005041 } else {
5042 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
5043 &tm.tm_year,
5044 &tm.tm_mon,
5045 &tm.tm_mday,
5046 &tm.tm_hour,
5047 &tm.tm_min,
5048 &tm.tm_sec) == 6) {
5049 /* OK */
5050 } else if (sscanf(optarg, "%d-%d-%d",
5051 &tm.tm_year,
5052 &tm.tm_mon,
5053 &tm.tm_mday) == 3) {
5054 tm.tm_hour = 0;
5055 tm.tm_min = 0;
5056 tm.tm_sec = 0;
5057 } else {
5058 goto date_fail;
5059 }
5060 tm.tm_year -= 1900;
5061 tm.tm_mon--;
bellard3c6b2082007-11-10 19:36:39 +00005062 rtc_start_date = mktimegm(&tm);
bellard7e0af5d02007-11-07 16:24:33 +00005063 if (rtc_start_date == -1) {
5064 date_fail:
5065 fprintf(stderr, "Invalid date format. Valid format are:\n"
5066 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
5067 exit(1);
5068 }
balrogf6503052008-02-17 11:42:19 +00005069 rtc_date_offset = time(NULL) - rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00005070 }
5071 }
5072 break;
bellard26a5f132008-05-28 12:30:31 +00005073 case QEMU_OPTION_tb_size:
5074 tb_size = strtol(optarg, NULL, 0);
5075 if (tb_size < 0)
5076 tb_size = 0;
5077 break;
pbrook2e70f6e2008-06-29 01:03:05 +00005078 case QEMU_OPTION_icount:
5079 use_icount = 1;
5080 if (strcmp(optarg, "auto") == 0) {
5081 icount_time_shift = -1;
5082 } else {
5083 icount_time_shift = strtol(optarg, NULL, 0);
5084 }
5085 break;
aliguori5bb79102008-10-13 03:12:02 +00005086 case QEMU_OPTION_incoming:
5087 incoming = optarg;
5088 break;
bellardcd6f1162004-05-13 22:02:20 +00005089 }
bellard0824d6f2003-06-24 13:42:40 +00005090 }
5091 }
bellard330d0412003-07-26 18:11:40 +00005092
aliguori7ba1e612008-11-05 16:04:33 +00005093#if defined(CONFIG_KVM) && defined(USE_KQEMU)
5094 if (kvm_allowed && kqemu_allowed) {
5095 fprintf(stderr,
5096 "You can not enable both KVM and kqemu at the same time\n");
5097 exit(1);
5098 }
5099#endif
5100
balrog3d878ca2008-10-28 10:59:59 +00005101 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
aliguorib2097002008-10-07 20:39:39 +00005102 if (smp_cpus > machine->max_cpus) {
5103 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
5104 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
5105 machine->max_cpus);
5106 exit(1);
5107 }
5108
aliguoribc0129d2008-08-01 15:12:34 +00005109 if (nographic) {
5110 if (serial_device_index == 0)
5111 serial_devices[0] = "stdio";
5112 if (parallel_device_index == 0)
5113 parallel_devices[0] = "null";
5114 if (strncmp(monitor_device, "vc", 2) == 0)
5115 monitor_device = "stdio";
5116 }
5117
ths71e3ceb2006-12-22 02:11:31 +00005118#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00005119 if (daemonize) {
5120 pid_t pid;
5121
5122 if (pipe(fds) == -1)
5123 exit(1);
5124
5125 pid = fork();
5126 if (pid > 0) {
5127 uint8_t status;
5128 ssize_t len;
5129
5130 close(fds[1]);
5131
5132 again:
ths93815bc2007-03-19 15:58:31 +00005133 len = read(fds[0], &status, 1);
5134 if (len == -1 && (errno == EINTR))
5135 goto again;
5136
5137 if (len != 1)
5138 exit(1);
5139 else if (status == 1) {
5140 fprintf(stderr, "Could not acquire pidfile\n");
5141 exit(1);
5142 } else
5143 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00005144 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00005145 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00005146
5147 setsid();
5148
5149 pid = fork();
5150 if (pid > 0)
5151 exit(0);
5152 else if (pid < 0)
5153 exit(1);
5154
5155 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00005156
5157 signal(SIGTSTP, SIG_IGN);
5158 signal(SIGTTOU, SIG_IGN);
5159 signal(SIGTTIN, SIG_IGN);
5160 }
5161#endif
5162
thsaa26bb22007-03-25 21:33:06 +00005163 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00005164 if (daemonize) {
5165 uint8_t status = 1;
5166 write(fds[1], &status, 1);
5167 } else
5168 fprintf(stderr, "Could not acquire pid file\n");
5169 exit(1);
5170 }
5171
bellardff3fbb32006-01-08 10:53:14 +00005172#ifdef USE_KQEMU
5173 if (smp_cpus > 1)
5174 kqemu_allowed = 0;
5175#endif
bellarda20dd502003-09-30 21:07:02 +00005176 linux_boot = (kernel_filename != NULL);
balrog7317b8c2007-11-18 02:09:36 +00005177 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
balrog6c41b272007-11-17 12:12:29 +00005178
j_mayer28c5af52007-11-11 01:50:45 +00005179 if (!linux_boot && net_boot == 0 &&
blueswir1f88e4b92008-08-12 15:58:35 +00005180 !machine->nodisk_ok && nb_drives_opt == 0)
ths15f82202007-06-29 23:26:08 +00005181 help(1);
bellard0824d6f2003-06-24 13:42:40 +00005182
thsf8d39c02008-07-03 10:01:15 +00005183 if (!linux_boot && *kernel_cmdline != '\0') {
5184 fprintf(stderr, "-append only allowed with -kernel option\n");
5185 exit(1);
5186 }
5187
5188 if (!linux_boot && initrd_filename != NULL) {
5189 fprintf(stderr, "-initrd only allowed with -kernel option\n");
5190 exit(1);
5191 }
5192
ths96d30e42007-01-07 20:42:14 +00005193 /* boot to floppy or the default cd if no hard disk defined yet */
j_mayer28c5af52007-11-11 01:50:45 +00005194 if (!boot_devices[0]) {
thse4bcb142007-12-02 04:51:10 +00005195 boot_devices = "cad";
ths96d30e42007-01-07 20:42:14 +00005196 }
bellardb118d612003-06-30 23:36:21 +00005197 setvbuf(stdout, NULL, _IOLBF, 0);
ths3b46e622007-09-17 08:09:54 +00005198
pbrook634fce92006-07-15 17:40:09 +00005199 init_timers();
aliguori7183b4b2008-11-05 20:40:18 +00005200 if (init_timer_alarm() < 0) {
5201 fprintf(stderr, "could not initialize alarm timer\n");
5202 exit(1);
5203 }
pbrook2e70f6e2008-06-29 01:03:05 +00005204 if (use_icount && icount_time_shift < 0) {
5205 use_icount = 2;
5206 /* 125MIPS seems a reasonable initial guess at the guest speed.
5207 It will be corrected fairly quickly anyway. */
5208 icount_time_shift = 3;
5209 init_icount_adjust();
5210 }
pbrook634fce92006-07-15 17:40:09 +00005211
bellardfd1dff42006-02-01 21:29:26 +00005212#ifdef _WIN32
5213 socket_init();
5214#endif
5215
bellard7c9d8e02005-11-15 22:16:05 +00005216 /* init network clients */
5217 if (nb_net_clients == 0) {
5218 /* if no clients, we use a default config */
aliguorif441b282008-08-28 20:05:14 +00005219 net_clients[nb_net_clients++] = "nic";
5220#ifdef CONFIG_SLIRP
5221 net_clients[nb_net_clients++] = "user";
5222#endif
bellardc20709a2004-04-21 23:27:19 +00005223 }
5224
bellard7c9d8e02005-11-15 22:16:05 +00005225 for(i = 0;i < nb_net_clients; i++) {
balrog9ad97e62008-07-29 13:16:31 +00005226 if (net_client_parse(net_clients[i]) < 0)
bellard7c9d8e02005-11-15 22:16:05 +00005227 exit(1);
bellard702c6512004-04-02 21:21:32 +00005228 }
aliguori63a01ef2008-10-31 19:10:00 +00005229 net_client_check();
bellardf1510b22003-06-25 00:07:40 +00005230
thseec85c22007-01-05 17:41:07 +00005231#ifdef TARGET_I386
balroged494d82007-12-11 23:23:52 +00005232 /* XXX: this should be moved in the PC machine instantiation code */
j_mayer28c5af52007-11-11 01:50:45 +00005233 if (net_boot != 0) {
5234 int netroms = 0;
5235 for (i = 0; i < nb_nics && i < 4; i++) {
thseec85c22007-01-05 17:41:07 +00005236 const char *model = nd_table[i].model;
5237 char buf[1024];
j_mayer28c5af52007-11-11 01:50:45 +00005238 if (net_boot & (1 << i)) {
5239 if (model == NULL)
5240 model = "ne2k_pci";
5241 snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
5242 if (get_image_size(buf) > 0) {
5243 if (nb_option_roms >= MAX_OPTION_ROMS) {
5244 fprintf(stderr, "Too many option ROMs\n");
5245 exit(1);
5246 }
5247 option_rom[nb_option_roms] = strdup(buf);
5248 nb_option_roms++;
5249 netroms++;
5250 }
5251 }
thseec85c22007-01-05 17:41:07 +00005252 }
j_mayer28c5af52007-11-11 01:50:45 +00005253 if (netroms == 0) {
thseec85c22007-01-05 17:41:07 +00005254 fprintf(stderr, "No valid PXE rom found for network device\n");
5255 exit(1);
5256 }
thseec85c22007-01-05 17:41:07 +00005257 }
5258#endif
5259
balrogdc72ac12008-11-09 00:04:26 +00005260 /* init the bluetooth world */
5261 for (i = 0; i < nb_bt_opts; i++)
5262 if (bt_parse(bt_opts[i]))
5263 exit(1);
5264
bellard0824d6f2003-06-24 13:42:40 +00005265 /* init the memory */
balrog7fb4fdc2008-04-24 17:59:27 +00005266 phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
5267
5268 if (machine->ram_require & RAMSIZE_FIXED) {
5269 if (ram_size > 0) {
5270 if (ram_size < phys_ram_size) {
aurel32cd940062008-04-28 20:26:54 +00005271 fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
5272 machine->name, (unsigned long long) phys_ram_size);
balrog7fb4fdc2008-04-24 17:59:27 +00005273 exit(-1);
5274 }
5275
5276 phys_ram_size = ram_size;
5277 } else
5278 ram_size = phys_ram_size;
5279 } else {
aurel324fc5d072008-04-27 21:39:40 +00005280 if (ram_size == 0)
balrog7fb4fdc2008-04-24 17:59:27 +00005281 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
5282
5283 phys_ram_size += ram_size;
5284 }
ths9ae02552007-01-05 17:39:04 +00005285
bellardd993e022005-02-10 22:00:06 +00005286 phys_ram_base = qemu_vmalloc(phys_ram_size);
bellard7f7f9872003-10-30 01:11:23 +00005287 if (!phys_ram_base) {
5288 fprintf(stderr, "Could not allocate physical memory\n");
bellard0824d6f2003-06-24 13:42:40 +00005289 exit(1);
5290 }
5291
bellard26a5f132008-05-28 12:30:31 +00005292 /* init the dynamic translator */
5293 cpu_exec_init_all(tb_size * 1024 * 1024);
5294
bellard5905b2e2004-08-01 21:53:26 +00005295 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00005296
5297 /* we always create the cdrom drive, even if no disk is there */
5298
5299 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00005300 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00005301
balrog9d413d12007-12-04 00:10:34 +00005302 /* we always create at least one floppy */
thse4bcb142007-12-02 04:51:10 +00005303
5304 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00005305 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00005306
balrog9d413d12007-12-04 00:10:34 +00005307 /* we always create one sd slot, even if no card is in it */
5308
5309 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00005310 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00005311
ths96d30e42007-01-07 20:42:14 +00005312 /* open the virtual block devices */
bellardc4b1fcc2004-03-14 21:44:30 +00005313
thse4bcb142007-12-02 04:51:10 +00005314 for(i = 0; i < nb_drives_opt; i++)
balrog609497a2008-01-14 02:56:53 +00005315 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
thse4bcb142007-12-02 04:51:10 +00005316 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00005317
bellardc88676f2006-08-06 13:36:11 +00005318 register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
aliguori475e4272008-10-06 20:21:51 +00005319 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00005320
bellard313aa562003-08-10 21:52:11 +00005321 /* terminal init */
ths740733b2007-06-08 01:57:56 +00005322 memset(&display_state, 0, sizeof(display_state));
bellarda20dd502003-09-30 21:07:02 +00005323 if (nographic) {
balrog4d3b6f62008-02-10 16:33:14 +00005324 if (curses) {
5325 fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
5326 exit(1);
5327 }
ths2ff89792007-06-21 23:34:19 +00005328 /* nearly nothing to do */
5329 dumb_display_init(ds);
ths73fc9742006-12-22 02:09:07 +00005330 } else if (vnc_display != NULL) {
ths71cab5c2007-08-25 01:35:38 +00005331 vnc_display_init(ds);
5332 if (vnc_display_open(ds, vnc_display) < 0)
5333 exit(1);
balrog4d3b6f62008-02-10 16:33:14 +00005334 } else
5335#if defined(CONFIG_CURSES)
5336 if (curses) {
5337 curses_display_init(ds, full_screen);
5338 } else
5339#endif
5340 {
bellard5b0753e2005-03-01 21:37:28 +00005341#if defined(CONFIG_SDL)
ths43523e92007-02-18 18:19:32 +00005342 sdl_display_init(ds, full_screen, no_frame);
bellard5b0753e2005-03-01 21:37:28 +00005343#elif defined(CONFIG_COCOA)
5344 cocoa_display_init(ds, full_screen);
pbrook67276f52007-11-15 19:04:08 +00005345#else
5346 dumb_display_init(ds);
bellard313aa562003-08-10 21:52:11 +00005347#endif
5348 }
bellard0824d6f2003-06-24 13:42:40 +00005349
aliguori5b08fc12008-08-21 20:08:03 +00005350#ifndef _WIN32
5351 /* must be after terminal init, SDL library changes signal handlers */
5352 termsig_setup();
5353#endif
5354
ths20d8a3e2007-02-18 17:04:49 +00005355 /* Maintain compatibility with multiple stdio monitors */
5356 if (!strcmp(monitor_device,"stdio")) {
5357 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
pbrookfd5f3932008-03-26 20:55:43 +00005358 const char *devname = serial_devices[i];
5359 if (devname && !strcmp(devname,"mon:stdio")) {
5360 monitor_device = NULL;
ths20d8a3e2007-02-18 17:04:49 +00005361 break;
pbrookfd5f3932008-03-26 20:55:43 +00005362 } else if (devname && !strcmp(devname,"stdio")) {
5363 monitor_device = NULL;
5364 serial_devices[i] = "mon:stdio";
ths20d8a3e2007-02-18 17:04:49 +00005365 break;
5366 }
5367 }
bellard82c643f2004-07-14 17:28:13 +00005368 }
pbrookfd5f3932008-03-26 20:55:43 +00005369 if (monitor_device) {
aliguori5ccfae12008-10-31 17:31:29 +00005370 monitor_hd = qemu_chr_open("monitor", monitor_device);
ths20d8a3e2007-02-18 17:04:49 +00005371 if (!monitor_hd) {
5372 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
5373 exit(1);
5374 }
5375 monitor_init(monitor_hd, !nographic);
5376 }
bellard82c643f2004-07-14 17:28:13 +00005377
bellard8d11df92004-08-24 21:13:40 +00005378 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005379 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005380 if (devname && strcmp(devname, "none")) {
aliguori5ccfae12008-10-31 17:31:29 +00005381 char label[32];
5382 snprintf(label, sizeof(label), "serial%d", i);
5383 serial_hds[i] = qemu_chr_open(label, devname);
bellard8d11df92004-08-24 21:13:40 +00005384 if (!serial_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00005385 fprintf(stderr, "qemu: could not open serial device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00005386 devname);
bellard8d11df92004-08-24 21:13:40 +00005387 exit(1);
5388 }
thsaf3a9032007-07-11 23:14:59 +00005389 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005390 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00005391 }
bellard82c643f2004-07-14 17:28:13 +00005392 }
bellard82c643f2004-07-14 17:28:13 +00005393
bellard6508fe52005-01-15 12:02:56 +00005394 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00005395 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00005396 if (devname && strcmp(devname, "none")) {
aliguori5ccfae12008-10-31 17:31:29 +00005397 char label[32];
5398 snprintf(label, sizeof(label), "parallel%d", i);
5399 parallel_hds[i] = qemu_chr_open(label, devname);
bellard6508fe52005-01-15 12:02:56 +00005400 if (!parallel_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00005401 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00005402 devname);
bellard6508fe52005-01-15 12:02:56 +00005403 exit(1);
5404 }
thsaf3a9032007-07-11 23:14:59 +00005405 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00005406 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00005407 }
5408 }
5409
aliguori7ba1e612008-11-05 16:04:33 +00005410 if (kvm_enabled()) {
5411 int ret;
5412
5413 ret = kvm_init(smp_cpus);
5414 if (ret < 0) {
5415 fprintf(stderr, "failed to initialize KVM\n");
5416 exit(1);
5417 }
5418 }
5419
blueswir1b881c2c2007-11-18 08:46:58 +00005420 machine->init(ram_size, vga_ram_size, boot_devices, ds,
j_mayer94fc95c2007-03-05 19:44:02 +00005421 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
bellard73332e52004-04-04 20:22:28 +00005422
pbrook0d92ed32006-05-21 16:30:15 +00005423 /* init USB devices */
5424 if (usb_enabled) {
5425 for(i = 0; i < usb_devices_index; i++) {
5426 if (usb_device_add(usb_devices[i]) < 0) {
5427 fprintf(stderr, "Warning: could not add USB device %s\n",
5428 usb_devices[i]);
5429 }
5430 }
5431 }
5432
ths740733b2007-06-08 01:57:56 +00005433 if (display_state.dpy_refresh) {
5434 display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
5435 qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
5436 }
bellard7f7f9872003-10-30 01:11:23 +00005437
bellard67b915a2004-03-31 23:37:16 +00005438#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00005439 if (use_gdbstub) {
bellardc636bb62007-02-05 20:46:05 +00005440 /* XXX: use standard host:port notation and modify options
5441 accordingly. */
pbrookcfc34752007-02-22 01:48:01 +00005442 if (gdbserver_start(gdbstub_port) < 0) {
5443 fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
bellardc636bb62007-02-05 20:46:05 +00005444 gdbstub_port);
bellard8a7ddc32004-03-31 19:00:16 +00005445 exit(1);
bellard8a7ddc32004-03-31 19:00:16 +00005446 }
balrog45669e02007-07-02 13:20:17 +00005447 }
bellard67b915a2004-03-31 23:37:16 +00005448#endif
balrog45669e02007-07-02 13:20:17 +00005449
bellardd63d3072004-10-03 13:29:03 +00005450 if (loadvm)
bellardfaea38e2006-08-05 21:31:00 +00005451 do_loadvm(loadvm);
bellardd63d3072004-10-03 13:29:03 +00005452
aliguori5bb79102008-10-13 03:12:02 +00005453 if (incoming) {
5454 autostart = 0; /* fixme how to deal with -daemonize */
5455 qemu_start_incoming_migration(incoming);
5456 }
5457
bellard67b915a2004-03-31 23:37:16 +00005458 {
bellard5905b2e2004-08-01 21:53:26 +00005459 /* XXX: simplify init */
aliguori83ab7952008-08-19 14:44:22 +00005460 read_passwords();
pbrook3c07f8e2007-01-21 16:47:01 +00005461 if (autostart) {
bellard5905b2e2004-08-01 21:53:26 +00005462 vm_start();
5463 }
bellard0824d6f2003-06-24 13:42:40 +00005464 }
thsffd843b2006-12-21 19:46:43 +00005465
ths71e3ceb2006-12-22 02:11:31 +00005466 if (daemonize) {
5467 uint8_t status = 0;
5468 ssize_t len;
5469 int fd;
5470
5471 again1:
5472 len = write(fds[1], &status, 1);
5473 if (len == -1 && (errno == EINTR))
5474 goto again1;
5475
5476 if (len != 1)
5477 exit(1);
5478
aliguoribd54b862008-07-23 00:58:33 +00005479 chdir("/");
balrogaeb30be2007-07-02 15:03:13 +00005480 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00005481 if (fd == -1)
5482 exit(1);
5483
5484 dup2(fd, 0);
5485 dup2(fd, 1);
5486 dup2(fd, 2);
5487
5488 close(fd);
5489 }
5490
bellard8a7ddc32004-03-31 19:00:16 +00005491 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00005492 quit_timers();
aliguori63a01ef2008-10-31 19:10:00 +00005493 net_cleanup();
thsb46a8902007-10-21 23:20:45 +00005494
bellard0824d6f2003-06-24 13:42:40 +00005495 return 0;
5496}