blob: 59b7c724e7531558330f3725d2f8bf91888ee8e5 [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25/* the following is needed on Linux to define ptsname() in stdlib.h */
26#if defined(__linux__)
27#define _GNU_SOURCE 1
28#endif
29
30#include "qemu-common.h"
31#include "hw/hw.h"
32#include "hw/boards.h"
33#include "hw/usb.h"
34#include "hw/pcmcia.h"
35#include "hw/pc.h"
36#include "hw/audiodev.h"
37#include "hw/isa.h"
38#include "hw/baum.h"
39#include "hw/goldfish_nand.h"
40#include "net.h"
41#include "console.h"
42#include "sysemu.h"
43#include "gdbstub.h"
44#include "qemu-timer.h"
45#include "qemu-char.h"
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010046#include "blockdev.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070047#include "audio/audio.h"
48
49#include "qemu_file.h"
50#include "android/android.h"
51#include "charpipe.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070052#include "modem_driver.h"
53#include "android/gps.h"
54#include "android/hw-qemud.h"
55#include "android/hw-kmsg.h"
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -070056#include "android/charmap.h"
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -070057#include "android/globals.h"
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -070058#include "android/utils/bufprint.h"
David 'Digit' Turner5f824112011-03-01 14:00:26 +010059#include "android/utils/debug.h"
David 'Digit' Turner48a3c662011-03-01 14:03:20 +010060#include "android/utils/filelock.h"
61#include "android/utils/path.h"
David 'Digit' Turner5f824112011-03-01 14:00:26 +010062#include "android/utils/stralloc.h"
David 'Digit' Turner40841b22011-03-01 14:04:00 +010063#include "android/utils/tempfile.h"
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -080064#include "android/display-core.h"
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -080065#include "android/utils/timezone.h"
David 'Digit' Turnerbdb6f2d2011-02-23 15:57:25 +010066#include "android/snapshot.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070067#include "targphys.h"
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -070068#include "tcpdump.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070069
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -070070#ifdef CONFIG_MEMCHECK
71#include "memcheck/memcheck.h"
72#endif // CONFIG_MEMCHECK
73
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070074#include <unistd.h>
75#include <fcntl.h>
76#include <signal.h>
77#include <time.h>
78#include <errno.h>
79#include <sys/time.h>
80#include <zlib.h>
81
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070082/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070083#include "config-host.h"
84
85#ifndef _WIN32
86#include <libgen.h>
87#include <pwd.h>
88#include <sys/times.h>
89#include <sys/wait.h>
90#include <termios.h>
91#include <sys/mman.h>
92#include <sys/ioctl.h>
93#include <sys/resource.h>
94#include <sys/socket.h>
95#include <netinet/in.h>
96#include <net/if.h>
97#if defined(__NetBSD__)
98#include <net/if_tap.h>
99#endif
100#ifdef __linux__
101#include <linux/if_tun.h>
102#endif
103#include <arpa/inet.h>
104#include <dirent.h>
105#include <netdb.h>
106#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -0700107#ifdef CONFIG_BSD
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700108#include <sys/stat.h>
109#if defined(__FreeBSD__) || defined(__DragonFly__)
110#include <libutil.h>
111#else
112#include <util.h>
113#endif
114#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
115#include <freebsd/stdlib.h>
116#else
117#ifdef __linux__
118#include <pty.h>
119#include <malloc.h>
120#include <linux/rtc.h>
121
122/* For the benefit of older linux systems which don't supply it,
123 we use a local copy of hpet.h. */
124/* #include <linux/hpet.h> */
125#include "hpet.h"
126
127#include <linux/ppdev.h>
128#include <linux/parport.h>
129#endif
130#ifdef __sun__
131#include <sys/stat.h>
132#include <sys/ethernet.h>
133#include <sys/sockio.h>
134#include <netinet/arp.h>
135#include <netinet/in.h>
136#include <netinet/in_systm.h>
137#include <netinet/ip.h>
138#include <netinet/ip_icmp.h> // must come after ip.h
139#include <netinet/udp.h>
140#include <netinet/tcp.h>
141#include <net/if.h>
142#include <syslog.h>
143#include <stropts.h>
144#endif
145#endif
146#endif
147
148#if defined(__OpenBSD__)
149#include <util.h>
150#endif
151
152#if defined(CONFIG_VDE)
153#include <libvdeplug.h>
154#endif
155
156#ifdef _WIN32
157#include <windows.h>
158#include <malloc.h>
159#include <sys/timeb.h>
160#include <mmsystem.h>
161#define getopt_long_only getopt_long
162#define memalign(align, size) malloc(size)
163#endif
164
165
166#ifdef CONFIG_COCOA
167#undef main
168#define main qemu_main
169#endif /* CONFIG_COCOA */
170
171#include "hw/hw.h"
172#include "hw/boards.h"
173#include "hw/usb.h"
174#include "hw/pcmcia.h"
175#include "hw/pc.h"
176#include "hw/audiodev.h"
177#include "hw/isa.h"
178#include "hw/baum.h"
179#include "hw/bt.h"
180#include "hw/watchdog.h"
181#include "hw/smbios.h"
182#include "hw/xen.h"
183#include "bt-host.h"
184#include "net.h"
185#include "monitor.h"
186#include "console.h"
187#include "sysemu.h"
188#include "gdbstub.h"
189#include "qemu-timer.h"
190#include "qemu-char.h"
191#include "cache-utils.h"
192#include "block.h"
193#include "dma.h"
194#include "audio/audio.h"
195#include "migration.h"
196#include "kvm.h"
197#include "balloon.h"
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700198#include "android/hw-lcd.h"
199#include "android/boot-properties.h"
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700200#include "android/core-init-utils.h"
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +0100201#include "android/audio-test.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700202
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -0700203#ifdef CONFIG_STANDALONE_CORE
204/* Verbose value used by the standalone emulator core (without UI) */
205unsigned long android_verbose;
206#endif // CONFIG_STANDALONE_CORE
207
Vladimir Chtchetkine57584042011-01-20 16:15:30 -0800208#if !defined(CONFIG_STANDALONE_CORE)
209/* in android/qemulator.c */
210extern void android_emulator_set_base_port(int port);
211#endif
212
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700213#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700214#undef main
215#define main qemu_main
216#endif
217
218#include "disas.h"
219
220#include "exec-all.h"
221
222#ifdef CONFIG_TRACE
223#include "trace.h"
224#include "dcache.h"
225#endif
226
227#include "qemu_socket.h"
228
229#if defined(CONFIG_SLIRP)
230#include "libslirp.h"
231#endif
232
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700233
234
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700235#define DEFAULT_RAM_SIZE 128
236
237/* Max number of USB devices that can be specified on the commandline. */
238#define MAX_USB_CMDLINE 8
239
240/* Max number of bluetooth switches on the commandline. */
241#define MAX_BT_CMDLINE 10
242
243/* XXX: use a two level table to limit memory usage */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700244
245static const char *data_dir;
246const char *bios_name = NULL;
247static void *ioport_opaque[MAX_IOPORTS];
248static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
249static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100250#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700251/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
252 to store the VM snapshots */
253DriveInfo drives_table[MAX_DRIVES+1];
254int nb_drives;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100255#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700256enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700257DisplayType display_type = DT_DEFAULT;
258const char* keyboard_layout = NULL;
259int64_t ticks_per_sec;
260ram_addr_t ram_size;
261int nb_nics;
262NICInfo nd_table[MAX_NICS];
263int vm_running;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100264int autostart;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700265static int rtc_utc = 1;
266static int rtc_date_offset = -1; /* -1 means no change */
267int cirrus_vga_enabled = 1;
268int std_vga_enabled = 0;
269int vmsvga_enabled = 0;
270int xenfb_enabled = 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700271QEMUClock *rtc_clock;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700272#ifdef TARGET_SPARC
273int graphic_width = 1024;
274int graphic_height = 768;
275int graphic_depth = 8;
276#else
277int graphic_width = 800;
278int graphic_height = 600;
279int graphic_depth = 15;
280#endif
281static int full_screen = 0;
282#ifdef CONFIG_SDL
283static int no_frame = 0;
284#endif
285int no_quit = 0;
286CharDriverState *serial_hds[MAX_SERIAL_PORTS];
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +0100287int serial_hds_count;
288
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700289CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
290CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
291#ifdef TARGET_I386
292int win2k_install_hack = 0;
293int rtc_td_hack = 0;
294#endif
295int usb_enabled = 0;
296int singlestep = 0;
297int smp_cpus = 1;
298const char *vnc_display;
299int acpi_enabled = 1;
300int no_hpet = 0;
301int no_virtio_balloon = 0;
302int fd_bootchk = 1;
303int no_reboot = 0;
304int no_shutdown = 0;
305int cursor_hide = 1;
306int graphic_rotate = 0;
307#ifndef _WIN32
308int daemonize = 0;
309#endif
310WatchdogTimerModel *watchdog = NULL;
311int watchdog_action = WDT_RESET;
312const char *option_rom[MAX_OPTION_ROMS];
313int nb_option_roms;
314int semihosting_enabled = 0;
315#ifdef TARGET_ARM
316int old_param = 0;
317#endif
318const char *qemu_name;
319int alt_grab = 0;
320#if defined(TARGET_SPARC) || defined(TARGET_PPC)
321unsigned int nb_prom_envs = 0;
322const char *prom_envs[MAX_PROM_ENVS];
323#endif
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100324#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700325int nb_drives_opt;
326struct drive_opt drives_opt[MAX_DRIVES];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100327#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700328int nb_numa_nodes;
329uint64_t node_mem[MAX_NODES];
330uint64_t node_cpumask[MAX_NODES];
331
332static CPUState *cur_cpu;
333static CPUState *next_cpu;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700334static QEMUTimer *nographic_timer;
335
336uint8_t qemu_uuid[16];
337
338
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700339int qemu_cpu_delay;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700340extern char* audio_input_source;
341
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700342extern char* android_op_ports;
343extern char* android_op_port;
344extern char* android_op_report_console;
345extern char* op_http_proxy;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700346// Path to the file containing specific key character map.
347char* op_charmap_file = NULL;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700348
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -0700349/* Path to hardware initialization file passed with -android-hw option. */
350char* android_op_hwini = NULL;
351
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -0700352/* Memory checker options. */
353char* android_op_memcheck = NULL;
354
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -0700355/* -dns-server option value. */
356char* android_op_dns_server = NULL;
357
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -0700358/* -radio option value. */
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700359char* android_op_radio = NULL;
360
361/* -gps option value. */
362char* android_op_gps = NULL;
363
364/* -audio option value. */
365char* android_op_audio = NULL;
366
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700367/* -cpu-delay option value. */
368char* android_op_cpu_delay = NULL;
369
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -0700370#ifdef CONFIG_NAND_LIMITS
371/* -nand-limits option value. */
372char* android_op_nand_limits = NULL;
373#endif // CONFIG_NAND_LIMITS
374
375/* -netspeed option value. */
376char* android_op_netspeed = NULL;
377
378/* -netdelay option value. */
379char* android_op_netdelay = NULL;
380
381/* -netfast option value. */
382int android_op_netfast = 0;
383
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -0700384/* -tcpdump option value. */
385char* android_op_tcpdump = NULL;
386
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700387/* -lcd-density option value. */
388char* android_op_lcd_density = NULL;
389
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700390/* -ui-port option value. This port will be used to report the core
391 * initialization completion.
392 */
393char* android_op_ui_port = NULL;
394
395/* -ui-settings option value. This value will be passed to the UI when new UI
396 * process is attaching to the core.
397 */
398char* android_op_ui_settings = NULL;
399
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -0800400/* -android-avdname option value. */
401char* android_op_avd_name = "unknown";
402
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -0700403extern int android_display_width;
404extern int android_display_height;
405extern int android_display_bpp;
406
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700407extern void dprint( const char* format, ... );
408
rich canningsd952f282011-03-01 15:40:09 -0800409const char* dns_log_filename = NULL;
410const char* drop_log_filename = NULL;
411static int rotate_logs_requested = 0;
412
Tim Baverstock24204cc2010-11-25 11:37:43 +0000413const char* savevm_on_exit = NULL;
Tim Baverstock24204cc2010-11-25 11:37:43 +0000414
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700415#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
416
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700417/* Reports the core initialization failure to the error stdout and to the UI
418 * socket before exiting the application.
419 * Parameters that are passed to this macro are used to format the error
420 * mesage using sprintf routine.
421 */
422#ifdef CONFIG_ANDROID
423#define PANIC(...) android_core_init_failure(__VA_ARGS__)
424#else
425#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
426 exit(1); \
427 } while (0)
428#endif // CONFIG_ANDROID
429
430/* Exits the core during initialization. */
431#ifdef CONFIG_ANDROID
432#define QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
433#else
434#define QEMU_EXIT(exit_code) exit(exit_code)
435#endif // CONFIG_ANDROID
436
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700437/***********************************************************/
438/* x86 ISA bus support */
439
440target_phys_addr_t isa_mem_base = 0;
441PicState2 *isa_pic;
442
443static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
444static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
445
446static uint32_t ioport_read(int index, uint32_t address)
447{
448 static IOPortReadFunc *default_func[3] = {
449 default_ioport_readb,
450 default_ioport_readw,
451 default_ioport_readl
452 };
453 IOPortReadFunc *func = ioport_read_table[index][address];
454 if (!func)
455 func = default_func[index];
456 return func(ioport_opaque[address], address);
457}
458
459static void ioport_write(int index, uint32_t address, uint32_t data)
460{
461 static IOPortWriteFunc *default_func[3] = {
462 default_ioport_writeb,
463 default_ioport_writew,
464 default_ioport_writel
465 };
466 IOPortWriteFunc *func = ioport_write_table[index][address];
467 if (!func)
468 func = default_func[index];
469 func(ioport_opaque[address], address, data);
470}
471
472static uint32_t default_ioport_readb(void *opaque, uint32_t address)
473{
474#ifdef DEBUG_UNUSED_IOPORT
475 fprintf(stderr, "unused inb: port=0x%04x\n", address);
476#endif
477 return 0xff;
478}
479
480static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
481{
482#ifdef DEBUG_UNUSED_IOPORT
483 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
484#endif
485}
486
487/* default is to make two byte accesses */
488static uint32_t default_ioport_readw(void *opaque, uint32_t address)
489{
490 uint32_t data;
491 data = ioport_read(0, address);
492 address = (address + 1) & (MAX_IOPORTS - 1);
493 data |= ioport_read(0, address) << 8;
494 return data;
495}
496
497static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
498{
499 ioport_write(0, address, data & 0xff);
500 address = (address + 1) & (MAX_IOPORTS - 1);
501 ioport_write(0, address, (data >> 8) & 0xff);
502}
503
504static uint32_t default_ioport_readl(void *opaque, uint32_t address)
505{
506#ifdef DEBUG_UNUSED_IOPORT
507 fprintf(stderr, "unused inl: port=0x%04x\n", address);
508#endif
509 return 0xffffffff;
510}
511
512static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
513{
514#ifdef DEBUG_UNUSED_IOPORT
515 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
516#endif
517}
518
rich canningsd952f282011-03-01 15:40:09 -0800519/*
520 * Sets a flag (rotate_logs_requested) to clear both the DNS and the
521 * drop logs upon receiving a SIGUSR1 signal. We need to clear the logs
522 * between the tasks that do not require restarting Qemu.
523 */
524void rotate_qemu_logs_handler(int signum) {
525 rotate_logs_requested = 1;
526}
527
528/*
529 * Resets the rotate_log_requested_flag. Normally called after qemu
530 * logs has been rotated.
531 */
532void reset_rotate_qemu_logs_request(void) {
533 rotate_logs_requested = 0;
534}
535
536/*
537 * Clears the passed qemu log when the rotate_logs_requested
538 * is set. We need to clear the logs between the tasks that do not
539 * require restarting Qemu.
540 */
541FILE* rotate_qemu_log(FILE* old_log_fd, const char* filename) {
542 FILE* new_log_fd = NULL;
543 if (old_log_fd) {
544 if (fclose(old_log_fd) == -1) {
545 fprintf(stderr, "Cannot close old_log fd\n");
546 exit(errno);
547 }
548 }
549
550 if (!filename) {
551 fprintf(stderr, "The log filename to be rotated is not provided");
552 exit(-1);
553 }
554
555 new_log_fd = fopen(filename , "wb+");
556 if (new_log_fd == NULL) {
557 fprintf(stderr, "Cannot open the log file: %s for write.\n",
558 filename);
559 exit(1);
560 }
561
562 return new_log_fd;
563}
564
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700565/***********************************************************/
566void hw_error(const char *fmt, ...)
567{
568 va_list ap;
569 CPUState *env;
570
571 va_start(ap, fmt);
572 fprintf(stderr, "qemu: hardware error: ");
573 vfprintf(stderr, fmt, ap);
574 fprintf(stderr, "\n");
575 for(env = first_cpu; env != NULL; env = env->next_cpu) {
576 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
577#ifdef TARGET_I386
578 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
579#else
580 cpu_dump_state(env, stderr, fprintf, 0);
581#endif
582 }
583 va_end(ap);
584 abort();
585}
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +0200586
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700587/***************/
588/* ballooning */
589
590static QEMUBalloonEvent *qemu_balloon_event;
591void *qemu_balloon_event_opaque;
592
593void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
594{
595 qemu_balloon_event = func;
596 qemu_balloon_event_opaque = opaque;
597}
598
599void qemu_balloon(ram_addr_t target)
600{
601 if (qemu_balloon_event)
602 qemu_balloon_event(qemu_balloon_event_opaque, target);
603}
604
605ram_addr_t qemu_balloon_status(void)
606{
607 if (qemu_balloon_event)
608 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
609 return 0;
610}
611
612/***********************************************************/
David Turner025c32f2010-09-10 14:52:42 +0200613/* real time host monotonic timer */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700614
615/* compute with 96 bit intermediate result: (a*b)/c */
616uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
617{
618 union {
619 uint64_t ll;
620 struct {
David 'Digit' Turner20894ae2010-05-10 17:07:36 -0700621#ifdef HOST_WORDS_BIGENDIAN
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700622 uint32_t high, low;
623#else
624 uint32_t low, high;
625#endif
626 } l;
627 } u, res;
628 uint64_t rl, rh;
629
630 u.ll = a;
631 rl = (uint64_t)u.l.low * (uint64_t)b;
632 rh = (uint64_t)u.l.high * (uint64_t)b;
633 rh += (rl >> 32);
634 res.l.high = rh / c;
635 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
636 return res.ll;
637}
638
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700639/***********************************************************/
640/* host time/date access */
641void qemu_get_timedate(struct tm *tm, int offset)
642{
643 time_t ti;
644 struct tm *ret;
645
646 time(&ti);
647 ti += offset;
648 if (rtc_date_offset == -1) {
649 if (rtc_utc)
650 ret = gmtime(&ti);
651 else
652 ret = localtime(&ti);
653 } else {
654 ti -= rtc_date_offset;
655 ret = gmtime(&ti);
656 }
657
658 memcpy(tm, ret, sizeof(struct tm));
659}
660
661int qemu_timedate_diff(struct tm *tm)
662{
663 time_t seconds;
664
665 if (rtc_date_offset == -1)
666 if (rtc_utc)
667 seconds = mktimegm(tm);
668 else
669 seconds = mktime(tm);
670 else
671 seconds = mktimegm(tm) + rtc_date_offset;
672
673 return seconds - time(NULL);
674}
675
676
677#ifdef CONFIG_TRACE
678static int tbflush_requested;
679static int exit_requested;
680
681void start_tracing()
682{
683 if (trace_filename == NULL)
684 return;
685 if (!tracing) {
686 fprintf(stderr,"-- start tracing --\n");
687 start_time = Now();
688 }
689 tracing = 1;
690 tbflush_requested = 1;
691 qemu_notify_event();
692}
693
694void stop_tracing()
695{
696 if (trace_filename == NULL)
697 return;
698 if (tracing) {
699 end_time = Now();
700 elapsed_usecs += end_time - start_time;
701 fprintf(stderr,"-- stop tracing --\n");
702 }
703 tracing = 0;
704 tbflush_requested = 1;
705 qemu_notify_event();
706}
707
708#ifndef _WIN32
709/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
710 * SIGUSR1 turns tracing on. SIGUSR2 turns tracing off.
711 */
712void sigusr_handler(int sig)
713{
714 if (sig == SIGUSR1)
715 start_tracing();
716 else
717 stop_tracing();
718}
719#endif
720
721/* This is the handler to catch control-C so that we can exit cleanly.
722 * This is needed when tracing to flush the buffers to disk.
723 */
724void sigint_handler(int sig)
725{
726 exit_requested = 1;
727 qemu_notify_event();
728}
729#endif /* CONFIG_TRACE */
730
731
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700732/***********************************************************/
733/* Bluetooth support */
734static int nb_hcis;
735static int cur_hci;
736static struct HCIInfo *hci_table[MAX_NICS];
737
738static struct bt_vlan_s {
739 struct bt_scatternet_s net;
740 int id;
741 struct bt_vlan_s *next;
742} *first_bt_vlan;
743
744/* find or alloc a new bluetooth "VLAN" */
745static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
746{
747 struct bt_vlan_s **pvlan, *vlan;
748 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
749 if (vlan->id == id)
750 return &vlan->net;
751 }
752 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
753 vlan->id = id;
754 pvlan = &first_bt_vlan;
755 while (*pvlan != NULL)
756 pvlan = &(*pvlan)->next;
757 *pvlan = vlan;
758 return &vlan->net;
759}
760
761static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
762{
763}
764
765static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
766{
767 return -ENOTSUP;
768}
769
770static struct HCIInfo null_hci = {
771 .cmd_send = null_hci_send,
772 .sco_send = null_hci_send,
773 .acl_send = null_hci_send,
774 .bdaddr_set = null_hci_addr_set,
775};
776
777struct HCIInfo *qemu_next_hci(void)
778{
779 if (cur_hci == nb_hcis)
780 return &null_hci;
781
782 return hci_table[cur_hci++];
783}
784
785static struct HCIInfo *hci_init(const char *str)
786{
787 char *endp;
788 struct bt_scatternet_s *vlan = 0;
789
790 if (!strcmp(str, "null"))
791 /* null */
792 return &null_hci;
793 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
794 /* host[:hciN] */
795 return bt_host_hci(str[4] ? str + 5 : "hci0");
796 else if (!strncmp(str, "hci", 3)) {
797 /* hci[,vlan=n] */
798 if (str[3]) {
799 if (!strncmp(str + 3, ",vlan=", 6)) {
800 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
801 if (*endp)
802 vlan = 0;
803 }
804 } else
805 vlan = qemu_find_bt_vlan(0);
806 if (vlan)
807 return bt_new_hci(vlan);
808 }
809
810 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
811
812 return 0;
813}
814
815static int bt_hci_parse(const char *str)
816{
817 struct HCIInfo *hci;
818 bdaddr_t bdaddr;
819
820 if (nb_hcis >= MAX_NICS) {
821 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
822 return -1;
823 }
824
825 hci = hci_init(str);
826 if (!hci)
827 return -1;
828
829 bdaddr.b[0] = 0x52;
830 bdaddr.b[1] = 0x54;
831 bdaddr.b[2] = 0x00;
832 bdaddr.b[3] = 0x12;
833 bdaddr.b[4] = 0x34;
834 bdaddr.b[5] = 0x56 + nb_hcis;
835 hci->bdaddr_set(hci, bdaddr.b);
836
837 hci_table[nb_hcis++] = hci;
838
839 return 0;
840}
841
842static void bt_vhci_add(int vlan_id)
843{
844 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
845
846 if (!vlan->slave)
847 fprintf(stderr, "qemu: warning: adding a VHCI to "
848 "an empty scatternet %i\n", vlan_id);
849
850 bt_vhci_init(bt_new_hci(vlan));
851}
852
853static struct bt_device_s *bt_device_add(const char *opt)
854{
855 struct bt_scatternet_s *vlan;
856 int vlan_id = 0;
857 char *endp = strstr(opt, ",vlan=");
858 int len = (endp ? endp - opt : strlen(opt)) + 1;
859 char devname[10];
860
861 pstrcpy(devname, MIN(sizeof(devname), len), opt);
862
863 if (endp) {
864 vlan_id = strtol(endp + 6, &endp, 0);
865 if (*endp) {
866 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
867 return 0;
868 }
869 }
870
871 vlan = qemu_find_bt_vlan(vlan_id);
872
873 if (!vlan->slave)
874 fprintf(stderr, "qemu: warning: adding a slave device to "
875 "an empty scatternet %i\n", vlan_id);
876
877 if (!strcmp(devname, "keyboard"))
878 return bt_keyboard_init(vlan);
879
880 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
881 return 0;
882}
883
884static int bt_parse(const char *opt)
885{
886 const char *endp, *p;
887 int vlan;
888
889 if (strstart(opt, "hci", &endp)) {
890 if (!*endp || *endp == ',') {
891 if (*endp)
892 if (!strstart(endp, ",vlan=", 0))
893 opt = endp + 1;
894
895 return bt_hci_parse(opt);
896 }
897 } else if (strstart(opt, "vhci", &endp)) {
898 if (!*endp || *endp == ',') {
899 if (*endp) {
900 if (strstart(endp, ",vlan=", &p)) {
901 vlan = strtol(p, (char **) &endp, 0);
902 if (*endp) {
903 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
904 return 1;
905 }
906 } else {
907 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
908 return 1;
909 }
910 } else
911 vlan = 0;
912
913 bt_vhci_add(vlan);
914 return 0;
915 }
916 } else if (strstart(opt, "device:", &endp))
917 return !bt_device_add(endp);
918
919 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
920 return 1;
921}
922
923/***********************************************************/
924/* QEMU Block devices */
925
926#define HD_ALIAS "index=%d,media=disk"
927#define CDROM_ALIAS "index=2,media=cdrom"
928#define FD_ALIAS "index=%d,if=floppy"
929#define PFLASH_ALIAS "if=pflash"
930#define MTD_ALIAS "if=mtd"
931#define SD_ALIAS "index=0,if=sd"
932
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100933static int drive_init_func(QemuOpts *opts, void *opaque)
934{
935 int *use_scsi = opaque;
936 int fatal_error = 0;
937
938 if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
939 if (fatal_error)
940 return 1;
941 }
942 return 0;
943}
944
945static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
946{
947 if (NULL == qemu_opt_get(opts, "snapshot")) {
948 qemu_opt_set(opts, "snapshot", "on");
949 }
950 return 0;
951}
952
953#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700954static int drive_opt_get_free_idx(void)
955{
956 int index;
957
958 for (index = 0; index < MAX_DRIVES; index++)
959 if (!drives_opt[index].used) {
960 drives_opt[index].used = 1;
961 return index;
962 }
963
964 return -1;
965}
966
967static int drive_get_free_idx(void)
968{
969 int index;
970
971 for (index = 0; index < MAX_DRIVES; index++)
972 if (!drives_table[index].used) {
973 drives_table[index].used = 1;
974 return index;
975 }
976
977 return -1;
978}
979
980int drive_add(const char *file, const char *fmt, ...)
981{
982 va_list ap;
983 int index = drive_opt_get_free_idx();
984
985 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
986 fprintf(stderr, "qemu: too many drives\n");
987 return -1;
988 }
989
990 drives_opt[index].file = file;
991 va_start(ap, fmt);
992 vsnprintf(drives_opt[index].opt,
993 sizeof(drives_opt[0].opt), fmt, ap);
994 va_end(ap);
David 'Digit' Turner92568952010-04-15 15:04:16 -0700995
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700996 nb_drives_opt++;
997 return index;
998}
999
1000void drive_remove(int index)
1001{
1002 drives_opt[index].used = 0;
1003 nb_drives_opt--;
1004}
1005
1006int drive_get_index(BlockInterfaceType type, int bus, int unit)
1007{
1008 int index;
1009
1010 /* seek interface, bus and unit */
1011
1012 for (index = 0; index < MAX_DRIVES; index++)
1013 if (drives_table[index].type == type &&
1014 drives_table[index].bus == bus &&
1015 drives_table[index].unit == unit &&
1016 drives_table[index].used)
1017 return index;
1018
1019 return -1;
1020}
1021
1022int drive_get_max_bus(BlockInterfaceType type)
1023{
1024 int max_bus;
1025 int index;
1026
1027 max_bus = -1;
1028 for (index = 0; index < nb_drives; index++) {
1029 if(drives_table[index].type == type &&
1030 drives_table[index].bus > max_bus)
1031 max_bus = drives_table[index].bus;
1032 }
1033 return max_bus;
1034}
1035
1036const char *drive_get_serial(BlockDriverState *bdrv)
1037{
1038 int index;
1039
1040 for (index = 0; index < nb_drives; index++)
1041 if (drives_table[index].bdrv == bdrv)
1042 return drives_table[index].serial;
1043
1044 return "\0";
1045}
1046
1047BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
1048{
1049 int index;
1050
1051 for (index = 0; index < nb_drives; index++)
1052 if (drives_table[index].bdrv == bdrv)
1053 return drives_table[index].onerror;
1054
1055 return BLOCK_ERR_STOP_ENOSPC;
1056}
1057
1058static void bdrv_format_print(void *opaque, const char *name)
1059{
1060 fprintf(stderr, " %s", name);
1061}
1062
1063void drive_uninit(BlockDriverState *bdrv)
1064{
1065 int i;
1066
1067 for (i = 0; i < MAX_DRIVES; i++)
1068 if (drives_table[i].bdrv == bdrv) {
1069 drives_table[i].bdrv = NULL;
1070 drives_table[i].used = 0;
1071 drive_remove(drives_table[i].drive_opt_idx);
1072 nb_drives--;
1073 break;
1074 }
1075}
1076
1077int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
1078{
1079 char buf[128];
1080 char file[1024];
1081 char devname[128];
1082 char serial[21];
1083 const char *mediastr = "";
1084 BlockInterfaceType type;
1085 enum { MEDIA_DISK, MEDIA_CDROM } media;
1086 int bus_id, unit_id;
1087 int cyls, heads, secs, translation;
1088 BlockDriverState *bdrv;
1089 BlockDriver *drv = NULL;
1090 QEMUMachine *machine = opaque;
1091 int max_devs;
1092 int index;
1093 int cache;
1094 int bdrv_flags, onerror;
1095 int drives_table_idx;
1096 char *str = arg->opt;
1097 static const char * const params[] = { "bus", "unit", "if", "index",
1098 "cyls", "heads", "secs", "trans",
1099 "media", "snapshot", "file",
1100 "cache", "format", "serial", "werror",
1101 NULL };
1102
1103 if (check_params(buf, sizeof(buf), params, str) < 0) {
1104 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
1105 buf, str);
1106 return -1;
1107 }
1108
1109 file[0] = 0;
1110 cyls = heads = secs = 0;
1111 bus_id = 0;
1112 unit_id = -1;
1113 translation = BIOS_ATA_TRANSLATION_AUTO;
1114 index = -1;
1115 cache = 3;
1116
1117 if (machine->use_scsi) {
1118 type = IF_SCSI;
1119 max_devs = MAX_SCSI_DEVS;
1120 pstrcpy(devname, sizeof(devname), "scsi");
1121 } else {
1122 type = IF_IDE;
1123 max_devs = MAX_IDE_DEVS;
1124 pstrcpy(devname, sizeof(devname), "ide");
1125 }
1126 media = MEDIA_DISK;
1127
1128 /* extract parameters */
1129
1130 if (get_param_value(buf, sizeof(buf), "bus", str)) {
1131 bus_id = strtol(buf, NULL, 0);
1132 if (bus_id < 0) {
1133 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
1134 return -1;
1135 }
1136 }
1137
1138 if (get_param_value(buf, sizeof(buf), "unit", str)) {
1139 unit_id = strtol(buf, NULL, 0);
1140 if (unit_id < 0) {
1141 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
1142 return -1;
1143 }
1144 }
1145
1146 if (get_param_value(buf, sizeof(buf), "if", str)) {
1147 pstrcpy(devname, sizeof(devname), buf);
1148 if (!strcmp(buf, "ide")) {
1149 type = IF_IDE;
1150 max_devs = MAX_IDE_DEVS;
1151 } else if (!strcmp(buf, "scsi")) {
1152 type = IF_SCSI;
1153 max_devs = MAX_SCSI_DEVS;
1154 } else if (!strcmp(buf, "floppy")) {
1155 type = IF_FLOPPY;
1156 max_devs = 0;
1157 } else if (!strcmp(buf, "pflash")) {
1158 type = IF_PFLASH;
1159 max_devs = 0;
1160 } else if (!strcmp(buf, "mtd")) {
1161 type = IF_MTD;
1162 max_devs = 0;
1163 } else if (!strcmp(buf, "sd")) {
1164 type = IF_SD;
1165 max_devs = 0;
1166 } else if (!strcmp(buf, "virtio")) {
1167 type = IF_VIRTIO;
1168 max_devs = 0;
1169 } else if (!strcmp(buf, "xen")) {
1170 type = IF_XEN;
1171 max_devs = 0;
1172 } else {
1173 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
1174 return -1;
1175 }
1176 }
1177
1178 if (get_param_value(buf, sizeof(buf), "index", str)) {
1179 index = strtol(buf, NULL, 0);
1180 if (index < 0) {
1181 fprintf(stderr, "qemu: '%s' invalid index\n", str);
1182 return -1;
1183 }
1184 }
1185
1186 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
1187 cyls = strtol(buf, NULL, 0);
1188 }
1189
1190 if (get_param_value(buf, sizeof(buf), "heads", str)) {
1191 heads = strtol(buf, NULL, 0);
1192 }
1193
1194 if (get_param_value(buf, sizeof(buf), "secs", str)) {
1195 secs = strtol(buf, NULL, 0);
1196 }
1197
1198 if (cyls || heads || secs) {
1199 if (cyls < 1 || cyls > 16383) {
1200 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
1201 return -1;
1202 }
1203 if (heads < 1 || heads > 16) {
1204 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
1205 return -1;
1206 }
1207 if (secs < 1 || secs > 63) {
1208 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
1209 return -1;
1210 }
1211 }
1212
1213 if (get_param_value(buf, sizeof(buf), "trans", str)) {
1214 if (!cyls) {
1215 fprintf(stderr,
1216 "qemu: '%s' trans must be used with cyls,heads and secs\n",
1217 str);
1218 return -1;
1219 }
1220 if (!strcmp(buf, "none"))
1221 translation = BIOS_ATA_TRANSLATION_NONE;
1222 else if (!strcmp(buf, "lba"))
1223 translation = BIOS_ATA_TRANSLATION_LBA;
1224 else if (!strcmp(buf, "auto"))
1225 translation = BIOS_ATA_TRANSLATION_AUTO;
1226 else {
1227 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
1228 return -1;
1229 }
1230 }
1231
1232 if (get_param_value(buf, sizeof(buf), "media", str)) {
1233 if (!strcmp(buf, "disk")) {
1234 media = MEDIA_DISK;
1235 } else if (!strcmp(buf, "cdrom")) {
1236 if (cyls || secs || heads) {
1237 fprintf(stderr,
1238 "qemu: '%s' invalid physical CHS format\n", str);
1239 return -1;
1240 }
1241 media = MEDIA_CDROM;
1242 } else {
1243 fprintf(stderr, "qemu: '%s' invalid media\n", str);
1244 return -1;
1245 }
1246 }
1247
1248 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
1249 if (!strcmp(buf, "on"))
1250 snapshot = 1;
1251 else if (!strcmp(buf, "off"))
1252 snapshot = 0;
1253 else {
1254 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
1255 return -1;
1256 }
1257 }
1258
1259 if (get_param_value(buf, sizeof(buf), "cache", str)) {
1260 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
1261 cache = 0;
1262 else if (!strcmp(buf, "writethrough"))
1263 cache = 1;
1264 else if (!strcmp(buf, "writeback"))
1265 cache = 2;
1266 else {
1267 fprintf(stderr, "qemu: invalid cache option\n");
1268 return -1;
1269 }
1270 }
1271
1272 if (get_param_value(buf, sizeof(buf), "format", str)) {
1273 if (strcmp(buf, "?") == 0) {
1274 fprintf(stderr, "qemu: Supported formats:");
1275 bdrv_iterate_format(bdrv_format_print, NULL);
1276 fprintf(stderr, "\n");
1277 return -1;
1278 }
1279 drv = bdrv_find_format(buf);
1280 if (!drv) {
1281 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
1282 return -1;
1283 }
1284 }
1285
1286 if (arg->file == NULL)
1287 get_param_value(file, sizeof(file), "file", str);
1288 else
1289 pstrcpy(file, sizeof(file), arg->file);
1290
1291 if (!get_param_value(serial, sizeof(serial), "serial", str))
1292 memset(serial, 0, sizeof(serial));
1293
1294 onerror = BLOCK_ERR_STOP_ENOSPC;
1295 if (get_param_value(buf, sizeof(serial), "werror", str)) {
1296 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
1297 fprintf(stderr, "werror is no supported by this format\n");
1298 return -1;
1299 }
1300 if (!strcmp(buf, "ignore"))
1301 onerror = BLOCK_ERR_IGNORE;
1302 else if (!strcmp(buf, "enospc"))
1303 onerror = BLOCK_ERR_STOP_ENOSPC;
1304 else if (!strcmp(buf, "stop"))
1305 onerror = BLOCK_ERR_STOP_ANY;
1306 else if (!strcmp(buf, "report"))
1307 onerror = BLOCK_ERR_REPORT;
1308 else {
1309 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
1310 return -1;
1311 }
1312 }
1313
1314 /* compute bus and unit according index */
1315
1316 if (index != -1) {
1317 if (bus_id != 0 || unit_id != -1) {
1318 fprintf(stderr,
1319 "qemu: '%s' index cannot be used with bus and unit\n", str);
1320 return -1;
1321 }
1322 if (max_devs == 0)
1323 {
1324 unit_id = index;
1325 bus_id = 0;
1326 } else {
1327 unit_id = index % max_devs;
1328 bus_id = index / max_devs;
1329 }
1330 }
1331
1332 /* if user doesn't specify a unit_id,
1333 * try to find the first free
1334 */
1335
1336 if (unit_id == -1) {
1337 unit_id = 0;
1338 while (drive_get_index(type, bus_id, unit_id) != -1) {
1339 unit_id++;
1340 if (max_devs && unit_id >= max_devs) {
1341 unit_id -= max_devs;
1342 bus_id++;
1343 }
1344 }
1345 }
1346
1347 /* check unit id */
1348
1349 if (max_devs && unit_id >= max_devs) {
1350 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
1351 str, unit_id, max_devs - 1);
1352 return -1;
1353 }
1354
1355 /*
1356 * ignore multiple definitions
1357 */
1358
1359 if (drive_get_index(type, bus_id, unit_id) != -1)
1360 return -2;
1361
1362 /* init */
1363
1364 if (type == IF_IDE || type == IF_SCSI)
1365 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
1366 if (max_devs)
1367 snprintf(buf, sizeof(buf), "%s%i%s%i",
1368 devname, bus_id, mediastr, unit_id);
1369 else
1370 snprintf(buf, sizeof(buf), "%s%s%i",
1371 devname, mediastr, unit_id);
1372 bdrv = bdrv_new(buf);
1373 drives_table_idx = drive_get_free_idx();
1374 drives_table[drives_table_idx].bdrv = bdrv;
1375 drives_table[drives_table_idx].type = type;
1376 drives_table[drives_table_idx].bus = bus_id;
1377 drives_table[drives_table_idx].unit = unit_id;
1378 drives_table[drives_table_idx].onerror = onerror;
1379 drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
1380 strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
1381 nb_drives++;
1382
1383 switch(type) {
1384 case IF_IDE:
1385 case IF_SCSI:
1386 case IF_XEN:
1387 switch(media) {
1388 case MEDIA_DISK:
1389 if (cyls != 0) {
1390 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
1391 bdrv_set_translation_hint(bdrv, translation);
1392 }
1393 break;
1394 case MEDIA_CDROM:
1395 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
1396 break;
1397 }
1398 break;
1399 case IF_SD:
1400 /* FIXME: This isn't really a floppy, but it's a reasonable
1401 approximation. */
1402 case IF_FLOPPY:
1403 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
1404 break;
1405 case IF_PFLASH:
1406 case IF_MTD:
1407 case IF_VIRTIO:
1408 break;
1409 case IF_COUNT:
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07001410 case IF_NONE:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001411 abort();
1412 }
1413 if (!file[0])
1414 return -2;
1415 bdrv_flags = 0;
1416 if (snapshot) {
1417 bdrv_flags |= BDRV_O_SNAPSHOT;
1418 cache = 2; /* always use write-back with snapshot */
1419 }
1420 if (cache == 0) /* no caching */
1421 bdrv_flags |= BDRV_O_NOCACHE;
1422 else if (cache == 2) /* write-back */
1423 bdrv_flags |= BDRV_O_CACHE_WB;
1424 else if (cache == 3) /* not specified */
1425 bdrv_flags |= BDRV_O_CACHE_DEF;
1426 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
1427 fprintf(stderr, "qemu: could not open disk image %s\n",
1428 file);
1429 return -1;
1430 }
1431 if (bdrv_key_required(bdrv))
1432 autostart = 0;
1433 return drives_table_idx;
1434}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001435#endif /* MAX_DRIVES */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001436
1437static void numa_add(const char *optarg)
1438{
1439 char option[128];
1440 char *endptr;
1441 unsigned long long value, endvalue;
1442 int nodenr;
1443
1444 optarg = get_opt_name(option, 128, optarg, ',') + 1;
1445 if (!strcmp(option, "node")) {
1446 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
1447 nodenr = nb_numa_nodes;
1448 } else {
1449 nodenr = strtoull(option, NULL, 10);
1450 }
1451
1452 if (get_param_value(option, 128, "mem", optarg) == 0) {
1453 node_mem[nodenr] = 0;
1454 } else {
1455 value = strtoull(option, &endptr, 0);
1456 switch (*endptr) {
1457 case 0: case 'M': case 'm':
1458 value <<= 20;
1459 break;
1460 case 'G': case 'g':
1461 value <<= 30;
1462 break;
1463 }
1464 node_mem[nodenr] = value;
1465 }
1466 if (get_param_value(option, 128, "cpus", optarg) == 0) {
1467 node_cpumask[nodenr] = 0;
1468 } else {
1469 value = strtoull(option, &endptr, 10);
1470 if (value >= 64) {
1471 value = 63;
1472 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
1473 } else {
1474 if (*endptr == '-') {
1475 endvalue = strtoull(endptr+1, &endptr, 10);
1476 if (endvalue >= 63) {
1477 endvalue = 62;
1478 fprintf(stderr,
1479 "only 63 CPUs in NUMA mode supported.\n");
1480 }
1481 value = (1 << (endvalue + 1)) - (1 << value);
1482 } else {
1483 value = 1 << value;
1484 }
1485 }
1486 node_cpumask[nodenr] = value;
1487 }
1488 nb_numa_nodes++;
1489 }
1490 return;
1491}
1492
1493/***********************************************************/
1494/* USB devices */
1495
1496static USBPort *used_usb_ports;
1497static USBPort *free_usb_ports;
1498
1499/* ??? Maybe change this to register a hub to keep track of the topology. */
1500void qemu_register_usb_port(USBPort *port, void *opaque, int index,
1501 usb_attachfn attach)
1502{
1503 port->opaque = opaque;
1504 port->index = index;
1505 port->attach = attach;
1506 port->next = free_usb_ports;
1507 free_usb_ports = port;
1508}
1509
1510int usb_device_add_dev(USBDevice *dev)
1511{
1512 USBPort *port;
1513
1514 /* Find a USB port to add the device to. */
1515 port = free_usb_ports;
1516 if (!port->next) {
1517 USBDevice *hub;
1518
1519 /* Create a new hub and chain it on. */
1520 free_usb_ports = NULL;
1521 port->next = used_usb_ports;
1522 used_usb_ports = port;
1523
1524 hub = usb_hub_init(VM_USB_HUB_SIZE);
1525 usb_attach(port, hub);
1526 port = free_usb_ports;
1527 }
1528
1529 free_usb_ports = port->next;
1530 port->next = used_usb_ports;
1531 used_usb_ports = port;
1532 usb_attach(port, dev);
1533 return 0;
1534}
1535
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001536#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001537static void usb_msd_password_cb(void *opaque, int err)
1538{
1539 USBDevice *dev = opaque;
1540
1541 if (!err)
1542 usb_device_add_dev(dev);
1543 else
1544 dev->handle_destroy(dev);
1545}
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001546#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001547
1548static int usb_device_add(const char *devname, int is_hotplug)
1549{
1550 const char *p;
1551 USBDevice *dev;
1552
1553 if (!free_usb_ports)
1554 return -1;
1555
1556 if (strstart(devname, "host:", &p)) {
1557 dev = usb_host_device_open(p);
1558 } else if (!strcmp(devname, "mouse")) {
1559 dev = usb_mouse_init();
1560 } else if (!strcmp(devname, "tablet")) {
1561 dev = usb_tablet_init();
1562 } else if (!strcmp(devname, "keyboard")) {
1563 dev = usb_keyboard_init();
1564 } else if (strstart(devname, "disk:", &p)) {
1565#if 0
1566 BlockDriverState *bs;
1567#endif
1568 dev = usb_msd_init(p);
1569 if (!dev)
1570 return -1;
1571#if 0
1572 bs = usb_msd_get_bdrv(dev);
1573 if (bdrv_key_required(bs)) {
1574 autostart = 0;
1575 if (is_hotplug) {
1576 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
1577 dev);
1578 return 0;
1579 }
1580 }
1581 } else if (!strcmp(devname, "wacom-tablet")) {
1582 dev = usb_wacom_init();
1583 } else if (strstart(devname, "serial:", &p)) {
1584 dev = usb_serial_init(p);
1585#ifdef CONFIG_BRLAPI
1586 } else if (!strcmp(devname, "braille")) {
1587 dev = usb_baum_init();
1588#endif
1589 } else if (strstart(devname, "net:", &p)) {
1590 int nic = nb_nics;
1591
1592 if (net_client_init("nic", p) < 0)
1593 return -1;
1594 nd_table[nic].model = "usb";
1595 dev = usb_net_init(&nd_table[nic]);
1596 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
1597 dev = usb_bt_init(devname[2] ? hci_init(p) :
1598 bt_new_hci(qemu_find_bt_vlan(0)));
1599#endif
1600 } else {
1601 return -1;
1602 }
1603 if (!dev)
1604 return -1;
1605
1606 return usb_device_add_dev(dev);
1607}
1608
1609int usb_device_del_addr(int bus_num, int addr)
1610{
1611 USBPort *port;
1612 USBPort **lastp;
1613 USBDevice *dev;
1614
1615 if (!used_usb_ports)
1616 return -1;
1617
1618 if (bus_num != 0)
1619 return -1;
1620
1621 lastp = &used_usb_ports;
1622 port = used_usb_ports;
1623 while (port && port->dev->addr != addr) {
1624 lastp = &port->next;
1625 port = port->next;
1626 }
1627
1628 if (!port)
1629 return -1;
1630
1631 dev = port->dev;
1632 *lastp = port->next;
1633 usb_attach(port, NULL);
1634 dev->handle_destroy(dev);
1635 port->next = free_usb_ports;
1636 free_usb_ports = port;
1637 return 0;
1638}
1639
1640static int usb_device_del(const char *devname)
1641{
1642 int bus_num, addr;
1643 const char *p;
1644
1645 if (strstart(devname, "host:", &p))
1646 return usb_host_device_close(p);
1647
1648 if (!used_usb_ports)
1649 return -1;
1650
1651 p = strchr(devname, '.');
1652 if (!p)
1653 return -1;
1654 bus_num = strtoul(devname, NULL, 0);
1655 addr = strtoul(p + 1, NULL, 0);
1656
1657 return usb_device_del_addr(bus_num, addr);
1658}
1659
1660void do_usb_add(Monitor *mon, const char *devname)
1661{
1662 usb_device_add(devname, 1);
1663}
1664
1665void do_usb_del(Monitor *mon, const char *devname)
1666{
1667 usb_device_del(devname);
1668}
1669
1670void usb_info(Monitor *mon)
1671{
1672 USBDevice *dev;
1673 USBPort *port;
1674 const char *speed_str;
1675
1676 if (!usb_enabled) {
1677 monitor_printf(mon, "USB support not enabled\n");
1678 return;
1679 }
1680
1681 for (port = used_usb_ports; port; port = port->next) {
1682 dev = port->dev;
1683 if (!dev)
1684 continue;
1685 switch(dev->speed) {
1686 case USB_SPEED_LOW:
1687 speed_str = "1.5";
1688 break;
1689 case USB_SPEED_FULL:
1690 speed_str = "12";
1691 break;
1692 case USB_SPEED_HIGH:
1693 speed_str = "480";
1694 break;
1695 default:
1696 speed_str = "?";
1697 break;
1698 }
1699 monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
1700 0, dev->addr, speed_str, dev->devname);
1701 }
1702}
1703
1704/***********************************************************/
1705/* PCMCIA/Cardbus */
1706
1707static struct pcmcia_socket_entry_s {
1708 PCMCIASocket *socket;
1709 struct pcmcia_socket_entry_s *next;
1710} *pcmcia_sockets = 0;
1711
1712void pcmcia_socket_register(PCMCIASocket *socket)
1713{
1714 struct pcmcia_socket_entry_s *entry;
1715
1716 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
1717 entry->socket = socket;
1718 entry->next = pcmcia_sockets;
1719 pcmcia_sockets = entry;
1720}
1721
1722void pcmcia_socket_unregister(PCMCIASocket *socket)
1723{
1724 struct pcmcia_socket_entry_s *entry, **ptr;
1725
1726 ptr = &pcmcia_sockets;
1727 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
1728 if (entry->socket == socket) {
1729 *ptr = entry->next;
1730 qemu_free(entry);
1731 }
1732}
1733
1734void pcmcia_info(Monitor *mon)
1735{
1736 struct pcmcia_socket_entry_s *iter;
1737
1738 if (!pcmcia_sockets)
1739 monitor_printf(mon, "No PCMCIA sockets\n");
1740
1741 for (iter = pcmcia_sockets; iter; iter = iter->next)
1742 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
1743 iter->socket->attached ? iter->socket->card_string :
1744 "Empty");
1745}
1746
1747/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001748/* I/O handling */
1749
1750typedef struct IOHandlerRecord {
1751 int fd;
David Turner4143d8f2010-09-10 11:05:02 +02001752 IOCanReadHandler *fd_read_poll;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001753 IOHandler *fd_read;
1754 IOHandler *fd_write;
1755 int deleted;
1756 void *opaque;
1757 /* temporary data */
1758 struct pollfd *ufd;
1759 struct IOHandlerRecord *next;
1760} IOHandlerRecord;
1761
1762static IOHandlerRecord *first_io_handler;
1763
1764/* XXX: fd_read_poll should be suppressed, but an API change is
1765 necessary in the character devices to suppress fd_can_read(). */
1766int qemu_set_fd_handler2(int fd,
David Turner4143d8f2010-09-10 11:05:02 +02001767 IOCanReadHandler *fd_read_poll,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001768 IOHandler *fd_read,
1769 IOHandler *fd_write,
1770 void *opaque)
1771{
1772 IOHandlerRecord **pioh, *ioh;
1773
1774 if (!fd_read && !fd_write) {
1775 pioh = &first_io_handler;
1776 for(;;) {
1777 ioh = *pioh;
1778 if (ioh == NULL)
1779 break;
1780 if (ioh->fd == fd) {
1781 ioh->deleted = 1;
1782 break;
1783 }
1784 pioh = &ioh->next;
1785 }
1786 } else {
1787 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
1788 if (ioh->fd == fd)
1789 goto found;
1790 }
1791 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1792 ioh->next = first_io_handler;
1793 first_io_handler = ioh;
1794 found:
1795 ioh->fd = fd;
1796 ioh->fd_read_poll = fd_read_poll;
1797 ioh->fd_read = fd_read;
1798 ioh->fd_write = fd_write;
1799 ioh->opaque = opaque;
1800 ioh->deleted = 0;
1801 }
1802 return 0;
1803}
1804
1805int qemu_set_fd_handler(int fd,
1806 IOHandler *fd_read,
1807 IOHandler *fd_write,
1808 void *opaque)
1809{
1810 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
1811}
1812
1813#ifdef _WIN32
1814/***********************************************************/
1815/* Polling handling */
1816
1817typedef struct PollingEntry {
1818 PollingFunc *func;
1819 void *opaque;
1820 struct PollingEntry *next;
1821} PollingEntry;
1822
1823static PollingEntry *first_polling_entry;
1824
1825int qemu_add_polling_cb(PollingFunc *func, void *opaque)
1826{
1827 PollingEntry **ppe, *pe;
1828 pe = qemu_mallocz(sizeof(PollingEntry));
1829 pe->func = func;
1830 pe->opaque = opaque;
1831 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
1832 *ppe = pe;
1833 return 0;
1834}
1835
1836void qemu_del_polling_cb(PollingFunc *func, void *opaque)
1837{
1838 PollingEntry **ppe, *pe;
1839 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
1840 pe = *ppe;
1841 if (pe->func == func && pe->opaque == opaque) {
1842 *ppe = pe->next;
1843 qemu_free(pe);
1844 break;
1845 }
1846 }
1847}
1848
1849/***********************************************************/
1850/* Wait objects support */
1851typedef struct WaitObjects {
1852 int num;
1853 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
1854 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
1855 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
1856} WaitObjects;
1857
1858static WaitObjects wait_objects = {0};
1859
1860int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
1861{
1862 WaitObjects *w = &wait_objects;
1863
1864 if (w->num >= MAXIMUM_WAIT_OBJECTS)
1865 return -1;
1866 w->events[w->num] = handle;
1867 w->func[w->num] = func;
1868 w->opaque[w->num] = opaque;
1869 w->num++;
1870 return 0;
1871}
1872
1873void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
1874{
1875 int i, found;
1876 WaitObjects *w = &wait_objects;
1877
1878 found = 0;
1879 for (i = 0; i < w->num; i++) {
1880 if (w->events[i] == handle)
1881 found = 1;
1882 if (found) {
1883 w->events[i] = w->events[i + 1];
1884 w->func[i] = w->func[i + 1];
1885 w->opaque[i] = w->opaque[i + 1];
1886 }
1887 }
1888 if (found)
1889 w->num--;
1890}
1891#endif
1892
1893/***********************************************************/
1894/* ram save/restore */
1895
1896static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
1897{
1898 int v;
1899
1900 v = qemu_get_byte(f);
1901 switch(v) {
1902 case 0:
1903 if (qemu_get_buffer(f, buf, len) != len)
1904 return -EIO;
1905 break;
1906 case 1:
1907 v = qemu_get_byte(f);
1908 memset(buf, v, len);
1909 break;
1910 default:
1911 return -EINVAL;
1912 }
1913
1914 if (qemu_file_has_error(f))
1915 return -EIO;
1916
1917 return 0;
1918}
1919
1920static int ram_load_v1(QEMUFile *f, void *opaque)
1921{
1922 int ret;
1923 ram_addr_t i;
1924
1925 if (qemu_get_be32(f) != last_ram_offset)
1926 return -EINVAL;
1927 for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
1928 ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
1929 if (ret)
1930 return ret;
1931 }
1932 return 0;
1933}
1934
1935#define BDRV_HASH_BLOCK_SIZE 1024
1936#define IOBUF_SIZE 4096
1937#define RAM_CBLOCK_MAGIC 0xfabe
1938
1939typedef struct RamDecompressState {
1940 z_stream zstream;
1941 QEMUFile *f;
1942 uint8_t buf[IOBUF_SIZE];
1943} RamDecompressState;
1944
1945static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
1946{
1947 int ret;
1948 memset(s, 0, sizeof(*s));
1949 s->f = f;
1950 ret = inflateInit(&s->zstream);
1951 if (ret != Z_OK)
1952 return -1;
1953 return 0;
1954}
1955
1956static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
1957{
1958 int ret, clen;
1959
1960 s->zstream.avail_out = len;
1961 s->zstream.next_out = buf;
1962 while (s->zstream.avail_out > 0) {
1963 if (s->zstream.avail_in == 0) {
1964 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
1965 return -1;
1966 clen = qemu_get_be16(s->f);
1967 if (clen > IOBUF_SIZE)
1968 return -1;
1969 qemu_get_buffer(s->f, s->buf, clen);
1970 s->zstream.avail_in = clen;
1971 s->zstream.next_in = s->buf;
1972 }
1973 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
1974 if (ret != Z_OK && ret != Z_STREAM_END) {
1975 return -1;
1976 }
1977 }
1978 return 0;
1979}
1980
1981static void ram_decompress_close(RamDecompressState *s)
1982{
1983 inflateEnd(&s->zstream);
1984}
1985
1986#define RAM_SAVE_FLAG_FULL 0x01
1987#define RAM_SAVE_FLAG_COMPRESS 0x02
1988#define RAM_SAVE_FLAG_MEM_SIZE 0x04
1989#define RAM_SAVE_FLAG_PAGE 0x08
1990#define RAM_SAVE_FLAG_EOS 0x10
1991
1992static int is_dup_page(uint8_t *page, uint8_t ch)
1993{
1994 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
1995 uint32_t *array = (uint32_t *)page;
1996 int i;
1997
1998 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
1999 if (array[i] != val)
2000 return 0;
2001 }
2002
2003 return 1;
2004}
2005
2006static int ram_save_block(QEMUFile *f)
2007{
2008 static ram_addr_t current_addr = 0;
2009 ram_addr_t saved_addr = current_addr;
2010 ram_addr_t addr = 0;
2011 int found = 0;
2012
2013 while (addr < last_ram_offset) {
2014 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
2015 uint8_t *p;
2016
2017 cpu_physical_memory_reset_dirty(current_addr,
2018 current_addr + TARGET_PAGE_SIZE,
2019 MIGRATION_DIRTY_FLAG);
2020
2021 p = qemu_get_ram_ptr(current_addr);
2022
2023 if (is_dup_page(p, *p)) {
2024 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
2025 qemu_put_byte(f, *p);
2026 } else {
2027 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
2028 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
2029 }
2030
2031 found = 1;
2032 break;
2033 }
2034 addr += TARGET_PAGE_SIZE;
2035 current_addr = (saved_addr + addr) % last_ram_offset;
2036 }
2037
2038 return found;
2039}
2040
2041static uint64_t bytes_transferred = 0;
2042
2043static ram_addr_t ram_save_remaining(void)
2044{
2045 ram_addr_t addr;
2046 ram_addr_t count = 0;
2047
2048 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2049 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2050 count++;
2051 }
2052
2053 return count;
2054}
2055
2056uint64_t ram_bytes_remaining(void)
2057{
2058 return ram_save_remaining() * TARGET_PAGE_SIZE;
2059}
2060
2061uint64_t ram_bytes_transferred(void)
2062{
2063 return bytes_transferred;
2064}
2065
2066uint64_t ram_bytes_total(void)
2067{
2068 return last_ram_offset;
2069}
2070
2071static int ram_save_live(QEMUFile *f, int stage, void *opaque)
2072{
2073 ram_addr_t addr;
2074 uint64_t bytes_transferred_last;
2075 double bwidth = 0;
2076 uint64_t expected_time = 0;
2077
2078 cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX);
2079
2080 if (stage == 1) {
2081 /* Make sure all dirty bits are set */
2082 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2083 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2084 cpu_physical_memory_set_dirty(addr);
2085 }
2086
2087 /* Enable dirty memory tracking */
2088 cpu_physical_memory_set_dirty_tracking(1);
2089
2090 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
2091 }
2092
2093 bytes_transferred_last = bytes_transferred;
David Turner6a9ef172010-09-09 22:54:36 +02002094 bwidth = qemu_get_clock_ns(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002095
2096 while (!qemu_file_rate_limit(f)) {
2097 int ret;
2098
2099 ret = ram_save_block(f);
2100 bytes_transferred += ret * TARGET_PAGE_SIZE;
2101 if (ret == 0) /* no more blocks */
2102 break;
2103 }
2104
David Turner6a9ef172010-09-09 22:54:36 +02002105 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002106 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
2107
2108 /* if we haven't transferred anything this round, force expected_time to a
2109 * a very high value, but without crashing */
2110 if (bwidth == 0)
2111 bwidth = 0.000001;
2112
2113 /* try transferring iterative blocks of memory */
2114
2115 if (stage == 3) {
2116
2117 /* flush all remaining blocks regardless of rate limiting */
2118 while (ram_save_block(f) != 0) {
2119 bytes_transferred += TARGET_PAGE_SIZE;
2120 }
2121 cpu_physical_memory_set_dirty_tracking(0);
2122 }
2123
2124 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
2125
2126 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
2127
2128 return (stage == 2) && (expected_time <= migrate_max_downtime());
2129}
2130
2131static int ram_load_dead(QEMUFile *f, void *opaque)
2132{
2133 RamDecompressState s1, *s = &s1;
2134 uint8_t buf[10];
2135 ram_addr_t i;
2136
2137 if (ram_decompress_open(s, f) < 0)
2138 return -EINVAL;
2139 for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
2140 if (ram_decompress_buf(s, buf, 1) < 0) {
2141 fprintf(stderr, "Error while reading ram block header\n");
2142 goto error;
2143 }
2144 if (buf[0] == 0) {
2145 if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
2146 BDRV_HASH_BLOCK_SIZE) < 0) {
2147 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
2148 goto error;
2149 }
2150 } else {
2151 error:
2152 printf("Error block header\n");
2153 return -EINVAL;
2154 }
2155 }
2156 ram_decompress_close(s);
2157
2158 return 0;
2159}
2160
2161static int ram_load(QEMUFile *f, void *opaque, int version_id)
2162{
2163 ram_addr_t addr;
2164 int flags;
2165
2166 if (version_id == 1)
2167 return ram_load_v1(f, opaque);
2168
2169 if (version_id == 2) {
2170 if (qemu_get_be32(f) != last_ram_offset)
2171 return -EINVAL;
2172 return ram_load_dead(f, opaque);
2173 }
2174
2175 if (version_id != 3)
2176 return -EINVAL;
2177
2178 do {
2179 addr = qemu_get_be64(f);
2180
2181 flags = addr & ~TARGET_PAGE_MASK;
2182 addr &= TARGET_PAGE_MASK;
2183
2184 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
2185 if (addr != last_ram_offset)
2186 return -EINVAL;
2187 }
2188
2189 if (flags & RAM_SAVE_FLAG_FULL) {
2190 if (ram_load_dead(f, opaque) < 0)
2191 return -EINVAL;
2192 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07002193
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002194 if (flags & RAM_SAVE_FLAG_COMPRESS) {
2195 uint8_t ch = qemu_get_byte(f);
2196 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
2197 } else if (flags & RAM_SAVE_FLAG_PAGE)
2198 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
2199 } while (!(flags & RAM_SAVE_FLAG_EOS));
2200
2201 return 0;
2202}
2203
2204void qemu_service_io(void)
2205{
2206 qemu_notify_event();
2207}
2208
2209/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002210/* machine registration */
2211
2212static QEMUMachine *first_machine = NULL;
2213QEMUMachine *current_machine = NULL;
2214
2215int qemu_register_machine(QEMUMachine *m)
2216{
2217 QEMUMachine **pm;
2218 pm = &first_machine;
2219 while (*pm != NULL)
2220 pm = &(*pm)->next;
2221 m->next = NULL;
2222 *pm = m;
2223 return 0;
2224}
2225
2226static QEMUMachine *find_machine(const char *name)
2227{
2228 QEMUMachine *m;
2229
2230 for(m = first_machine; m != NULL; m = m->next) {
2231 if (!strcmp(m->name, name))
2232 return m;
2233 }
2234 return NULL;
2235}
2236
2237static QEMUMachine *find_default_machine(void)
2238{
2239 QEMUMachine *m;
2240
2241 for(m = first_machine; m != NULL; m = m->next) {
2242 if (m->is_default) {
2243 return m;
2244 }
2245 }
2246 return NULL;
2247}
2248
2249/***********************************************************/
2250/* main execution loop */
2251
2252static void gui_update(void *opaque)
2253{
2254 uint64_t interval = GUI_REFRESH_INTERVAL;
2255 DisplayState *ds = opaque;
2256 DisplayChangeListener *dcl = ds->listeners;
2257
2258 dpy_refresh(ds);
2259
2260 while (dcl != NULL) {
2261 if (dcl->gui_timer_interval &&
2262 dcl->gui_timer_interval < interval)
2263 interval = dcl->gui_timer_interval;
2264 dcl = dcl->next;
2265 }
2266 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
2267}
2268
2269static void nographic_update(void *opaque)
2270{
2271 uint64_t interval = GUI_REFRESH_INTERVAL;
2272
2273 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
2274}
2275
2276struct vm_change_state_entry {
2277 VMChangeStateHandler *cb;
2278 void *opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002279 QLIST_ENTRY (vm_change_state_entry) entries;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002280};
2281
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002282static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002283
2284VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
2285 void *opaque)
2286{
2287 VMChangeStateEntry *e;
2288
2289 e = qemu_mallocz(sizeof (*e));
2290
2291 e->cb = cb;
2292 e->opaque = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002293 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002294 return e;
2295}
2296
2297void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
2298{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002299 QLIST_REMOVE (e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002300 qemu_free (e);
2301}
2302
2303static void vm_state_notify(int running, int reason)
2304{
2305 VMChangeStateEntry *e;
2306
2307 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
2308 e->cb(e->opaque, running, reason);
2309 }
2310}
2311
2312static void resume_all_vcpus(void);
2313static void pause_all_vcpus(void);
2314
2315void vm_start(void)
2316{
2317 if (!vm_running) {
2318 cpu_enable_ticks();
2319 vm_running = 1;
2320 vm_state_notify(1, 0);
David Turner6a9ef172010-09-09 22:54:36 +02002321 //qemu_rearm_alarm_timer(alarm_timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002322 resume_all_vcpus();
2323 }
2324}
2325
2326/* reset/shutdown handler */
2327
2328typedef struct QEMUResetEntry {
2329 QEMUResetHandler *func;
2330 void *opaque;
2331 int order;
2332 struct QEMUResetEntry *next;
2333} QEMUResetEntry;
2334
2335static QEMUResetEntry *first_reset_entry;
2336static int reset_requested;
2337static int shutdown_requested;
2338static int powerdown_requested;
2339static int debug_requested;
2340static int vmstop_requested;
2341
2342int qemu_shutdown_requested(void)
2343{
2344 int r = shutdown_requested;
2345 shutdown_requested = 0;
2346 return r;
2347}
2348
2349int qemu_reset_requested(void)
2350{
2351 int r = reset_requested;
2352 reset_requested = 0;
2353 return r;
2354}
2355
2356int qemu_powerdown_requested(void)
2357{
2358 int r = powerdown_requested;
2359 powerdown_requested = 0;
2360 return r;
2361}
2362
2363static int qemu_debug_requested(void)
2364{
2365 int r = debug_requested;
2366 debug_requested = 0;
2367 return r;
2368}
2369
2370static int qemu_vmstop_requested(void)
2371{
2372 int r = vmstop_requested;
2373 vmstop_requested = 0;
2374 return r;
2375}
2376
2377static void do_vm_stop(int reason)
2378{
2379 if (vm_running) {
2380 cpu_disable_ticks();
2381 vm_running = 0;
2382 pause_all_vcpus();
2383 vm_state_notify(0, reason);
2384 }
2385}
2386
2387void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
2388{
2389 QEMUResetEntry **pre, *re;
2390
2391 pre = &first_reset_entry;
2392 while (*pre != NULL && (*pre)->order >= order) {
2393 pre = &(*pre)->next;
2394 }
2395 re = qemu_mallocz(sizeof(QEMUResetEntry));
2396 re->func = func;
2397 re->opaque = opaque;
2398 re->order = order;
2399 re->next = NULL;
2400 *pre = re;
2401}
2402
2403void qemu_system_reset(void)
2404{
2405 QEMUResetEntry *re;
2406
2407 /* reset all devices */
2408 for(re = first_reset_entry; re != NULL; re = re->next) {
2409 re->func(re->opaque);
2410 }
2411}
2412
2413void qemu_system_reset_request(void)
2414{
2415 if (no_reboot) {
2416 shutdown_requested = 1;
2417 } else {
2418 reset_requested = 1;
2419 }
2420 qemu_notify_event();
2421}
2422
2423void qemu_system_shutdown_request(void)
2424{
2425 shutdown_requested = 1;
2426 qemu_notify_event();
2427}
2428
2429void qemu_system_powerdown_request(void)
2430{
2431 powerdown_requested = 1;
2432 qemu_notify_event();
2433}
2434
2435#ifdef CONFIG_IOTHREAD
2436static void qemu_system_vmstop_request(int reason)
2437{
2438 vmstop_requested = reason;
2439 qemu_notify_event();
2440}
2441#endif
2442
2443#ifndef _WIN32
2444static int io_thread_fd = -1;
2445
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002446#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002447static void qemu_event_increment(void)
2448{
2449 static const char byte = 0;
2450
2451 if (io_thread_fd == -1)
2452 return;
2453
2454 write(io_thread_fd, &byte, sizeof(byte));
2455}
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002456#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002457
2458static void qemu_event_read(void *opaque)
2459{
2460 int fd = (unsigned long)opaque;
2461 ssize_t len;
2462
2463 /* Drain the notify pipe */
2464 do {
2465 char buffer[512];
2466 len = read(fd, buffer, sizeof(buffer));
2467 } while ((len == -1 && errno == EINTR) || len > 0);
2468}
2469
2470static int qemu_event_init(void)
2471{
2472 int err;
2473 int fds[2];
2474
2475 err = pipe(fds);
2476 if (err == -1)
2477 return -errno;
2478
2479 err = fcntl_setfl(fds[0], O_NONBLOCK);
2480 if (err < 0)
2481 goto fail;
2482
2483 err = fcntl_setfl(fds[1], O_NONBLOCK);
2484 if (err < 0)
2485 goto fail;
2486
2487 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
2488 (void *)(unsigned long)fds[0]);
2489
2490 io_thread_fd = fds[1];
2491 return 0;
2492
2493fail:
2494 close(fds[0]);
2495 close(fds[1]);
2496 return err;
2497}
2498#else
2499HANDLE qemu_event_handle;
2500
2501static void dummy_event_handler(void *opaque)
2502{
2503}
2504
2505static int qemu_event_init(void)
2506{
2507 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
2508 if (!qemu_event_handle) {
2509 perror("Failed CreateEvent");
2510 return -1;
2511 }
2512 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
2513 return 0;
2514}
2515
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02002516#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002517static void qemu_event_increment(void)
2518{
2519 SetEvent(qemu_event_handle);
2520}
2521#endif
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02002522#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002523
2524static int cpu_can_run(CPUState *env)
2525{
2526 if (env->stop)
2527 return 0;
2528 if (env->stopped)
2529 return 0;
2530 return 1;
2531}
2532
2533#ifndef CONFIG_IOTHREAD
2534static int qemu_init_main_loop(void)
2535{
2536 return qemu_event_init();
2537}
2538
2539void qemu_init_vcpu(void *_env)
2540{
2541 CPUState *env = _env;
2542
2543 if (kvm_enabled())
2544 kvm_init_vcpu(env);
2545 return;
2546}
2547
2548int qemu_cpu_self(void *env)
2549{
2550 return 1;
2551}
2552
2553static void resume_all_vcpus(void)
2554{
2555}
2556
2557static void pause_all_vcpus(void)
2558{
2559}
2560
2561void qemu_cpu_kick(void *env)
2562{
2563 return;
2564}
2565
2566void qemu_notify_event(void)
2567{
2568 CPUState *env = cpu_single_env;
2569
2570 if (env) {
2571 cpu_exit(env);
2572#ifdef USE_KQEMU
2573 if (env->kqemu_enabled)
2574 kqemu_cpu_interrupt(env);
2575#endif
2576 }
2577}
2578
2579#define qemu_mutex_lock_iothread() do { } while (0)
2580#define qemu_mutex_unlock_iothread() do { } while (0)
2581
2582void vm_stop(int reason)
2583{
2584 do_vm_stop(reason);
2585}
2586
2587#else /* CONFIG_IOTHREAD */
2588
2589#include "qemu-thread.h"
2590
2591QemuMutex qemu_global_mutex;
2592static QemuMutex qemu_fair_mutex;
2593
2594static QemuThread io_thread;
2595
2596static QemuThread *tcg_cpu_thread;
2597static QemuCond *tcg_halt_cond;
2598
2599static int qemu_system_ready;
2600/* cpu creation */
2601static QemuCond qemu_cpu_cond;
2602/* system init */
2603static QemuCond qemu_system_cond;
2604static QemuCond qemu_pause_cond;
2605
2606static void block_io_signals(void);
2607static void unblock_io_signals(void);
2608static int tcg_has_work(void);
2609
2610static int qemu_init_main_loop(void)
2611{
2612 int ret;
2613
2614 ret = qemu_event_init();
2615 if (ret)
2616 return ret;
2617
2618 qemu_cond_init(&qemu_pause_cond);
2619 qemu_mutex_init(&qemu_fair_mutex);
2620 qemu_mutex_init(&qemu_global_mutex);
2621 qemu_mutex_lock(&qemu_global_mutex);
2622
2623 unblock_io_signals();
2624 qemu_thread_self(&io_thread);
2625
2626 return 0;
2627}
2628
2629static void qemu_wait_io_event(CPUState *env)
2630{
2631 while (!tcg_has_work())
2632 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
2633
2634 qemu_mutex_unlock(&qemu_global_mutex);
2635
2636 /*
2637 * Users of qemu_global_mutex can be starved, having no chance
2638 * to acquire it since this path will get to it first.
2639 * So use another lock to provide fairness.
2640 */
2641 qemu_mutex_lock(&qemu_fair_mutex);
2642 qemu_mutex_unlock(&qemu_fair_mutex);
2643
2644 qemu_mutex_lock(&qemu_global_mutex);
2645 if (env->stop) {
2646 env->stop = 0;
2647 env->stopped = 1;
2648 qemu_cond_signal(&qemu_pause_cond);
2649 }
2650}
2651
2652static int qemu_cpu_exec(CPUState *env);
2653
2654static void *kvm_cpu_thread_fn(void *arg)
2655{
2656 CPUState *env = arg;
2657
2658 block_io_signals();
2659 qemu_thread_self(env->thread);
2660
2661 /* signal CPU creation */
2662 qemu_mutex_lock(&qemu_global_mutex);
2663 env->created = 1;
2664 qemu_cond_signal(&qemu_cpu_cond);
2665
2666 /* and wait for machine initialization */
2667 while (!qemu_system_ready)
2668 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2669
2670 while (1) {
2671 if (cpu_can_run(env))
2672 qemu_cpu_exec(env);
2673 qemu_wait_io_event(env);
2674 }
2675
2676 return NULL;
2677}
2678
2679static void tcg_cpu_exec(void);
2680
2681static void *tcg_cpu_thread_fn(void *arg)
2682{
2683 CPUState *env = arg;
2684
2685 block_io_signals();
2686 qemu_thread_self(env->thread);
2687
2688 /* signal CPU creation */
2689 qemu_mutex_lock(&qemu_global_mutex);
2690 for (env = first_cpu; env != NULL; env = env->next_cpu)
2691 env->created = 1;
2692 qemu_cond_signal(&qemu_cpu_cond);
2693
2694 /* and wait for machine initialization */
2695 while (!qemu_system_ready)
2696 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2697
2698 while (1) {
2699 tcg_cpu_exec();
2700 qemu_wait_io_event(cur_cpu);
2701 }
2702
2703 return NULL;
2704}
2705
2706void qemu_cpu_kick(void *_env)
2707{
2708 CPUState *env = _env;
2709 qemu_cond_broadcast(env->halt_cond);
2710 if (kvm_enabled())
2711 qemu_thread_signal(env->thread, SIGUSR1);
2712}
2713
2714int qemu_cpu_self(void *env)
2715{
2716 return (cpu_single_env != NULL);
2717}
2718
2719static void cpu_signal(int sig)
2720{
2721 if (cpu_single_env)
2722 cpu_exit(cpu_single_env);
2723}
2724
2725static void block_io_signals(void)
2726{
2727 sigset_t set;
2728 struct sigaction sigact;
2729
2730 sigemptyset(&set);
2731 sigaddset(&set, SIGUSR2);
2732 sigaddset(&set, SIGIO);
2733 sigaddset(&set, SIGALRM);
2734 pthread_sigmask(SIG_BLOCK, &set, NULL);
2735
2736 sigemptyset(&set);
2737 sigaddset(&set, SIGUSR1);
2738 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2739
2740 memset(&sigact, 0, sizeof(sigact));
2741 sigact.sa_handler = cpu_signal;
2742 sigaction(SIGUSR1, &sigact, NULL);
2743}
2744
2745static void unblock_io_signals(void)
2746{
2747 sigset_t set;
2748
2749 sigemptyset(&set);
2750 sigaddset(&set, SIGUSR2);
2751 sigaddset(&set, SIGIO);
2752 sigaddset(&set, SIGALRM);
2753 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2754
2755 sigemptyset(&set);
2756 sigaddset(&set, SIGUSR1);
2757 pthread_sigmask(SIG_BLOCK, &set, NULL);
2758}
2759
2760static void qemu_signal_lock(unsigned int msecs)
2761{
2762 qemu_mutex_lock(&qemu_fair_mutex);
2763
2764 while (qemu_mutex_trylock(&qemu_global_mutex)) {
2765 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
2766 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
2767 break;
2768 }
2769 qemu_mutex_unlock(&qemu_fair_mutex);
2770}
2771
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002772void qemu_mutex_lock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002773{
2774 if (kvm_enabled()) {
2775 qemu_mutex_lock(&qemu_fair_mutex);
2776 qemu_mutex_lock(&qemu_global_mutex);
2777 qemu_mutex_unlock(&qemu_fair_mutex);
2778 } else
2779 qemu_signal_lock(100);
2780}
2781
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002782void qemu_mutex_unlock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002783{
2784 qemu_mutex_unlock(&qemu_global_mutex);
2785}
2786
2787static int all_vcpus_paused(void)
2788{
2789 CPUState *penv = first_cpu;
2790
2791 while (penv) {
2792 if (!penv->stopped)
2793 return 0;
2794 penv = (CPUState *)penv->next_cpu;
2795 }
2796
2797 return 1;
2798}
2799
2800static void pause_all_vcpus(void)
2801{
2802 CPUState *penv = first_cpu;
2803
2804 while (penv) {
2805 penv->stop = 1;
2806 qemu_thread_signal(penv->thread, SIGUSR1);
2807 qemu_cpu_kick(penv);
2808 penv = (CPUState *)penv->next_cpu;
2809 }
2810
2811 while (!all_vcpus_paused()) {
2812 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
2813 penv = first_cpu;
2814 while (penv) {
2815 qemu_thread_signal(penv->thread, SIGUSR1);
2816 penv = (CPUState *)penv->next_cpu;
2817 }
2818 }
2819}
2820
2821static void resume_all_vcpus(void)
2822{
2823 CPUState *penv = first_cpu;
2824
2825 while (penv) {
2826 penv->stop = 0;
2827 penv->stopped = 0;
2828 qemu_thread_signal(penv->thread, SIGUSR1);
2829 qemu_cpu_kick(penv);
2830 penv = (CPUState *)penv->next_cpu;
2831 }
2832}
2833
2834static void tcg_init_vcpu(void *_env)
2835{
2836 CPUState *env = _env;
2837 /* share a single thread for all cpus with TCG */
2838 if (!tcg_cpu_thread) {
2839 env->thread = qemu_mallocz(sizeof(QemuThread));
2840 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
2841 qemu_cond_init(env->halt_cond);
2842 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
2843 while (env->created == 0)
2844 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2845 tcg_cpu_thread = env->thread;
2846 tcg_halt_cond = env->halt_cond;
2847 } else {
2848 env->thread = tcg_cpu_thread;
2849 env->halt_cond = tcg_halt_cond;
2850 }
2851}
2852
2853static void kvm_start_vcpu(CPUState *env)
2854{
2855#if 0
2856 kvm_init_vcpu(env);
2857 env->thread = qemu_mallocz(sizeof(QemuThread));
2858 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
2859 qemu_cond_init(env->halt_cond);
2860 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
2861 while (env->created == 0)
2862 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2863#endif
2864}
2865
2866void qemu_init_vcpu(void *_env)
2867{
2868 CPUState *env = _env;
2869
2870 if (kvm_enabled())
2871 kvm_start_vcpu(env);
2872 else
2873 tcg_init_vcpu(env);
2874}
2875
2876void qemu_notify_event(void)
2877{
2878 qemu_event_increment();
2879}
2880
2881void vm_stop(int reason)
2882{
2883 QemuThread me;
2884 qemu_thread_self(&me);
2885
2886 if (!qemu_thread_equal(&me, &io_thread)) {
2887 qemu_system_vmstop_request(reason);
2888 /*
2889 * FIXME: should not return to device code in case
2890 * vm_stop() has been requested.
2891 */
2892 if (cpu_single_env) {
2893 cpu_exit(cpu_single_env);
2894 cpu_single_env->stop = 1;
2895 }
2896 return;
2897 }
2898 do_vm_stop(reason);
2899}
2900
2901#endif
2902
2903
2904#ifdef _WIN32
2905static void host_main_loop_wait(int *timeout)
2906{
2907 int ret, ret2, i;
2908 PollingEntry *pe;
2909
2910
2911 /* XXX: need to suppress polling by better using win32 events */
2912 ret = 0;
2913 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
2914 ret |= pe->func(pe->opaque);
2915 }
2916 if (ret == 0) {
2917 int err;
2918 WaitObjects *w = &wait_objects;
2919
2920 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
2921 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
2922 if (w->func[ret - WAIT_OBJECT_0])
2923 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
2924
2925 /* Check for additional signaled events */
2926 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
2927
2928 /* Check if event is signaled */
2929 ret2 = WaitForSingleObject(w->events[i], 0);
2930 if(ret2 == WAIT_OBJECT_0) {
2931 if (w->func[i])
2932 w->func[i](w->opaque[i]);
2933 } else if (ret2 == WAIT_TIMEOUT) {
2934 } else {
2935 err = GetLastError();
2936 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
2937 }
2938 }
2939 } else if (ret == WAIT_TIMEOUT) {
2940 } else {
2941 err = GetLastError();
2942 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
2943 }
2944 }
2945
2946 *timeout = 0;
2947}
2948#else
2949static void host_main_loop_wait(int *timeout)
2950{
2951}
2952#endif
2953
2954void main_loop_wait(int timeout)
2955{
2956 IOHandlerRecord *ioh;
2957 fd_set rfds, wfds, xfds;
2958 int ret, nfds;
2959 struct timeval tv;
2960
2961 qemu_bh_update_timeout(&timeout);
2962
2963 host_main_loop_wait(&timeout);
2964
2965 /* poll any events */
2966 /* XXX: separate device handlers from system ones */
2967 nfds = -1;
2968 FD_ZERO(&rfds);
2969 FD_ZERO(&wfds);
2970 FD_ZERO(&xfds);
2971 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2972 if (ioh->deleted)
2973 continue;
2974 if (ioh->fd_read &&
2975 (!ioh->fd_read_poll ||
2976 ioh->fd_read_poll(ioh->opaque) != 0)) {
2977 FD_SET(ioh->fd, &rfds);
2978 if (ioh->fd > nfds)
2979 nfds = ioh->fd;
2980 }
2981 if (ioh->fd_write) {
2982 FD_SET(ioh->fd, &wfds);
2983 if (ioh->fd > nfds)
2984 nfds = ioh->fd;
2985 }
2986 }
2987
2988 tv.tv_sec = timeout / 1000;
2989 tv.tv_usec = (timeout % 1000) * 1000;
2990
2991#if defined(CONFIG_SLIRP)
2992 if (slirp_is_inited()) {
2993 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2994 }
2995#endif
2996 qemu_mutex_unlock_iothread();
2997 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
2998 qemu_mutex_lock_iothread();
2999 if (ret > 0) {
3000 IOHandlerRecord **pioh;
3001
3002 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
3003 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
3004 ioh->fd_read(ioh->opaque);
3005 }
3006 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
3007 ioh->fd_write(ioh->opaque);
3008 }
3009 }
3010
David 'Digit' Turner6b512812010-10-15 15:05:04 +02003011 /* remove deleted IO handlers */
3012 pioh = &first_io_handler;
3013 while (*pioh) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003014 ioh = *pioh;
3015 if (ioh->deleted) {
3016 *pioh = ioh->next;
3017 qemu_free(ioh);
3018 } else
3019 pioh = &ioh->next;
3020 }
3021 }
3022#if defined(CONFIG_SLIRP)
3023 if (slirp_is_inited()) {
3024 if (ret < 0) {
3025 FD_ZERO(&rfds);
3026 FD_ZERO(&wfds);
3027 FD_ZERO(&xfds);
3028 }
3029 slirp_select_poll(&rfds, &wfds, &xfds);
3030 }
3031#endif
3032 charpipe_poll();
3033
David Turner6a9ef172010-09-09 22:54:36 +02003034 qemu_run_all_timers();
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003035
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003036 /* Check bottom-halves last in case any of the earlier events triggered
3037 them. */
3038 qemu_bh_poll();
3039
3040}
3041
3042static int qemu_cpu_exec(CPUState *env)
3043{
3044 int ret;
3045#ifdef CONFIG_PROFILER
3046 int64_t ti;
3047#endif
3048
3049#ifdef CONFIG_PROFILER
3050 ti = profile_getclock();
3051#endif
3052 if (use_icount) {
3053 int64_t count;
3054 int decr;
3055 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3056 env->icount_decr.u16.low = 0;
3057 env->icount_extra = 0;
3058 count = qemu_next_deadline();
3059 count = (count + (1 << icount_time_shift) - 1)
3060 >> icount_time_shift;
3061 qemu_icount += count;
3062 decr = (count > 0xffff) ? 0xffff : count;
3063 count -= decr;
3064 env->icount_decr.u16.low = decr;
3065 env->icount_extra = count;
3066 }
David 'Digit' Turnera577fca2009-10-15 18:18:09 -07003067#ifdef CONFIG_TRACE
3068 if (tbflush_requested) {
3069 tbflush_requested = 0;
3070 tb_flush(env);
3071 return EXCP_INTERRUPT;
3072 }
3073#endif
3074
3075
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003076 ret = cpu_exec(env);
3077#ifdef CONFIG_PROFILER
3078 qemu_time += profile_getclock() - ti;
3079#endif
3080 if (use_icount) {
3081 /* Fold pending instructions back into the
3082 instruction counter, and clear the interrupt flag. */
3083 qemu_icount -= (env->icount_decr.u16.low
3084 + env->icount_extra);
3085 env->icount_decr.u32 = 0;
3086 env->icount_extra = 0;
3087 }
3088 return ret;
3089}
3090
3091static void tcg_cpu_exec(void)
3092{
3093 int ret = 0;
3094
3095 if (next_cpu == NULL)
3096 next_cpu = first_cpu;
3097 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
3098 CPUState *env = cur_cpu = next_cpu;
3099
3100 if (!vm_running)
3101 break;
David 'Digit' Turner6b512812010-10-15 15:05:04 +02003102 if (qemu_timer_alarm_pending()) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003103 break;
3104 }
3105 if (cpu_can_run(env))
3106 ret = qemu_cpu_exec(env);
3107 if (ret == EXCP_DEBUG) {
3108 gdb_set_stop_cpu(env);
3109 debug_requested = 1;
3110 break;
3111 }
3112 }
3113}
3114
3115static int cpu_has_work(CPUState *env)
3116{
3117 if (env->stop)
3118 return 1;
3119 if (env->stopped)
3120 return 0;
3121 if (!env->halted)
3122 return 1;
3123 if (qemu_cpu_has_work(env))
3124 return 1;
3125 return 0;
3126}
3127
David 'Digit' Turner6b512812010-10-15 15:05:04 +02003128int tcg_has_work(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003129{
3130 CPUState *env;
3131
3132 for (env = first_cpu; env != NULL; env = env->next_cpu)
3133 if (cpu_has_work(env))
3134 return 1;
3135 return 0;
3136}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003137
3138static int vm_can_run(void)
3139{
3140 if (powerdown_requested)
3141 return 0;
3142 if (reset_requested)
3143 return 0;
3144 if (shutdown_requested)
3145 return 0;
3146 if (debug_requested)
3147 return 0;
3148 return 1;
3149}
3150
3151static void main_loop(void)
3152{
3153 int r;
3154
3155#ifdef CONFIG_IOTHREAD
3156 qemu_system_ready = 1;
3157 qemu_cond_broadcast(&qemu_system_cond);
3158#endif
3159
3160 for (;;) {
3161 do {
3162#ifdef CONFIG_PROFILER
3163 int64_t ti;
3164#endif
3165#ifndef CONFIG_IOTHREAD
3166 tcg_cpu_exec();
3167#endif
3168#ifdef CONFIG_PROFILER
3169 ti = profile_getclock();
3170#endif
3171 main_loop_wait(qemu_calculate_timeout());
3172#ifdef CONFIG_PROFILER
3173 dev_time += profile_getclock() - ti;
3174#endif
rich canningsd952f282011-03-01 15:40:09 -08003175
3176 if (rotate_logs_requested) {
3177 FILE* new_dns_log_fd = rotate_qemu_log(get_slirp_dns_log_fd(),
3178 dns_log_filename);
3179 FILE* new_drop_log_fd = rotate_qemu_log(get_slirp_drop_log_fd(),
3180 drop_log_filename);
3181 slirp_dns_log_fd(new_dns_log_fd);
3182 slirp_drop_log_fd(new_drop_log_fd);
3183 reset_rotate_qemu_logs_request();
3184 }
3185
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003186 } while (vm_can_run());
3187
3188 if (qemu_debug_requested())
3189 vm_stop(EXCP_DEBUG);
3190 if (qemu_shutdown_requested()) {
3191 if (no_shutdown) {
3192 vm_stop(0);
3193 no_shutdown = 0;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003194 } else {
Tim Baverstock24204cc2010-11-25 11:37:43 +00003195 if (savevm_on_exit != NULL) {
3196 do_savevm(cur_mon, savevm_on_exit);
3197 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003198 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003199 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003200 }
3201 if (qemu_reset_requested()) {
3202 pause_all_vcpus();
3203 qemu_system_reset();
3204 resume_all_vcpus();
3205 }
3206 if (qemu_powerdown_requested())
3207 qemu_system_powerdown();
3208 if ((r = qemu_vmstop_requested()))
3209 vm_stop(r);
3210 }
3211 pause_all_vcpus();
3212}
3213
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003214void version(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003215{
3216 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3217}
3218
3219void qemu_help(int exitcode)
3220{
3221 version();
3222 printf("usage: %s [options] [disk_image]\n"
3223 "\n"
3224 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
3225 "\n"
3226#define DEF(option, opt_arg, opt_enum, opt_help) \
3227 opt_help
3228#define DEFHEADING(text) stringify(text) "\n"
3229#include "qemu-options.h"
3230#undef DEF
3231#undef DEFHEADING
3232#undef GEN_DOCS
3233 "\n"
3234 "During emulation, the following keys are useful:\n"
3235 "ctrl-alt-f toggle full screen\n"
3236 "ctrl-alt-n switch to virtual console 'n'\n"
3237 "ctrl-alt toggle mouse and keyboard grab\n"
3238 "\n"
3239 "When using -nographic, press 'ctrl-a h' to get some help.\n"
3240 ,
3241 "qemu",
3242 DEFAULT_RAM_SIZE,
3243#ifndef _WIN32
3244 DEFAULT_NETWORK_SCRIPT,
3245 DEFAULT_NETWORK_DOWN_SCRIPT,
3246#endif
3247 DEFAULT_GDBSTUB_PORT,
3248 "/tmp/qemu.log");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003249 QEMU_EXIT(exitcode);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003250}
3251
3252#define HAS_ARG 0x0001
3253
3254enum {
3255#define DEF(option, opt_arg, opt_enum, opt_help) \
3256 opt_enum,
3257#define DEFHEADING(text)
3258#include "qemu-options.h"
3259#undef DEF
3260#undef DEFHEADING
3261#undef GEN_DOCS
3262};
3263
3264typedef struct QEMUOption {
3265 const char *name;
3266 int flags;
3267 int index;
3268} QEMUOption;
3269
3270static const QEMUOption qemu_options[] = {
3271 { "h", 0, QEMU_OPTION_h },
3272#define DEF(option, opt_arg, opt_enum, opt_help) \
3273 { option, opt_arg, opt_enum },
3274#define DEFHEADING(text)
3275#include "qemu-options.h"
3276#undef DEF
3277#undef DEFHEADING
3278#undef GEN_DOCS
3279 { NULL, 0, 0 },
3280};
3281
3282#ifdef HAS_AUDIO
3283struct soundhw soundhw[] = {
3284#ifdef HAS_AUDIO_CHOICE
3285#if defined(TARGET_I386) || defined(TARGET_MIPS)
3286 {
3287 "pcspk",
3288 "PC speaker",
3289 0,
3290 1,
3291 { .init_isa = pcspk_audio_init }
3292 },
3293#endif
3294
3295#ifdef CONFIG_SB16
3296 {
3297 "sb16",
3298 "Creative Sound Blaster 16",
3299 0,
3300 1,
3301 { .init_isa = SB16_init }
3302 },
3303#endif
3304
3305#ifdef CONFIG_CS4231A
3306 {
3307 "cs4231a",
3308 "CS4231A",
3309 0,
3310 1,
3311 { .init_isa = cs4231a_init }
3312 },
3313#endif
3314
3315#ifdef CONFIG_ADLIB
3316 {
3317 "adlib",
3318#ifdef HAS_YMF262
3319 "Yamaha YMF262 (OPL3)",
3320#else
3321 "Yamaha YM3812 (OPL2)",
3322#endif
3323 0,
3324 1,
3325 { .init_isa = Adlib_init }
3326 },
3327#endif
3328
3329#ifdef CONFIG_GUS
3330 {
3331 "gus",
3332 "Gravis Ultrasound GF1",
3333 0,
3334 1,
3335 { .init_isa = GUS_init }
3336 },
3337#endif
3338
3339#ifdef CONFIG_AC97
3340 {
3341 "ac97",
3342 "Intel 82801AA AC97 Audio",
3343 0,
3344 0,
3345 { .init_pci = ac97_init }
3346 },
3347#endif
3348
3349#ifdef CONFIG_ES1370
3350 {
3351 "es1370",
3352 "ENSONIQ AudioPCI ES1370",
3353 0,
3354 0,
3355 { .init_pci = es1370_init }
3356 },
3357#endif
3358
3359#endif /* HAS_AUDIO_CHOICE */
3360
3361 { NULL, NULL, 0, 0, { NULL } }
3362};
3363
3364static void select_soundhw (const char *optarg)
3365{
3366 struct soundhw *c;
3367
3368 if (*optarg == '?') {
3369 show_valid_cards:
3370
3371 printf ("Valid sound card names (comma separated):\n");
3372 for (c = soundhw; c->name; ++c) {
3373 printf ("%-11s %s\n", c->name, c->descr);
3374 }
3375 printf ("\n-soundhw all will enable all of the above\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003376 if (*optarg != '?') {
3377 PANIC("Unknown sound card name: %s", optarg);
3378 } else {
3379 QEMU_EXIT(0);
3380 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003381 }
3382 else {
3383 size_t l;
3384 const char *p;
3385 char *e;
3386 int bad_card = 0;
3387
3388 if (!strcmp (optarg, "all")) {
3389 for (c = soundhw; c->name; ++c) {
3390 c->enabled = 1;
3391 }
3392 return;
3393 }
3394
3395 p = optarg;
3396 while (*p) {
3397 e = strchr (p, ',');
3398 l = !e ? strlen (p) : (size_t) (e - p);
3399
3400 for (c = soundhw; c->name; ++c) {
3401 if (!strncmp (c->name, p, l)) {
3402 c->enabled = 1;
3403 break;
3404 }
3405 }
3406
3407 if (!c->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003408#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003409 if (l > 80) {
3410 fprintf (stderr,
3411 "Unknown sound card name (too big to show)\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003412 } else {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003413 fprintf (stderr, "Unknown sound card name `%.*s'\n",
3414 (int) l, p);
3415 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003416#endif // !CONFIG_ANDROID
3417 bad_card = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003418 }
3419 p += l + (e != NULL);
3420 }
3421
3422 if (bad_card)
3423 goto show_valid_cards;
3424 }
3425}
3426#endif
3427
3428static void select_vgahw (const char *p)
3429{
3430 const char *opts;
3431
3432 cirrus_vga_enabled = 0;
3433 std_vga_enabled = 0;
3434 vmsvga_enabled = 0;
3435 xenfb_enabled = 0;
3436 if (strstart(p, "std", &opts)) {
3437 std_vga_enabled = 1;
3438 } else if (strstart(p, "cirrus", &opts)) {
3439 cirrus_vga_enabled = 1;
3440 } else if (strstart(p, "vmware", &opts)) {
3441 vmsvga_enabled = 1;
3442 } else if (strstart(p, "xenfb", &opts)) {
3443 xenfb_enabled = 1;
3444 } else if (!strstart(p, "none", &opts)) {
3445 invalid_vga:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003446 PANIC("Unknown vga type: %s", p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003447 }
3448 while (*opts) {
3449 const char *nextopt;
3450
3451 if (strstart(opts, ",retrace=", &nextopt)) {
3452 opts = nextopt;
3453 if (strstart(opts, "dumb", &nextopt))
3454 vga_retrace_method = VGA_RETRACE_DUMB;
3455 else if (strstart(opts, "precise", &nextopt))
3456 vga_retrace_method = VGA_RETRACE_PRECISE;
3457 else goto invalid_vga;
3458 } else goto invalid_vga;
3459 opts = nextopt;
3460 }
3461}
3462
3463#ifdef _WIN32
3464static BOOL WINAPI qemu_ctrl_handler(DWORD type)
3465{
3466 exit(STATUS_CONTROL_C_EXIT);
3467 return TRUE;
3468}
3469#endif
3470
3471int qemu_uuid_parse(const char *str, uint8_t *uuid)
3472{
3473 int ret;
3474
3475 if(strlen(str) != 36)
3476 return -1;
3477
3478 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
3479 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
3480 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
3481
3482 if(ret != 16)
3483 return -1;
3484
3485#ifdef TARGET_I386
3486 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
3487#endif
3488
3489 return 0;
3490}
3491
3492#define MAX_NET_CLIENTS 32
3493
3494#ifndef _WIN32
3495
3496static void termsig_handler(int signal)
3497{
3498 qemu_system_shutdown_request();
3499}
3500
3501static void sigchld_handler(int signal)
3502{
3503 waitpid(-1, NULL, WNOHANG);
3504}
3505
3506static void sighandler_setup(void)
3507{
3508 struct sigaction act;
3509
3510 memset(&act, 0, sizeof(act));
3511 act.sa_handler = termsig_handler;
3512 sigaction(SIGINT, &act, NULL);
3513 sigaction(SIGHUP, &act, NULL);
3514 sigaction(SIGTERM, &act, NULL);
3515
3516 act.sa_handler = sigchld_handler;
3517 act.sa_flags = SA_NOCLDSTOP;
3518 sigaction(SIGCHLD, &act, NULL);
3519}
3520
3521#endif
3522
3523#ifdef _WIN32
3524/* Look for support files in the same directory as the executable. */
3525static char *find_datadir(const char *argv0)
3526{
3527 char *p;
3528 char buf[MAX_PATH];
3529 DWORD len;
3530
3531 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
3532 if (len == 0) {
3533 return NULL;
3534 }
3535
3536 buf[len] = 0;
3537 p = buf + len - 1;
3538 while (p != buf && *p != '\\')
3539 p--;
3540 *p = 0;
3541 if (access(buf, R_OK) == 0) {
3542 return qemu_strdup(buf);
3543 }
3544 return NULL;
3545}
3546#else /* !_WIN32 */
3547
3548/* Find a likely location for support files using the location of the binary.
3549 For installed binaries this will be "$bindir/../share/qemu". When
Bruce Beare02c63852011-02-24 09:10:52 -08003550 running from the build tree this will be "$bindir/../pc-bios".
3551 The emulator running from the SDK will find the support files in $bindir/lib/pc-bios. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003552#define SHARE_SUFFIX "/share/qemu"
3553#define BUILD_SUFFIX "/pc-bios"
Bruce Beare02c63852011-02-24 09:10:52 -08003554#define SDK_SUFFIX "/lib/pc-bios"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003555static char *find_datadir(const char *argv0)
3556{
3557 char *dir;
3558 char *p = NULL;
3559 char *res;
3560#ifdef PATH_MAX
3561 char buf[PATH_MAX];
3562#endif
3563 size_t max_len;
3564
3565#if defined(__linux__)
3566 {
3567 int len;
3568 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
3569 if (len > 0) {
3570 buf[len] = 0;
3571 p = buf;
3572 }
3573 }
3574#elif defined(__FreeBSD__)
3575 {
3576 int len;
3577 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
3578 if (len > 0) {
3579 buf[len] = 0;
3580 p = buf;
3581 }
3582 }
3583#endif
3584 /* If we don't have any way of figuring out the actual executable
3585 location then try argv[0]. */
3586 if (!p) {
3587#ifdef PATH_MAX
3588 p = buf;
3589#endif
3590 p = realpath(argv0, p);
3591 if (!p) {
3592 return NULL;
3593 }
3594 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003595
Bruce Beare02c63852011-02-24 09:10:52 -08003596#define STRLEN_CONST(str) (sizeof(str)-1)
3597 dir = dirname(p);
3598 max_len = strlen(dir) + 1 +
3599 MAX(STRLEN_CONST(SDK_SUFFIX), MAX(STRLEN_CONST(SHARE_SUFFIX), STRLEN_CONST(BUILD_SUFFIX)));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003600 res = qemu_mallocz(max_len);
Bruce Beare02c63852011-02-24 09:10:52 -08003601
3602 snprintf(res, max_len, "%s%s", dir, SDK_SUFFIX);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003603 if (access(res, R_OK)) {
Bruce Beare02c63852011-02-24 09:10:52 -08003604 dir = dirname(dir);
3605
3606 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
3607 if (access(res, R_OK)) {
3608 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
3609 if (access(res, R_OK)) {
3610 qemu_free(res);
3611 res = NULL;
3612 }
3613 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003614 }
3615#ifndef PATH_MAX
3616 free(p);
3617#endif
3618 return res;
3619}
3620#undef SHARE_SUFFIX
3621#undef BUILD_SUFFIX
3622#endif
3623
3624char *qemu_find_file(int type, const char *name)
3625{
3626 int len;
3627 const char *subdir;
3628 char *buf;
3629
3630 /* If name contains path separators then try it as a straight path. */
3631 if ((strchr(name, '/') || strchr(name, '\\'))
3632 && access(name, R_OK) == 0) {
3633 return strdup(name);
3634 }
3635 switch (type) {
3636 case QEMU_FILE_TYPE_BIOS:
3637 subdir = "";
3638 break;
3639 case QEMU_FILE_TYPE_KEYMAP:
3640 subdir = "keymaps/";
3641 break;
3642 default:
3643 abort();
3644 }
3645 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
3646 buf = qemu_mallocz(len);
3647 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
3648 if (access(buf, R_OK)) {
3649 qemu_free(buf);
3650 return NULL;
3651 }
3652 return buf;
3653}
3654
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003655static int
3656add_dns_server( const char* server_name )
3657{
3658 SockAddress addr;
3659
3660 if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
3661 fprintf(stdout,
3662 "### WARNING: can't resolve DNS server name '%s'\n",
3663 server_name );
3664 return -1;
3665 }
3666
3667 fprintf(stderr,
3668 "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
3669
3670 if ( slirp_add_dns_server( &addr ) < 0 ) {
3671 fprintf(stderr,
3672 "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
3673 return -1;
3674 }
3675 return 0;
3676}
3677
rich cannings7339b552011-02-16 13:43:44 -08003678/* Parses an integer
3679 * Pararm:
3680 * str String containing a number to be parsed.
3681 * result Passes the parsed integer in this argument
3682 * returns 0 if ok, -1 if failed
3683 */
3684int
3685parse_int(const char *str, int *result)
3686{
3687 char* r;
3688 *result = strtol(str, &r, 0);
3689 if (r == NULL || *r != '\0')
3690 return -1;
3691
3692 return 0;
3693}
3694
rich canningsd952f282011-03-01 15:40:09 -08003695#ifndef _WIN32
3696/*
3697 * Initializes the SIGUSR1 signal handler to clear Qemu logs.
3698 */
3699void init_qemu_clear_logs_sig() {
3700 struct sigaction act;
3701 sigfillset(&act.sa_mask);
3702 act.sa_flags = 0;
3703 act.sa_handler = rotate_qemu_logs_handler;
3704 if (sigaction(SIGUSR1, &act, NULL) == -1) {
3705 fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
3706 exit(-1);
3707 }
3708}
3709#endif
3710
3711
rich cannings7339b552011-02-16 13:43:44 -08003712
3713/* parses a null-terminated string specifying a network port (e.g., "80") or
3714 * port range (e.g., "[6666-7000]"). In case of a single port, lport and hport
3715 * are the same. Returns 0 on success, -1 on error. */
3716
3717int parse_port_range(const char *str, unsigned short *lport,
3718 unsigned short *hport) {
3719
3720 unsigned int low = 0, high = 0;
3721 char *p, *arg = strdup(str);
3722
3723 if ((*arg == '[') && ((p = strrchr(arg, ']')) != NULL)) {
3724 p = arg + 1; /* skip '[' */
3725 low = atoi(strtok(p, "-"));
3726 high = atoi(strtok(NULL, "-"));
3727 if ((low > 0) && (high > 0) && (low < high) && (high < 65535)) {
3728 *lport = low;
3729 *hport = high;
3730 }
3731 }
3732 else {
3733 low = atoi(arg);
3734 if ((0 < low) && (low < 65535)) {
3735 *lport = low;
3736 *hport = low;
3737 }
3738 }
3739 free(arg);
3740 if (low != 0)
3741 return 0;
3742 return -1;
3743}
3744
3745/*
3746 * Implements the generic port forwarding option
3747 */
3748void
3749net_slirp_forward(const char *optarg)
3750{
3751 /*
3752 * we expect the following format:
3753 * dst_net:dst_mask:dst_port:redirect_ip:redirect_port OR
3754 * dst_net:dst_mask:[dp_range_start-dp_range_end]:redirect_ip:redirect_port
3755 */
3756 char *argument = strdup(optarg), *p = argument;
3757 char *dst_net, *dst_mask, *dst_port;
3758 char *redirect_ip, *redirect_port;
3759 uint32_t dnet, dmask, rip;
3760 unsigned short dlport, dhport, rport;
3761
3762
3763 dst_net = strtok(p, ":");
3764 dst_mask = strtok(NULL, ":");
3765 dst_port = strtok(NULL, ":");
3766 redirect_ip = strtok(NULL, ":");
3767 redirect_port = strtok(NULL, ":");
3768
3769 if (dst_net == NULL || dst_mask == NULL || dst_port == NULL ||
3770 redirect_ip == NULL || redirect_port == NULL) {
3771 fprintf(stderr,
3772 "Invalid argument for -net-forward, we expect "
3773 "dst_net:dst_mask:dst_port:redirect_ip:redirect_port or "
3774 "dst_net:dst_mask:[dp_range_start-dp_range_end]"
3775 ":redirect_ip:redirect_port: %s\n",
3776 optarg);
3777 exit(1);
3778 }
3779
3780 /* inet_strtoip converts dotted address to host byte order */
3781 if (inet_strtoip(dst_net, &dnet) == -1) {
3782 fprintf(stderr, "Invalid destination IP net: %s\n", dst_net);
3783 exit(1);
3784 }
3785 if (inet_strtoip(dst_mask, &dmask) == -1) {
3786 fprintf(stderr, "Invalid destination IP mask: %s\n", dst_mask);
3787 exit(1);
3788 }
3789 if (inet_strtoip(redirect_ip, &rip) == -1) {
3790 fprintf(stderr, "Invalid redirect IP address: %s\n", redirect_ip);
3791 exit(1);
3792 }
3793
3794 if (parse_port_range(dst_port, &dlport, &dhport) == -1) {
3795 fprintf(stderr, "Invalid destination port or port range\n");
3796 exit(1);
3797 }
3798
3799 rport = atoi(redirect_port);
3800 if (!rport) {
3801 fprintf(stderr, "Invalid redirect port: %s\n", redirect_port);
3802 exit(1);
3803 }
3804
3805 dnet &= dmask;
3806
3807 slirp_add_net_forward(dnet, dmask, dlport, dhport,
3808 rip, rport);
3809
3810 free(argument);
3811}
3812
3813
3814/* Parses an -allow-tcp or -allow-udp argument and inserts a corresponding
3815 * entry in the allows list */
3816void
3817slirp_allow(const char *optarg, u_int8_t proto)
3818{
3819 /*
3820 * we expect the following format:
3821 * dst_ip:dst_port OR dst_ip:[dst_lport-dst_hport]
3822 */
3823 char *argument = strdup(optarg), *p = argument;
3824 char *dst_ip_str, *dst_port_str;
3825 uint32_t dst_ip;
3826 unsigned short dst_lport, dst_hport;
3827
3828 dst_ip_str = strtok(p, ":");
3829 dst_port_str = strtok(NULL, ":");
3830
3831 if (dst_ip_str == NULL || dst_port_str == NULL) {
3832 fprintf(stderr,
3833 "Invalid argument %s for -allow. We expect "
3834 "dst_ip:dst_port or dst_ip:[dst_lport-dst_hport]\n",
3835 optarg);
3836 exit(1);
3837 }
3838
3839 if (inet_strtoip(dst_ip_str, &dst_ip) == -1) {
3840 fprintf(stderr, "Invalid destination IP address: %s\n", dst_ip_str);
3841 exit(1);
3842 }
3843 if (parse_port_range(dst_port_str, &dst_lport, &dst_hport) == -1) {
3844 fprintf(stderr, "Invalid destination port or port range\n");
3845 exit(1);
3846 }
3847
3848 slirp_add_allow(dst_ip, dst_lport, dst_hport, proto);
3849
3850 free(argument);
3851}
3852
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01003853/* Add a serial device at a given location in the emulated hardware table.
3854 * On failure, this function aborts the program with an error message.
3855 */
3856static void
3857serial_hds_add_at(int index, const char* devname)
3858{
3859 char label[32];
3860
3861 if (!devname || !strcmp(devname,"none"))
3862 return;
3863
3864 if (index >= MAX_SERIAL_PORTS) {
3865 PANIC("qemu: invalid serial index for %s (%d >= %d)",
3866 devname, index, MAX_SERIAL_PORTS);
3867 }
3868 if (serial_hds[index] != NULL) {
3869 PANIC("qemu: invalid serial index for %s (%d: already taken!)",
3870 devname, index);
3871 }
3872 snprintf(label, sizeof(label), "serial%d", index);
3873 serial_hds[index] = qemu_chr_open(label, devname, NULL);
3874 if (!serial_hds[index]) {
3875 PANIC("qemu: could not open serial device '%s'", devname);
3876 }
3877}
3878
3879
3880/* Find a free slot in the emulated serial device table, and register
3881 * it. Return the allocated table index.
3882 */
3883static int
3884serial_hds_add(const char* devname)
3885{
3886 int index;
3887
3888 /* Find first free slot */
3889 for (index = 0; index < MAX_SERIAL_PORTS; index++) {
3890 if (serial_hds[index] == NULL) {
3891 serial_hds_add_at(index, devname);
3892 return index;
3893 }
3894 }
3895
3896 PANIC("qemu: too many serial devices registered (%d)", index);
3897 return -1; /* shouldn't happen */
3898}
3899
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003900int main(int argc, char **argv, char **envp)
3901{
3902 const char *gdbstub_dev = NULL;
3903 uint32_t boot_devices_bitmap = 0;
3904 int i;
3905 int snapshot, linux_boot, net_boot;
David Turner6a9ef172010-09-09 22:54:36 +02003906 const char *icount_option = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003907 const char *initrd_filename;
3908 const char *kernel_filename, *kernel_cmdline;
3909 const char *boot_devices = "";
3910 DisplayState *ds;
3911 DisplayChangeListener *dcl;
3912 int cyls, heads, secs, translation;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003913 QemuOpts *hda_opts = NULL;
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01003914 QemuOpts *hdb_opts = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003915 const char *net_clients[MAX_NET_CLIENTS];
3916 int nb_net_clients;
3917 const char *bt_opts[MAX_BT_CMDLINE];
3918 int nb_bt_opts;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003919 int optind;
3920 const char *r, *optarg;
3921 CharDriverState *monitor_hd = NULL;
3922 const char *monitor_device;
3923 const char *serial_devices[MAX_SERIAL_PORTS];
3924 int serial_device_index;
3925 const char *parallel_devices[MAX_PARALLEL_PORTS];
3926 int parallel_device_index;
3927 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
3928 int virtio_console_index;
3929 const char *loadvm = NULL;
3930 QEMUMachine *machine;
3931 const char *cpu_model;
3932 const char *usb_devices[MAX_USB_CMDLINE];
3933 int usb_devices_index;
3934#ifndef _WIN32
3935 int fds[2];
3936#endif
3937 int tb_size;
3938 const char *pid_file = NULL;
3939 const char *incoming = NULL;
3940#ifndef _WIN32
3941 int fd = 0;
3942 struct passwd *pwd = NULL;
3943 const char *chroot_dir = NULL;
3944 const char *run_as = NULL;
3945#endif
3946 CPUState *env;
3947 int show_vnc_port = 0;
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07003948 IniFile* hw_ini = NULL;
David 'Digit' Turner5f824112011-03-01 14:00:26 +01003949 STRALLOC_DEFINE(kernel_params);
3950 STRALLOC_DEFINE(kernel_config);
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003951 int dns_count = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003952
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003953 /* Initialize sockets before anything else, so we can properly report
3954 * initialization failures back to the UI. */
3955#ifdef _WIN32
3956 socket_init();
3957#endif
3958
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003959 init_clocks();
3960
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003961 qemu_cache_utils_init(envp);
3962
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07003963 QLIST_INIT (&vm_change_state_head);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003964#ifndef _WIN32
3965 {
3966 struct sigaction act;
3967 sigfillset(&act.sa_mask);
3968 act.sa_flags = 0;
3969 act.sa_handler = SIG_IGN;
3970 sigaction(SIGPIPE, &act, NULL);
3971 }
3972#else
3973 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
3974 /* Note: cpu_interrupt() is currently not SMP safe, so we force
3975 QEMU to run on a single CPU */
3976 {
3977 HANDLE h;
3978 DWORD mask, smask;
3979 int i;
3980 h = GetCurrentProcess();
3981 if (GetProcessAffinityMask(h, &mask, &smask)) {
3982 for(i = 0; i < 32; i++) {
3983 if (mask & (1 << i))
3984 break;
3985 }
3986 if (i != 32) {
3987 mask = 1 << i;
3988 SetProcessAffinityMask(h, mask);
3989 }
3990 }
3991 }
3992#endif
3993
3994 module_call_init(MODULE_INIT_MACHINE);
3995 machine = find_default_machine();
3996 cpu_model = NULL;
3997 initrd_filename = NULL;
3998 ram_size = 0;
3999 snapshot = 0;
4000 kernel_filename = NULL;
4001 kernel_cmdline = "";
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004002
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004003 cyls = heads = secs = 0;
4004 translation = BIOS_ATA_TRANSLATION_AUTO;
4005 monitor_device = "vc:80Cx24C";
4006
4007 serial_devices[0] = "vc:80Cx24C";
4008 for(i = 1; i < MAX_SERIAL_PORTS; i++)
4009 serial_devices[i] = NULL;
4010 serial_device_index = 0;
4011
4012 parallel_devices[0] = "vc:80Cx24C";
4013 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
4014 parallel_devices[i] = NULL;
4015 parallel_device_index = 0;
4016
4017 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
4018 virtio_consoles[i] = NULL;
4019 virtio_console_index = 0;
4020
4021 for (i = 0; i < MAX_NODES; i++) {
4022 node_mem[i] = 0;
4023 node_cpumask[i] = 0;
4024 }
4025
4026 usb_devices_index = 0;
4027
4028 nb_net_clients = 0;
4029 nb_bt_opts = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004030#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004031 nb_drives = 0;
4032 nb_drives_opt = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004033#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004034 nb_numa_nodes = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004035
4036 nb_nics = 0;
4037
4038 tb_size = 0;
4039 autostart= 1;
4040
4041 register_watchdogs();
4042
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004043 /* Initialize boot properties. */
4044 boot_property_init_service();
4045
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004046 optind = 1;
4047 for(;;) {
4048 if (optind >= argc)
4049 break;
4050 r = argv[optind];
4051 if (r[0] != '-') {
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004052 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004053 } else {
4054 const QEMUOption *popt;
4055
4056 optind++;
4057 /* Treat --foo the same as -foo. */
4058 if (r[1] == '-')
4059 r++;
4060 popt = qemu_options;
4061 for(;;) {
4062 if (!popt->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004063 PANIC("%s: invalid option -- '%s'",
4064 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004065 }
4066 if (!strcmp(popt->name, r + 1))
4067 break;
4068 popt++;
4069 }
4070 if (popt->flags & HAS_ARG) {
4071 if (optind >= argc) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004072 PANIC("%s: option '%s' requires an argument",
4073 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004074 }
4075 optarg = argv[optind++];
4076 } else {
4077 optarg = NULL;
4078 }
4079
4080 switch(popt->index) {
4081 case QEMU_OPTION_M:
4082 machine = find_machine(optarg);
4083 if (!machine) {
4084 QEMUMachine *m;
4085 printf("Supported machines are:\n");
4086 for(m = first_machine; m != NULL; m = m->next) {
4087 printf("%-10s %s%s\n",
4088 m->name, m->desc,
4089 m->is_default ? " (default)" : "");
4090 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004091 if (*optarg != '?') {
4092 PANIC("Invalid machine parameter: %s",
4093 optarg);
4094 } else {
4095 QEMU_EXIT(0);
4096 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004097 }
4098 break;
4099 case QEMU_OPTION_cpu:
4100 /* hw initialization will check this */
4101 if (*optarg == '?') {
4102/* XXX: implement xxx_cpu_list for targets that still miss it */
4103#if defined(cpu_list)
4104 cpu_list(stdout, &fprintf);
4105#endif
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004106 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004107 } else {
4108 cpu_model = optarg;
4109 }
4110 break;
4111 case QEMU_OPTION_initrd:
4112 initrd_filename = optarg;
4113 break;
4114 case QEMU_OPTION_hda:
4115 if (cyls == 0)
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004116 hda_opts = drive_add(optarg, HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004117 else
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004118 hda_opts = drive_add(optarg, HD_ALIAS
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004119 ",cyls=%d,heads=%d,secs=%d%s",
4120 0, cyls, heads, secs,
4121 translation == BIOS_ATA_TRANSLATION_LBA ?
4122 ",trans=lba" :
4123 translation == BIOS_ATA_TRANSLATION_NONE ?
4124 ",trans=none" : "");
4125 break;
4126 case QEMU_OPTION_hdb:
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01004127 hdb_opts = drive_add(optarg, HD_ALIAS, 1);
4128 break;
4129
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004130 case QEMU_OPTION_hdc:
4131 case QEMU_OPTION_hdd:
4132 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
4133 break;
4134 case QEMU_OPTION_drive:
4135 drive_add(NULL, "%s", optarg);
4136 break;
4137 case QEMU_OPTION_mtdblock:
4138 drive_add(optarg, MTD_ALIAS);
4139 break;
4140 case QEMU_OPTION_sd:
4141 drive_add(optarg, SD_ALIAS);
4142 break;
4143 case QEMU_OPTION_pflash:
4144 drive_add(optarg, PFLASH_ALIAS);
4145 break;
4146 case QEMU_OPTION_snapshot:
4147 snapshot = 1;
4148 break;
4149 case QEMU_OPTION_hdachs:
4150 {
4151 const char *p;
4152 p = optarg;
4153 cyls = strtol(p, (char **)&p, 0);
4154 if (cyls < 1 || cyls > 16383)
4155 goto chs_fail;
4156 if (*p != ',')
4157 goto chs_fail;
4158 p++;
4159 heads = strtol(p, (char **)&p, 0);
4160 if (heads < 1 || heads > 16)
4161 goto chs_fail;
4162 if (*p != ',')
4163 goto chs_fail;
4164 p++;
4165 secs = strtol(p, (char **)&p, 0);
4166 if (secs < 1 || secs > 63)
4167 goto chs_fail;
4168 if (*p == ',') {
4169 p++;
4170 if (!strcmp(p, "none"))
4171 translation = BIOS_ATA_TRANSLATION_NONE;
4172 else if (!strcmp(p, "lba"))
4173 translation = BIOS_ATA_TRANSLATION_LBA;
4174 else if (!strcmp(p, "auto"))
4175 translation = BIOS_ATA_TRANSLATION_AUTO;
4176 else
4177 goto chs_fail;
4178 } else if (*p != '\0') {
4179 chs_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004180 PANIC("qemu: invalid physical CHS format");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004181 }
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004182 if (hda_opts != NULL) {
4183 char num[16];
4184 snprintf(num, sizeof(num), "%d", cyls);
4185 qemu_opt_set(hda_opts, "cyls", num);
4186 snprintf(num, sizeof(num), "%d", heads);
4187 qemu_opt_set(hda_opts, "heads", num);
4188 snprintf(num, sizeof(num), "%d", secs);
4189 qemu_opt_set(hda_opts, "secs", num);
4190 if (translation == BIOS_ATA_TRANSLATION_LBA)
4191 qemu_opt_set(hda_opts, "trans", "lba");
4192 if (translation == BIOS_ATA_TRANSLATION_NONE)
4193 qemu_opt_set(hda_opts, "trans", "none");
4194 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004195 }
4196 break;
4197 case QEMU_OPTION_numa:
4198 if (nb_numa_nodes >= MAX_NODES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004199 PANIC("qemu: too many NUMA nodes");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004200 }
4201 numa_add(optarg);
4202 break;
4203 case QEMU_OPTION_nographic:
4204 display_type = DT_NOGRAPHIC;
4205 break;
4206#ifdef CONFIG_CURSES
4207 case QEMU_OPTION_curses:
4208 display_type = DT_CURSES;
4209 break;
4210#endif
4211 case QEMU_OPTION_portrait:
4212 graphic_rotate = 1;
4213 break;
4214 case QEMU_OPTION_kernel:
4215 kernel_filename = optarg;
4216 break;
4217 case QEMU_OPTION_append:
4218 kernel_cmdline = optarg;
4219 break;
4220 case QEMU_OPTION_cdrom:
4221 drive_add(optarg, CDROM_ALIAS);
4222 break;
4223 case QEMU_OPTION_boot:
4224 boot_devices = optarg;
4225 /* We just do some generic consistency checks */
4226 {
4227 /* Could easily be extended to 64 devices if needed */
4228 const char *p;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07004229
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004230 boot_devices_bitmap = 0;
4231 for (p = boot_devices; *p != '\0'; p++) {
4232 /* Allowed boot devices are:
4233 * a b : floppy disk drives
4234 * c ... f : IDE disk drives
4235 * g ... m : machine implementation dependant drives
4236 * n ... p : network devices
4237 * It's up to each machine implementation to check
4238 * if the given boot devices match the actual hardware
4239 * implementation and firmware features.
4240 */
4241 if (*p < 'a' || *p > 'q') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004242 PANIC("Invalid boot device '%c'", *p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004243 }
4244 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004245 PANIC(
4246 "Boot device '%c' was given twice",*p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004247 }
4248 boot_devices_bitmap |= 1 << (*p - 'a');
4249 }
4250 }
4251 break;
4252 case QEMU_OPTION_fda:
4253 case QEMU_OPTION_fdb:
4254 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
4255 break;
4256#ifdef TARGET_I386
4257 case QEMU_OPTION_no_fd_bootchk:
4258 fd_bootchk = 0;
4259 break;
4260#endif
4261 case QEMU_OPTION_net:
4262 if (nb_net_clients >= MAX_NET_CLIENTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004263 PANIC("qemu: too many network clients");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004264 }
4265 net_clients[nb_net_clients] = optarg;
4266 nb_net_clients++;
4267 break;
4268#ifdef CONFIG_SLIRP
4269 case QEMU_OPTION_tftp:
4270 tftp_prefix = optarg;
4271 break;
4272 case QEMU_OPTION_bootp:
4273 bootp_filename = optarg;
4274 break;
4275#if 0 /* ANDROID disabled */
4276#ifndef _WIN32
4277 case QEMU_OPTION_smb:
4278 net_slirp_smb(optarg);
4279 break;
4280#endif
4281#endif /* ANDROID */
4282 case QEMU_OPTION_redir:
4283 net_slirp_redir(NULL, optarg, NULL);
4284 break;
4285#endif
4286 case QEMU_OPTION_bt:
4287 if (nb_bt_opts >= MAX_BT_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004288 PANIC("qemu: too many bluetooth options");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004289 }
4290 bt_opts[nb_bt_opts++] = optarg;
4291 break;
4292#ifdef HAS_AUDIO
4293 case QEMU_OPTION_audio_help:
4294 AUD_help ();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004295 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004296 break;
4297 case QEMU_OPTION_soundhw:
4298 select_soundhw (optarg);
4299 break;
4300#endif
4301 case QEMU_OPTION_h:
4302 qemu_help(0);
4303 break;
4304 case QEMU_OPTION_version:
4305 version();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004306 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004307 break;
4308 case QEMU_OPTION_m: {
4309 uint64_t value;
4310 char *ptr;
4311
4312 value = strtoul(optarg, &ptr, 10);
4313 switch (*ptr) {
4314 case 0: case 'M': case 'm':
4315 value <<= 20;
4316 break;
4317 case 'G': case 'g':
4318 value <<= 30;
4319 break;
4320 default:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004321 PANIC("qemu: invalid ram size: %s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004322 }
4323
4324 /* On 32-bit hosts, QEMU is limited by virtual address space */
4325 if (value > (2047 << 20)
4326#ifndef CONFIG_KQEMU
4327 && HOST_LONG_BITS == 32
4328#endif
4329 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004330 PANIC("qemu: at most 2047 MB RAM can be simulated");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004331 }
4332 if (value != (uint64_t)(ram_addr_t)value) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004333 PANIC("qemu: ram size too large");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004334 }
4335 ram_size = value;
4336 break;
4337 }
4338 case QEMU_OPTION_d:
4339 {
4340 int mask;
4341 const CPULogItem *item;
4342
4343 mask = cpu_str_to_log_mask(optarg);
4344 if (!mask) {
4345 printf("Log items (comma separated):\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004346 for(item = cpu_log_items; item->mask != 0; item++) {
4347 printf("%-10s %s\n", item->name, item->help);
4348 }
4349 PANIC("Invalid parameter -d=%s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004350 }
4351 cpu_set_log(mask);
4352 }
4353 break;
4354 case QEMU_OPTION_s:
4355 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
4356 break;
4357 case QEMU_OPTION_gdb:
4358 gdbstub_dev = optarg;
4359 break;
4360 case QEMU_OPTION_L:
4361 data_dir = optarg;
4362 break;
4363 case QEMU_OPTION_bios:
4364 bios_name = optarg;
4365 break;
4366 case QEMU_OPTION_singlestep:
4367 singlestep = 1;
4368 break;
4369 case QEMU_OPTION_S:
4370#if 0 /* ANDROID */
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004371 PANIC("Sorry, stopped launch is not supported in the Android emulator" );
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004372#endif
4373 autostart = 0;
4374 break;
4375#ifndef _WIN32
4376 case QEMU_OPTION_k:
4377 keyboard_layout = optarg;
4378 break;
4379#endif
4380 case QEMU_OPTION_localtime:
4381 rtc_utc = 0;
4382 break;
4383 case QEMU_OPTION_vga:
4384 select_vgahw (optarg);
4385 break;
4386#if defined(TARGET_PPC) || defined(TARGET_SPARC)
4387 case QEMU_OPTION_g:
4388 {
4389 const char *p;
4390 int w, h, depth;
4391 p = optarg;
4392 w = strtol(p, (char **)&p, 10);
4393 if (w <= 0) {
4394 graphic_error:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004395 PANIC("qemu: invalid resolution or depth");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004396 }
4397 if (*p != 'x')
4398 goto graphic_error;
4399 p++;
4400 h = strtol(p, (char **)&p, 10);
4401 if (h <= 0)
4402 goto graphic_error;
4403 if (*p == 'x') {
4404 p++;
4405 depth = strtol(p, (char **)&p, 10);
4406 if (depth != 8 && depth != 15 && depth != 16 &&
4407 depth != 24 && depth != 32)
4408 goto graphic_error;
4409 } else if (*p == '\0') {
4410 depth = graphic_depth;
4411 } else {
4412 goto graphic_error;
4413 }
4414
4415 graphic_width = w;
4416 graphic_height = h;
4417 graphic_depth = depth;
4418 }
4419 break;
4420#endif
4421 case QEMU_OPTION_echr:
4422 {
4423 char *r;
4424 term_escape_char = strtol(optarg, &r, 0);
4425 if (r == optarg)
4426 printf("Bad argument to echr\n");
4427 break;
4428 }
4429 case QEMU_OPTION_monitor:
4430 monitor_device = optarg;
4431 break;
4432 case QEMU_OPTION_serial:
4433 if (serial_device_index >= MAX_SERIAL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004434 PANIC("qemu: too many serial ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004435 }
4436 serial_devices[serial_device_index] = optarg;
4437 serial_device_index++;
4438 break;
4439 case QEMU_OPTION_watchdog:
4440 i = select_watchdog(optarg);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004441 if (i > 0) {
4442 if (i == 1) {
4443 PANIC("Invalid watchdog parameter: %s",
4444 optarg);
4445 } else {
4446 QEMU_EXIT(0);
4447 }
4448 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004449 break;
4450 case QEMU_OPTION_watchdog_action:
4451 if (select_watchdog_action(optarg) == -1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004452 PANIC("Unknown -watchdog-action parameter");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004453 }
4454 break;
4455 case QEMU_OPTION_virtiocon:
4456 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004457 PANIC("qemu: too many virtio consoles");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004458 }
4459 virtio_consoles[virtio_console_index] = optarg;
4460 virtio_console_index++;
4461 break;
4462 case QEMU_OPTION_parallel:
4463 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004464 PANIC("qemu: too many parallel ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004465 }
4466 parallel_devices[parallel_device_index] = optarg;
4467 parallel_device_index++;
4468 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00004469 case QEMU_OPTION_loadvm:
4470 loadvm = optarg;
4471 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00004472 case QEMU_OPTION_savevm_on_exit:
4473 savevm_on_exit = optarg;
4474 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004475 case QEMU_OPTION_full_screen:
4476 full_screen = 1;
4477 break;
4478#ifdef CONFIG_SDL
4479 case QEMU_OPTION_no_frame:
4480 no_frame = 1;
4481 break;
4482 case QEMU_OPTION_alt_grab:
4483 alt_grab = 1;
4484 break;
4485 case QEMU_OPTION_no_quit:
4486 no_quit = 1;
4487 break;
4488 case QEMU_OPTION_sdl:
4489 display_type = DT_SDL;
4490 break;
4491#endif
4492 case QEMU_OPTION_pidfile:
4493 pid_file = optarg;
4494 break;
4495#ifdef TARGET_I386
4496 case QEMU_OPTION_win2k_hack:
4497 win2k_install_hack = 1;
4498 break;
4499 case QEMU_OPTION_rtc_td_hack:
4500 rtc_td_hack = 1;
4501 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08004502#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004503 case QEMU_OPTION_acpitable:
4504 if(acpi_table_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004505 PANIC("Wrong acpi table provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004506 }
4507 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08004508#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004509 case QEMU_OPTION_smbios:
4510 if(smbios_entry_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004511 PANIC("Wrong smbios provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004512 }
4513 break;
4514#endif
4515#ifdef CONFIG_KQEMU
4516 case QEMU_OPTION_no_kqemu:
4517 kqemu_allowed = 0;
4518 break;
4519 case QEMU_OPTION_kernel_kqemu:
4520 kqemu_allowed = 2;
4521 break;
4522#endif
Jun Nakajima1321c762011-03-04 17:17:45 -08004523#ifdef TARGET_I386
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004524#ifdef CONFIG_KVM
4525 case QEMU_OPTION_enable_kvm:
4526 kvm_allowed = 1;
4527#ifdef CONFIG_KQEMU
4528 kqemu_allowed = 0;
4529#endif
4530 break;
4531#endif
Jun Nakajima1321c762011-03-04 17:17:45 -08004532#endif /* TARGET_I386 */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004533 case QEMU_OPTION_usb:
4534 usb_enabled = 1;
4535 break;
4536 case QEMU_OPTION_usbdevice:
4537 usb_enabled = 1;
4538 if (usb_devices_index >= MAX_USB_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004539 PANIC("Too many USB devices");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004540 }
4541 usb_devices[usb_devices_index] = optarg;
4542 usb_devices_index++;
4543 break;
4544 case QEMU_OPTION_smp:
4545 smp_cpus = atoi(optarg);
4546 if (smp_cpus < 1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004547 PANIC("Invalid number of CPUs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004548 }
4549 break;
4550 case QEMU_OPTION_vnc:
4551 display_type = DT_VNC;
4552 vnc_display = optarg;
4553 break;
4554#ifdef TARGET_I386
4555 case QEMU_OPTION_no_acpi:
4556 acpi_enabled = 0;
4557 break;
4558 case QEMU_OPTION_no_hpet:
4559 no_hpet = 1;
4560 break;
4561 case QEMU_OPTION_no_virtio_balloon:
4562 no_virtio_balloon = 1;
4563 break;
4564#endif
4565 case QEMU_OPTION_no_reboot:
4566 no_reboot = 1;
4567 break;
4568 case QEMU_OPTION_no_shutdown:
4569 no_shutdown = 1;
4570 break;
4571 case QEMU_OPTION_show_cursor:
4572 cursor_hide = 0;
4573 break;
4574 case QEMU_OPTION_uuid:
4575 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004576 PANIC("Fail to parse UUID string. Wrong format.");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004577 }
4578 break;
4579#ifndef _WIN32
4580 case QEMU_OPTION_daemonize:
4581 daemonize = 1;
4582 break;
4583#endif
4584 case QEMU_OPTION_option_rom:
4585 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004586 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004587 }
4588 option_rom[nb_option_roms] = optarg;
4589 nb_option_roms++;
4590 break;
4591#if defined(TARGET_ARM) || defined(TARGET_M68K)
4592 case QEMU_OPTION_semihosting:
4593 semihosting_enabled = 1;
4594 break;
4595#endif
4596 case QEMU_OPTION_name:
4597 qemu_name = optarg;
4598 break;
4599#if defined(TARGET_SPARC) || defined(TARGET_PPC)
4600 case QEMU_OPTION_prom_env:
4601 if (nb_prom_envs >= MAX_PROM_ENVS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004602 PANIC("Too many prom variables");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004603 }
4604 prom_envs[nb_prom_envs] = optarg;
4605 nb_prom_envs++;
4606 break;
4607#endif
4608#ifdef TARGET_ARM
4609 case QEMU_OPTION_old_param:
4610 old_param = 1;
4611 break;
4612#endif
4613 case QEMU_OPTION_clock:
4614 configure_alarms(optarg);
4615 break;
4616 case QEMU_OPTION_startdate:
4617 {
4618 struct tm tm;
David 'Digit' Turnerdc468202010-10-27 02:34:46 +02004619 time_t rtc_start_date = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004620 if (!strcmp(optarg, "now")) {
4621 rtc_date_offset = -1;
4622 } else {
4623 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
4624 &tm.tm_year,
4625 &tm.tm_mon,
4626 &tm.tm_mday,
4627 &tm.tm_hour,
4628 &tm.tm_min,
4629 &tm.tm_sec) == 6) {
4630 /* OK */
4631 } else if (sscanf(optarg, "%d-%d-%d",
4632 &tm.tm_year,
4633 &tm.tm_mon,
4634 &tm.tm_mday) == 3) {
4635 tm.tm_hour = 0;
4636 tm.tm_min = 0;
4637 tm.tm_sec = 0;
4638 } else {
4639 goto date_fail;
4640 }
4641 tm.tm_year -= 1900;
4642 tm.tm_mon--;
4643 rtc_start_date = mktimegm(&tm);
4644 if (rtc_start_date == -1) {
4645 date_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004646 PANIC("Invalid date format. Valid format are:\n"
4647 "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004648 }
4649 rtc_date_offset = time(NULL) - rtc_start_date;
4650 }
4651 }
4652 break;
rich cannings7339b552011-02-16 13:43:44 -08004653
4654 /* -------------------------------------------------------*/
4655 /* User mode network stack restrictions */
4656 case QEMU_OPTION_drop_udp:
4657 slirp_drop_udp();
4658 break;
4659 case QEMU_OPTION_drop_tcp:
4660 slirp_drop_tcp();
4661 break;
4662 case QEMU_OPTION_allow_tcp:
4663 slirp_allow(optarg, IPPROTO_TCP);
4664 break;
4665 case QEMU_OPTION_allow_udp:
4666 slirp_allow(optarg, IPPROTO_UDP);
4667 break;
4668 case QEMU_OPTION_drop_log:
4669 {
4670 FILE* drop_log_fd;
rich canningsd952f282011-03-01 15:40:09 -08004671 drop_log_filename = optarg;
4672 drop_log_fd = fopen(optarg, "w+");
rich cannings7339b552011-02-16 13:43:44 -08004673
4674 if (!drop_log_fd) {
4675 fprintf(stderr, "Cannot open drop log: %s\n", optarg);
4676 exit(1);
4677 }
4678
4679 slirp_drop_log_fd(drop_log_fd);
4680 }
4681 break;
4682
4683 case QEMU_OPTION_dns_log:
4684 {
4685 FILE* dns_log_fd;
rich canningsd952f282011-03-01 15:40:09 -08004686 dns_log_filename = optarg;
4687 dns_log_fd = fopen(optarg, "wb+");
rich cannings7339b552011-02-16 13:43:44 -08004688
4689 if (dns_log_fd == NULL) {
4690 fprintf(stderr, "Cannot open dns log: %s\n", optarg);
4691 exit(1);
4692 }
4693
4694 slirp_dns_log_fd(dns_log_fd);
4695 }
4696 break;
4697
4698
4699 case QEMU_OPTION_max_dns_conns:
4700 {
4701 int max_dns_conns = 0;
4702 if (parse_int(optarg, &max_dns_conns)) {
4703 fprintf(stderr,
4704 "qemu: syntax: -max-dns-conns max_connections\n");
4705 exit(1);
4706 }
4707 if (max_dns_conns <= 0 || max_dns_conns == LONG_MAX) {
4708 fprintf(stderr,
4709 "Invalid arg for max dns connections: %s\n",
4710 optarg);
4711 exit(1);
4712 }
4713 slirp_set_max_dns_conns(max_dns_conns);
4714 }
4715 break;
4716
4717 case QEMU_OPTION_net_forward:
4718 net_slirp_forward(optarg);
4719 break;
4720 case QEMU_OPTION_net_forward_tcp2sink:
4721 {
4722 SockAddress saddr;
4723
4724 if (parse_host_port(&saddr, optarg)) {
4725 fprintf(stderr,
4726 "Invalid ip/port %s for "
4727 "-forward-dropped-tcp2sink. "
4728 "We expect 'sink_ip:sink_port'\n",
4729 optarg);
4730 exit(1);
4731 }
4732 slirp_forward_dropped_tcp2sink(saddr.u.inet.address,
4733 saddr.u.inet.port);
4734 }
4735 break;
4736 /* -------------------------------------------------------*/
4737
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004738 case QEMU_OPTION_tb_size:
4739 tb_size = strtol(optarg, NULL, 0);
4740 if (tb_size < 0)
4741 tb_size = 0;
4742 break;
4743 case QEMU_OPTION_icount:
David Turner6a9ef172010-09-09 22:54:36 +02004744 icount_option = optarg;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004745 break;
4746 case QEMU_OPTION_incoming:
4747 incoming = optarg;
4748 break;
4749#ifndef _WIN32
4750 case QEMU_OPTION_chroot:
4751 chroot_dir = optarg;
4752 break;
4753 case QEMU_OPTION_runas:
4754 run_as = optarg;
4755 break;
4756#endif
4757#ifdef CONFIG_XEN
4758 case QEMU_OPTION_xen_domid:
4759 xen_domid = atoi(optarg);
4760 break;
4761 case QEMU_OPTION_xen_create:
4762 xen_mode = XEN_CREATE;
4763 break;
4764 case QEMU_OPTION_xen_attach:
4765 xen_mode = XEN_ATTACH;
4766 break;
4767#endif
4768
4769
4770 case QEMU_OPTION_mic:
4771 audio_input_source = (char*)optarg;
4772 break;
4773#ifdef CONFIG_TRACE
David 'Digit' Turnera577fca2009-10-15 18:18:09 -07004774 case QEMU_OPTION_trace:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004775 trace_filename = optarg;
4776 tracing = 1;
4777 break;
4778#if 0
4779 case QEMU_OPTION_trace_miss:
4780 trace_cache_miss = 1;
4781 break;
4782 case QEMU_OPTION_trace_addr:
4783 trace_all_addr = 1;
4784 break;
4785#endif
4786 case QEMU_OPTION_tracing:
4787 if (strcmp(optarg, "off") == 0)
4788 tracing = 0;
4789 else if (strcmp(optarg, "on") == 0 && trace_filename)
4790 tracing = 1;
4791 else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004792 PANIC("Unexpected option to -tracing ('%s')",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004793 optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004794 }
4795 break;
4796#if 0
4797 case QEMU_OPTION_dcache_load_miss:
4798 dcache_load_miss_penalty = atoi(optarg);
4799 break;
4800 case QEMU_OPTION_dcache_store_miss:
4801 dcache_store_miss_penalty = atoi(optarg);
4802 break;
4803#endif
4804#endif
4805#ifdef CONFIG_NAND
4806 case QEMU_OPTION_nand:
4807 nand_add_dev(optarg);
4808 break;
4809#endif
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07004810 case QEMU_OPTION_android_ports:
4811 android_op_ports = (char*)optarg;
4812 break;
4813
4814 case QEMU_OPTION_android_port:
4815 android_op_port = (char*)optarg;
4816 break;
4817
4818 case QEMU_OPTION_android_report_console:
4819 android_op_report_console = (char*)optarg;
4820 break;
4821
4822 case QEMU_OPTION_http_proxy:
4823 op_http_proxy = (char*)optarg;
4824 break;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004825
4826 case QEMU_OPTION_charmap:
4827 op_charmap_file = (char*)optarg;
4828 break;
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07004829
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004830 case QEMU_OPTION_android_hw:
4831 android_op_hwini = (char*)optarg;
4832 break;
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07004833
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004834 case QEMU_OPTION_dns_server:
4835 android_op_dns_server = (char*)optarg;
4836 break;
4837
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004838 case QEMU_OPTION_radio:
4839 android_op_radio = (char*)optarg;
4840 break;
4841
4842 case QEMU_OPTION_gps:
4843 android_op_gps = (char*)optarg;
4844 break;
4845
4846 case QEMU_OPTION_audio:
4847 android_op_audio = (char*)optarg;
4848 break;
4849
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004850 case QEMU_OPTION_cpu_delay:
4851 android_op_cpu_delay = (char*)optarg;
4852 break;
4853
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07004854 case QEMU_OPTION_show_kernel:
4855 android_kmsg_init(ANDROID_KMSG_PRINT_MESSAGES);
4856 break;
4857
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004858#ifdef CONFIG_NAND_LIMITS
4859 case QEMU_OPTION_nand_limits:
4860 android_op_nand_limits = (char*)optarg;
4861 break;
4862#endif // CONFIG_NAND_LIMITS
4863
4864 case QEMU_OPTION_netspeed:
4865 android_op_netspeed = (char*)optarg;
4866 break;
4867
4868 case QEMU_OPTION_netdelay:
4869 android_op_netdelay = (char*)optarg;
4870 break;
4871
4872 case QEMU_OPTION_netfast:
4873 android_op_netfast = 1;
4874 break;
4875
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07004876 case QEMU_OPTION_tcpdump:
4877 android_op_tcpdump = (char*)optarg;
4878 break;
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004879
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004880 case QEMU_OPTION_boot_property:
4881 boot_property_parse_option((char*)optarg);
4882 break;
4883
4884 case QEMU_OPTION_lcd_density:
4885 android_op_lcd_density = (char*)optarg;
4886 break;
4887
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004888 case QEMU_OPTION_ui_port:
4889 android_op_ui_port = (char*)optarg;
4890 break;
4891
4892 case QEMU_OPTION_ui_settings:
4893 android_op_ui_settings = (char*)optarg;
4894 break;
4895
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +01004896 case QEMU_OPTION_audio_test_out:
4897 android_audio_test_start_out();
4898 break;
4899
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -08004900 case QEMU_OPTION_android_avdname:
4901 android_op_avd_name = (char*)optarg;
4902 break;
4903
4904 case QEMU_OPTION_timezone:
4905 if (timezone_set((char*)optarg)) {
4906 fprintf(stderr, "emulator: it seems the timezone '%s' is not in zoneinfo format\n",
4907 (char*)optarg);
4908 }
4909 break;
4910
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004911#ifdef CONFIG_MEMCHECK
4912 case QEMU_OPTION_android_memcheck:
4913 android_op_memcheck = (char*)optarg;
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004914 /* This will set ro.kernel.memcheck system property
4915 * to memcheck's tracing flags. */
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004916 stralloc_add_format(kernel_config, " memcheck=%s", android_op_memcheck);
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004917 break;
4918#endif // CONFIG_MEMCHECK
David 'Digit' Turnerbdb6f2d2011-02-23 15:57:25 +01004919
4920 case QEMU_OPTION_snapshot_no_time_update:
4921 android_snapshot_update_time = 0;
4922 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004923 }
4924 }
4925 }
4926
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004927 /* Initialize character map. */
4928 if (android_charmap_setup(op_charmap_file)) {
4929 if (op_charmap_file) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004930 PANIC(
4931 "Unable to initialize character map from file %s.",
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004932 op_charmap_file);
4933 } else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004934 PANIC(
4935 "Unable to initialize default character map.");
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004936 }
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004937 }
4938
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004939 /* If no data_dir is specified then try to find it relative to the
4940 executable path. */
4941 if (!data_dir) {
4942 data_dir = find_datadir(argv[0]);
4943 }
4944 /* If all else fails use the install patch specified when building. */
4945 if (!data_dir) {
4946 data_dir = CONFIG_QEMU_SHAREDIR;
4947 }
4948
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004949 if (!android_op_hwini) {
4950 PANIC("Missing -android-hw <file> option!");
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004951 }
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004952 hw_ini = iniFile_newFromFile(android_op_hwini);
4953 if (hw_ini == NULL) {
4954 PANIC("Could not find %s file.", android_op_hwini);
4955 }
David 'Digit' Turnerb64325d2011-03-22 16:07:01 +01004956
4957 androidHwConfig_init(android_hw, 0);
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004958 androidHwConfig_read(android_hw, hw_ini);
David 'Digit' Turnerb64325d2011-03-22 16:07:01 +01004959
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004960 iniFile_free(hw_ini);
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004961
4962 {
4963 int width = android_hw->hw_lcd_width;
4964 int height = android_hw->hw_lcd_height;
4965 int depth = android_hw->hw_lcd_depth;
4966
4967 /* A bit of sanity checking */
4968 if (width <= 0 || height <= 0 ||
4969 (depth != 16 && depth != 32) ||
4970 (((width|height) & 3) != 0) )
4971 {
4972 PANIC("Invalid display configuration (%d,%d,%d)",
4973 width, height, depth);
4974 }
4975 android_display_width = width;
4976 android_display_height = height;
4977 android_display_bpp = depth;
4978 }
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004979
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004980#ifdef CONFIG_NAND_LIMITS
4981 /* Init nand stuff. */
4982 if (android_op_nand_limits) {
4983 parse_nand_limits(android_op_nand_limits);
4984 }
4985#endif // CONFIG_NAND_LIMITS
4986
David 'Digit' Turner53eb66d2011-03-01 14:58:23 +01004987 /* Initialize AVD name from hardware configuration if needed */
4988 if (!android_op_avd_name) {
4989 if (android_hw->avd_name && *android_hw->avd_name) {
4990 android_op_avd_name = android_hw->avd_name;
4991 VERBOSE_PRINT(init,"AVD Name: %s", android_op_avd_name);
4992 }
4993 }
4994
David 'Digit' Turner40841b22011-03-01 14:04:00 +01004995 /* Initialize system partition image */
4996 {
4997 char tmp[PATH_MAX+32];
4998 const char* sysImage = android_hw->disk_systemPartition_path;
4999 const char* initImage = android_hw->disk_systemPartition_initPath;
5000 uint64_t sysBytes = android_hw->disk_systemPartition_size;
5001
5002 if (sysBytes == 0) {
5003 PANIC("Invalid system partition size: %" PRUd64, sysBytes);
5004 }
5005
5006 snprintf(tmp,sizeof(tmp),"system,size=0x%" PRUx64, sysBytes);
5007
5008 if (sysImage && *sysImage) {
5009 if (filelock_create(sysImage) == NULL) {
5010 fprintf(stderr,"WARNING: System image already in use, changes will not persist!\n");
5011 /* If there is no file= parameters, nand_add_dev will create
5012 * a temporary file to back the partition image. */
5013 } else {
5014 pstrcat(tmp,sizeof(tmp),",file=");
5015 pstrcat(tmp,sizeof(tmp),sysImage);
5016 }
5017 }
5018 if (initImage && *initImage) {
5019 if (!path_exists(initImage)) {
5020 PANIC("Invalid initial system image path: %s", initImage);
5021 }
5022 pstrcat(tmp,sizeof(tmp),",initfile=");
5023 pstrcat(tmp,sizeof(tmp),initImage);
5024 } else {
5025 PANIC("Missing initial system image path!");
5026 }
5027 nand_add_dev(tmp);
5028 }
5029
David 'Digit' Turnerfd59c332011-03-01 00:48:52 +01005030 /* Initialize data partition image */
5031 {
5032 char tmp[PATH_MAX+32];
5033 const char* dataImage = android_hw->disk_dataPartition_path;
5034 const char* initImage = android_hw->disk_dataPartition_initPath;
5035 uint64_t dataBytes = android_hw->disk_dataPartition_size;
5036
5037 if (dataBytes == 0) {
5038 PANIC("Invalid data partition size: %" PRUd64, dataBytes);
5039 }
5040
5041 snprintf(tmp,sizeof(tmp),"userdata,size=0x%" PRUx64, dataBytes);
5042
5043 if (dataImage && *dataImage) {
5044 if (filelock_create(dataImage) == NULL) {
5045 fprintf(stderr, "WARNING: Data partition already in use. Changes will not persist!\n");
5046 /* Note: if there is no file= parameters, nand_add_dev() will
5047 * create a temporary file to back the partition image. */
5048 } else {
5049 /* Create the file if needed */
5050 if (!path_exists(dataImage)) {
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01005051 if (path_empty_file(dataImage) < 0) {
5052 PANIC("Could not create data image file %s: %s", dataImage, strerror(errno));
5053 }
David 'Digit' Turnerfd59c332011-03-01 00:48:52 +01005054 }
5055 pstrcat(tmp, sizeof(tmp), ",file=");
5056 pstrcat(tmp, sizeof(tmp), dataImage);
5057 }
5058 }
5059 if (initImage && *initImage) {
5060 pstrcat(tmp, sizeof(tmp), ",initfile=");
5061 pstrcat(tmp, sizeof(tmp), initImage);
5062 }
5063 nand_add_dev(tmp);
5064 }
5065
David 'Digit' Turner48a3c662011-03-01 14:03:20 +01005066 /* Init SD-Card stuff. For Android, it is always hda */
5067 /* If the -hda option was used, ignore the Android-provided one */
5068 if (hda_opts == NULL) {
5069 const char* sdPath = android_hw->hw_sdCard_path;
5070 if (sdPath && *sdPath) {
5071 if (!path_exists(sdPath)) {
5072 fprintf(stderr, "WARNING: SD Card image is missing: %s\n", sdPath);
5073 } else if (filelock_create(sdPath) == NULL) {
5074 fprintf(stderr, "WARNING: SD Card image already in use: %s\n", sdPath);
5075 } else {
5076 /* Successful locking */
5077 hda_opts = drive_add(sdPath, HD_ALIAS, 0);
5078 }
5079 }
5080 }
5081
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01005082 if (hdb_opts == NULL) {
5083 const char* spath = android_hw->disk_snapStorage_path;
5084 if (spath && *spath) {
5085 if (!path_exists(spath)) {
5086 PANIC("Snapshot storage file does not exist: %s", spath);
5087 }
5088 if (filelock_create(spath) == NULL) {
5089 PANIC("Snapshot storag already in use: %s", spath);
5090 }
5091 hdb_opts = drive_add(spath, HD_ALIAS, 1);
5092 }
5093 }
5094
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07005095 /* Set the VM's max heap size, passed as a boot property */
5096 if (android_hw->vm_heapSize > 0) {
5097 char tmp[64];
5098 snprintf(tmp, sizeof(tmp), "%dm", android_hw->vm_heapSize);
5099 boot_property_add("dalvik.vm.heapsize",tmp);
5100 }
5101
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07005102 /* Initialize net speed and delays stuff. */
5103 if (android_parse_network_speed(android_op_netspeed) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005104 PANIC("invalid -netspeed parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07005105 android_op_netspeed);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07005106 }
5107
5108 if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005109 PANIC("invalid -netdelay parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07005110 android_op_netdelay);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07005111 }
5112
5113 if (android_op_netfast) {
5114 qemu_net_download_speed = 0;
5115 qemu_net_upload_speed = 0;
5116 qemu_net_min_latency = 0;
5117 qemu_net_max_latency = 0;
5118 }
5119
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07005120 /* Initialize LCD density */
David 'Digit' Turner5377c5b2011-02-10 16:52:19 +01005121 if (android_hw->hw_lcd_density) {
5122 long density = android_hw->hw_lcd_density;
5123 if (density <= 0) {
5124 PANIC("Invalid hw.lcd.density value: %ld", density);
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07005125 }
5126 hwLcd_setBootProperty(density);
5127 }
5128
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07005129 /* Initialize TCP dump */
5130 if (android_op_tcpdump) {
5131 if (qemu_tcpdump_start(android_op_tcpdump) < 0) {
5132 fprintf(stdout, "could not start packet capture: %s\n", strerror(errno));
5133 }
5134 }
5135
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005136 /* Initialize modem */
5137 if (android_op_radio) {
5138 CharDriverState* cs = qemu_chr_open("radio", android_op_radio, NULL);
5139 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005140 PANIC("unsupported character device specification: %s\n"
5141 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005142 android_op_radio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005143 }
5144 android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
5145 } else if (android_hw->hw_gsmModem != 0 ) {
5146 if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005147 PANIC("could not initialize qemud 'gsm' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005148 }
5149 }
5150
5151 /* Initialize GPS */
5152 if (android_op_gps) {
5153 CharDriverState* cs = qemu_chr_open("gps", android_op_gps, NULL);
5154 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005155 PANIC("unsupported character device specification: %s\n"
5156 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005157 android_op_gps);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005158 }
5159 android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
5160 } else if (android_hw->hw_gps != 0) {
5161 if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005162 PANIC("could not initialize qemud 'gps' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005163 }
5164 }
5165
5166 /* Initialize audio. */
5167 if (android_op_audio) {
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005168 if ( !audio_check_backend_name( 0, android_op_audio ) ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005169 PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005170 android_op_audio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005171 }
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005172 }
5173
5174 if (android_op_cpu_delay) {
5175 char* end;
5176 long delay = strtol(android_op_cpu_delay, &end, 0);
5177 if (end == NULL || *end || delay < 0 || delay > 1000 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005178 PANIC("option -cpu-delay must be an integer between 0 and 1000" );
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07005179 }
5180 if (delay > 0)
5181 delay = (1000-delay);
5182
5183 qemu_cpu_delay = (int) delay;
5184 }
5185
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005186 if (android_op_dns_server) {
5187 char* x = strchr(android_op_dns_server, ',');
5188 dns_count = 0;
5189 if (x == NULL)
5190 {
5191 if ( add_dns_server( android_op_dns_server ) == 0 )
5192 dns_count = 1;
5193 }
5194 else
5195 {
5196 x = android_op_dns_server;
5197 while (*x) {
5198 char* y = strchr(x, ',');
5199
5200 if (y != NULL) {
5201 *y = 0;
5202 y++;
5203 } else {
5204 y = x + strlen(x);
5205 }
5206
5207 if (y > x && add_dns_server( x ) == 0) {
5208 dns_count += 1;
5209 }
5210 x = y;
5211 }
5212 }
5213 if (dns_count == 0)
5214 fprintf( stdout, "### WARNING: will use system default DNS server\n" );
5215 }
5216
5217 if (dns_count == 0)
5218 dns_count = slirp_get_system_dns_servers();
5219 if (dns_count) {
David 'Digit' Turner5f824112011-03-01 14:00:26 +01005220 stralloc_add_format(kernel_config, " ndns=%d", dns_count);
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005221 }
5222
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07005223#ifdef CONFIG_MEMCHECK
5224 if (android_op_memcheck) {
5225 memcheck_init(android_op_memcheck);
5226 }
5227#endif // CONFIG_MEMCHECK
5228
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01005229 /* Initialize cache partition, if any */
5230 if (android_hw->disk_cachePartition != 0) {
5231 char tmp[PATH_MAX+32];
5232 const char* partPath = android_hw->disk_cachePartition_path;
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01005233 uint64_t partSize = android_hw->disk_cachePartition_size;
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01005234
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01005235 snprintf(tmp,sizeof(tmp),"cache,size=0x%" PRUx64, partSize);
5236
5237 if (partPath && *partPath && strcmp(partPath, "<temp>") != 0) {
5238 if (filelock_create(partPath) == NULL) {
5239 fprintf(stderr, "WARNING: Cache partition already in use. Changes will not persist!\n");
5240 /* Note: if there is no file= parameters, nand_add_dev() will
5241 * create a temporary file to back the partition image. */
5242 } else {
5243 /* Create the file if needed */
5244 if (!path_exists(partPath)) {
5245 if (path_empty_file(partPath) < 0) {
5246 PANIC("Could not create cache image file %s: %s", partPath, strerror(errno));
5247 }
5248 }
5249 pstrcat(tmp, sizeof(tmp), ",file=");
5250 pstrcat(tmp, sizeof(tmp), partPath);
5251 }
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01005252 }
5253 nand_add_dev(tmp);
5254 }
5255
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01005256 /* We always force qemu=1 when running inside QEMU */
5257 stralloc_add_str(kernel_params, " qemu=1");
5258
5259 /* We always initialize the first serial port for the android-kmsg
5260 * character device (used to send kernel messages) */
5261 serial_hds_add_at(0, "android-kmsg");
5262 stralloc_add_str(kernel_params, " console=ttyS0");
5263
5264 /* We always initialize the second serial port for the android-qemud
5265 * character device as well */
5266 serial_hds_add_at(1, "android-qemud");
5267 stralloc_add_str(kernel_params, " android.qemud=ttyS1");
5268
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005269#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
5270 if (kvm_allowed && kqemu_allowed) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005271 PANIC(
5272 "You can not enable both KVM and kqemu at the same time");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005273 }
5274#endif
5275
5276 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
5277 if (smp_cpus > machine->max_cpus) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005278 PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
5279 "supported by machine `%s' (%d)", smp_cpus, machine->name,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005280 machine->max_cpus);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005281 }
5282
5283 if (display_type == DT_NOGRAPHIC) {
5284 if (serial_device_index == 0)
5285 serial_devices[0] = "stdio";
5286 if (parallel_device_index == 0)
5287 parallel_devices[0] = "null";
5288 if (strncmp(monitor_device, "vc", 2) == 0)
5289 monitor_device = "stdio";
5290 }
5291
5292#ifndef _WIN32
5293 if (daemonize) {
5294 pid_t pid;
5295
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005296 if (pipe(fds) == -1) {
5297 PANIC("Unable to aquire pidfile");
5298 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005299
5300 pid = fork();
5301 if (pid > 0) {
5302 uint8_t status;
5303 ssize_t len;
5304
5305 close(fds[1]);
5306
5307 again:
5308 len = read(fds[0], &status, 1);
5309 if (len == -1 && (errno == EINTR))
5310 goto again;
5311
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005312 if (len != 1) {
5313 PANIC("Error when aquiring pidfile");
5314 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005315 else if (status == 1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005316 PANIC("Could not acquire pidfile");
5317 } else {
5318 QEMU_EXIT(0);
5319 }
5320 } else if (pid < 0) {
5321 PANIC("Unable to daemonize");
5322 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005323
5324 setsid();
5325
5326 pid = fork();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005327 if (pid > 0) {
5328 QEMU_EXIT(0);
5329 } else if (pid < 0) {
5330 PANIC("Could not acquire pid file");
5331 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005332
5333 umask(027);
5334
5335 signal(SIGTSTP, SIG_IGN);
5336 signal(SIGTTOU, SIG_IGN);
5337 signal(SIGTTIN, SIG_IGN);
5338 }
5339
5340 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
5341 if (daemonize) {
5342 uint8_t status = 1;
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02005343 int ret;
5344 do {
5345 ret = write(fds[1], &status, 1);
5346 } while (ret < 0 && errno == EINTR);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005347 PANIC("Could not acquire pid file");
5348 } else {
5349 PANIC("Could not acquire pid file");
5350 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005351 }
5352#endif
5353
5354#ifdef CONFIG_KQEMU
5355 if (smp_cpus > 1)
5356 kqemu_allowed = 0;
5357#endif
5358 if (qemu_init_main_loop()) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005359 PANIC("qemu_init_main_loop failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005360 }
David 'Digit' Turner0b019492011-03-01 14:02:42 +01005361
5362 if (kernel_filename == NULL) {
5363 kernel_filename = android_hw->kernel_path;
5364 }
5365 if (initrd_filename == NULL) {
5366 initrd_filename = android_hw->disk_ramdisk_path;
5367 }
5368
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005369 linux_boot = (kernel_filename != NULL);
5370 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
5371
5372 if (!linux_boot && *kernel_cmdline != '\0') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005373 PANIC("-append only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005374 }
5375
5376 if (!linux_boot && initrd_filename != NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005377 PANIC("-initrd only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005378 }
5379
5380 /* boot to floppy or the default cd if no hard disk defined yet */
5381 if (!boot_devices[0]) {
5382 boot_devices = "cad";
5383 }
5384 setvbuf(stdout, NULL, _IOLBF, 0);
5385
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005386 if (init_timer_alarm() < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005387 PANIC("could not initialize alarm timer");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005388 }
David Turner6a9ef172010-09-09 22:54:36 +02005389 configure_icount(icount_option);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005390
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005391 /* init network clients */
5392 if (nb_net_clients == 0) {
5393 /* if no clients, we use a default config */
5394 net_clients[nb_net_clients++] = "nic";
5395#ifdef CONFIG_SLIRP
5396 net_clients[nb_net_clients++] = "user";
5397#endif
5398 }
5399
5400 for(i = 0;i < nb_net_clients; i++) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005401 if (net_client_parse(net_clients[i]) < 0) {
5402 PANIC("Unable to parse net clients");
5403 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005404 }
5405 net_client_check();
5406
5407#ifdef TARGET_I386
5408 /* XXX: this should be moved in the PC machine instantiation code */
5409 if (net_boot != 0) {
5410 int netroms = 0;
5411 for (i = 0; i < nb_nics && i < 4; i++) {
5412 const char *model = nd_table[i].model;
5413 char buf[1024];
5414 char *filename;
5415 if (net_boot & (1 << i)) {
5416 if (model == NULL)
5417 model = "ne2k_pci";
5418 snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
5419 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
5420 if (filename && get_image_size(filename) > 0) {
5421 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005422 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005423 }
5424 option_rom[nb_option_roms] = qemu_strdup(buf);
5425 nb_option_roms++;
5426 netroms++;
5427 }
5428 if (filename) {
5429 qemu_free(filename);
5430 }
5431 }
5432 }
5433 if (netroms == 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005434 PANIC("No valid PXE rom found for network device");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005435 }
5436 }
5437#endif
5438
5439 /* init the bluetooth world */
5440 for (i = 0; i < nb_bt_opts; i++)
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005441 if (bt_parse(bt_opts[i])) {
5442 PANIC("Unable to parse bluetooth options");
5443 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005444
5445 /* init the memory */
David 'Digit' Turner5377c5b2011-02-10 16:52:19 +01005446 if (ram_size == 0) {
5447 ram_size = android_hw->hw_ramSize * 1024LL * 1024;
5448 if (ram_size == 0) {
5449 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
5450 }
5451 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005452
5453#ifdef CONFIG_KQEMU
5454 /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
5455 guest ram allocation. It needs to go away. */
5456 if (kqemu_allowed) {
5457 kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
5458 kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
5459 if (!kqemu_phys_ram_base) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005460 PANIC("Could not allocate physical memory");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005461 }
5462 }
5463#endif
5464
rich canningsd952f282011-03-01 15:40:09 -08005465#ifndef _WIN32
5466 init_qemu_clear_logs_sig();
5467#endif
5468
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005469 /* init the dynamic translator */
5470 cpu_exec_init_all(tb_size * 1024 * 1024);
5471
5472 bdrv_init();
5473
5474 /* we always create the cdrom drive, even if no disk is there */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005475#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005476 if (nb_drives_opt < MAX_DRIVES)
5477 drive_add(NULL, CDROM_ALIAS);
5478
5479 /* we always create at least one floppy */
5480
5481 if (nb_drives_opt < MAX_DRIVES)
5482 drive_add(NULL, FD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005483 /* we always create one sd slot, even if no card is in it */
5484
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005485 if (1) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005486 drive_add(NULL, SD_ALIAS);
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005487 }
5488#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005489
5490 /* open the virtual block devices */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005491 if (snapshot)
5492 qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
5493 if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
5494 exit(1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005495
David Turner6a9ef172010-09-09 22:54:36 +02005496 //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005497 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
5498
5499#ifndef _WIN32
5500 /* must be after terminal init, SDL library changes signal handlers */
5501 sighandler_setup();
5502#endif
5503
5504 /* Maintain compatibility with multiple stdio monitors */
5505 if (!strcmp(monitor_device,"stdio")) {
5506 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
5507 const char *devname = serial_devices[i];
5508 if (devname && !strcmp(devname,"mon:stdio")) {
5509 monitor_device = NULL;
5510 break;
5511 } else if (devname && !strcmp(devname,"stdio")) {
5512 monitor_device = NULL;
5513 serial_devices[i] = "mon:stdio";
5514 break;
5515 }
5516 }
5517 }
5518
5519 if (nb_numa_nodes > 0) {
5520 int i;
5521
5522 if (nb_numa_nodes > smp_cpus) {
5523 nb_numa_nodes = smp_cpus;
5524 }
5525
5526 /* If no memory size if given for any node, assume the default case
5527 * and distribute the available memory equally across all nodes
5528 */
5529 for (i = 0; i < nb_numa_nodes; i++) {
5530 if (node_mem[i] != 0)
5531 break;
5532 }
5533 if (i == nb_numa_nodes) {
5534 uint64_t usedmem = 0;
5535
5536 /* On Linux, the each node's border has to be 8MB aligned,
5537 * the final node gets the rest.
5538 */
5539 for (i = 0; i < nb_numa_nodes - 1; i++) {
5540 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
5541 usedmem += node_mem[i];
5542 }
5543 node_mem[i] = ram_size - usedmem;
5544 }
5545
5546 for (i = 0; i < nb_numa_nodes; i++) {
5547 if (node_cpumask[i] != 0)
5548 break;
5549 }
5550 /* assigning the VCPUs round-robin is easier to implement, guest OSes
5551 * must cope with this anyway, because there are BIOSes out there in
5552 * real machines which also use this scheme.
5553 */
5554 if (i == nb_numa_nodes) {
5555 for (i = 0; i < smp_cpus; i++) {
5556 node_cpumask[i % nb_numa_nodes] |= 1 << i;
5557 }
5558 }
5559 }
5560
5561 if (kvm_enabled()) {
5562 int ret;
5563
5564 ret = kvm_init(smp_cpus);
5565 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005566 PANIC("failed to initialize KVM");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005567 }
5568 }
5569
5570 if (monitor_device) {
5571 monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
5572 if (!monitor_hd) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005573 PANIC("qemu: could not open monitor device '%s'",
5574 monitor_device);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005575 }
5576 }
5577
5578 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01005579 serial_hds_add(serial_devices[i]);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005580 }
5581
5582 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5583 const char *devname = parallel_devices[i];
5584 if (devname && strcmp(devname, "none")) {
5585 char label[32];
5586 snprintf(label, sizeof(label), "parallel%d", i);
5587 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
5588 if (!parallel_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005589 PANIC("qemu: could not open parallel device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005590 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005591 }
5592 }
5593 }
5594
5595 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5596 const char *devname = virtio_consoles[i];
5597 if (devname && strcmp(devname, "none")) {
5598 char label[32];
5599 snprintf(label, sizeof(label), "virtcon%d", i);
5600 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
5601 if (!virtcon_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005602 PANIC("qemu: could not open virtio console '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005603 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005604 }
5605 }
5606 }
5607
5608 module_call_init(MODULE_INIT_DEVICE);
5609
5610
5611#ifdef CONFIG_TRACE
5612 if (trace_filename) {
5613 trace_init(trace_filename);
5614#if 0
5615 // We don't need the dcache code until we can get load and store tracing
5616 // working again.
5617 dcache_init(dcache_size, dcache_ways, dcache_line_size,
5618 dcache_replace_policy, dcache_load_miss_penalty,
5619 dcache_store_miss_penalty);
5620#endif
5621 fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
5622 }
5623#endif
5624
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005625 /* Combine kernel command line passed from the UI with parameters
David 'Digit' Turner5f824112011-03-01 14:00:26 +01005626 * collected during initialization.
5627 *
5628 * The order is the following:
5629 * - parameters from the hw configuration (kernel.parameters)
5630 * - additionnal parameters from options (e.g. -memcheck)
5631 * - the -append parameters.
5632 */
5633 {
5634 const char* kernel_parameters;
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005635
David 'Digit' Turner0b019492011-03-01 14:02:42 +01005636 if (android_hw->kernel_parameters) {
David 'Digit' Turner62c7ae52011-03-08 15:46:53 +01005637 stralloc_add_c(kernel_params, ' ');
David 'Digit' Turner0b019492011-03-01 14:02:42 +01005638 stralloc_add_str(kernel_params, android_hw->kernel_parameters);
5639 }
5640
David 'Digit' Turner5f824112011-03-01 14:00:26 +01005641 /* If not empty, kernel_config always contains a leading space */
5642 stralloc_append(kernel_params, kernel_config);
5643
5644 if (*kernel_cmdline) {
5645 stralloc_add_c(kernel_params, ' ');
5646 stralloc_add_str(kernel_params, kernel_cmdline);
5647 }
5648
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01005649 /* Remove any leading/trailing spaces */
5650 stralloc_strip(kernel_params);
5651
David 'Digit' Turner5f824112011-03-01 14:00:26 +01005652 kernel_parameters = stralloc_cstr(kernel_params);
5653 VERBOSE_PRINT(init, "Kernel parameters: %s", kernel_parameters);
5654
5655 machine->init(ram_size,
5656 boot_devices,
5657 kernel_filename,
5658 kernel_parameters,
5659 initrd_filename,
5660 cpu_model);
5661
5662 stralloc_reset(kernel_params);
5663 stralloc_reset(kernel_config);
5664 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005665
5666
5667 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5668 for (i = 0; i < nb_numa_nodes; i++) {
5669 if (node_cpumask[i] & (1 << env->cpu_index)) {
5670 env->numa_node = i;
5671 }
5672 }
5673 }
5674
5675 current_machine = machine;
5676
5677 /* Set KVM's vcpu state to qemu's initial CPUState. */
5678 if (kvm_enabled()) {
5679 int ret;
5680
5681 ret = kvm_sync_vcpus();
5682 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005683 PANIC("failed to initialize vcpus");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005684 }
5685 }
5686
5687 /* init USB devices */
5688 if (usb_enabled) {
5689 for(i = 0; i < usb_devices_index; i++) {
5690 if (usb_device_add(usb_devices[i], 0) < 0) {
5691 fprintf(stderr, "Warning: could not add USB device %s\n",
5692 usb_devices[i]);
5693 }
5694 }
5695 }
5696
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08005697 /* just use the first displaystate for the moment */
David 'Digit' Turner94702b02011-01-20 02:46:33 +01005698 ds = get_displaystate();
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08005699
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01005700 /* Initialize display from the command line parameters. */
5701 android_display_reset(ds,
5702 android_display_width,
5703 android_display_height,
5704 android_display_bpp);
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07005705
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005706 if (display_type == DT_DEFAULT) {
5707#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
5708 display_type = DT_SDL;
5709#else
5710 display_type = DT_VNC;
5711 vnc_display = "localhost:0,to=99";
5712 show_vnc_port = 1;
5713#endif
5714 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07005715
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005716
5717 switch (display_type) {
5718 case DT_NOGRAPHIC:
5719 break;
5720#if defined(CONFIG_CURSES)
5721 case DT_CURSES:
5722 curses_display_init(ds, full_screen);
5723 break;
5724#endif
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07005725#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005726 case DT_SDL:
5727 sdl_display_init(ds, full_screen, no_frame);
5728 break;
5729#elif defined(CONFIG_COCOA)
5730 case DT_SDL:
5731 cocoa_display_init(ds, full_screen);
5732 break;
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08005733#elif defined(CONFIG_STANDALONE_CORE)
5734 case DT_SDL:
Vladimir Chtchetkinee95660a2010-12-20 08:28:03 -08005735 coredisplay_init(ds);
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08005736 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005737#endif
5738 case DT_VNC:
5739 vnc_display_init(ds);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005740 if (vnc_display_open(ds, vnc_display) < 0) {
5741 PANIC("Unable to initialize VNC display");
5742 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005743
5744 if (show_vnc_port) {
5745 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
5746 }
5747 break;
5748 default:
5749 break;
5750 }
5751 dpy_resize(ds);
5752
5753 dcl = ds->listeners;
5754 while (dcl != NULL) {
5755 if (dcl->dpy_refresh != NULL) {
5756 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5757 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
5758 }
5759 dcl = dcl->next;
5760 }
5761
5762 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
5763 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5764 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5765 }
5766
David 'Digit' Turner94702b02011-01-20 02:46:33 +01005767 text_consoles_set_display(ds);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005768 qemu_chr_initial_reset();
5769
5770 if (monitor_device && monitor_hd)
5771 monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
5772
5773 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5774 const char *devname = serial_devices[i];
5775 if (devname && strcmp(devname, "none")) {
5776 if (strstart(devname, "vc", 0))
5777 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
5778 }
5779 }
5780
5781 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5782 const char *devname = parallel_devices[i];
5783 if (devname && strcmp(devname, "none")) {
5784 if (strstart(devname, "vc", 0))
5785 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
5786 }
5787 }
5788
5789 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5790 const char *devname = virtio_consoles[i];
5791 if (virtcon_hds[i] && devname) {
5792 if (strstart(devname, "vc", 0))
5793 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
5794 }
5795 }
5796
5797 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005798 PANIC("qemu: could not open gdbserver on device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005799 gdbstub_dev);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005800 }
5801
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005802 /* call android-specific setup function */
5803 android_emulation_setup();
5804
Vladimir Chtchetkine57584042011-01-20 16:15:30 -08005805#if !defined(CONFIG_STANDALONE_CORE)
5806 // For the standalone emulator (UI+core in one executable) we need to
5807 // set the window title here.
5808 android_emulator_set_base_port(android_base_port);
5809#endif
5810
Ot ten Thije871da2a2010-09-20 10:29:22 +01005811 if (loadvm)
5812 do_loadvm(cur_mon, loadvm);
5813
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005814 if (incoming) {
5815 autostart = 0; /* fixme how to deal with -daemonize */
5816 qemu_start_incoming_migration(incoming);
5817 }
5818
5819 if (autostart)
5820 vm_start();
5821
5822#ifndef _WIN32
5823 if (daemonize) {
5824 uint8_t status = 0;
5825 ssize_t len;
5826
5827 again1:
5828 len = write(fds[1], &status, 1);
5829 if (len == -1 && (errno == EINTR))
5830 goto again1;
5831
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005832 if (len != 1) {
5833 PANIC("Unable to daemonize");
5834 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005835
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005836 if (chdir("/")) {
5837 perror("not able to chdir to /");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005838 PANIC("not able to chdir to /");
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005839 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005840 TFR(fd = open("/dev/null", O_RDWR));
5841 if (fd == -1)
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005842 PANIC("open(\"/dev/null\") failed: %s", errno_str);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005843 }
5844
5845 if (run_as) {
5846 pwd = getpwnam(run_as);
5847 if (!pwd) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005848 PANIC("User \"%s\" doesn't exist", run_as);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005849 }
5850 }
5851
5852 if (chroot_dir) {
5853 if (chroot(chroot_dir) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005854 PANIC("chroot failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005855 }
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005856 if (chdir("/")) {
5857 perror("not able to chdir to /");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005858 PANIC("not able to chdir to /");
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005859 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005860 }
5861
5862 if (run_as) {
5863 if (setgid(pwd->pw_gid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005864 PANIC("Failed to setgid(%d)", pwd->pw_gid);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005865 }
5866 if (setuid(pwd->pw_uid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005867 PANIC("Failed to setuid(%d)", pwd->pw_uid);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005868 }
5869 if (setuid(0) != -1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005870 PANIC("Dropping privileges failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005871 }
5872 }
5873
5874 if (daemonize) {
5875 dup2(fd, 0);
5876 dup2(fd, 1);
5877 dup2(fd, 2);
5878
5879 close(fd);
5880 }
5881#endif
5882
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005883#ifdef CONFIG_ANDROID
5884 // This will notify the UI that the core is successfuly initialized
5885 android_core_init_completed();
5886#endif // CONFIG_ANDROID
5887
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005888 main_loop();
5889 quit_timers();
5890 net_cleanup();
5891 android_emulation_teardown();
5892 return 0;
5893}
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07005894
5895void
5896android_emulation_teardown(void)
5897{
5898 android_charmap_done();
5899}