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