blob: caef03da187d12847eea018191a5f650eb61f5c5 [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
2 * QEMU System Emulator
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25/* the following is needed on Linux to define ptsname() in stdlib.h */
26#if defined(__linux__)
27#define _GNU_SOURCE 1
28#endif
29
30#include "qemu-common.h"
31#include "hw/hw.h"
32#include "hw/boards.h"
33#include "hw/usb.h"
34#include "hw/pcmcia.h"
35#include "hw/pc.h"
36#include "hw/audiodev.h"
37#include "hw/isa.h"
38#include "hw/baum.h"
39#include "hw/goldfish_nand.h"
40#include "net.h"
41#include "console.h"
42#include "sysemu.h"
43#include "gdbstub.h"
44#include "qemu-timer.h"
45#include "qemu-char.h"
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +010046#include "blockdev.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070047#include "audio/audio.h"
48
49#include "qemu_file.h"
50#include "android/android.h"
51#include "charpipe.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070052#include "modem_driver.h"
53#include "android/gps.h"
54#include "android/hw-qemud.h"
55#include "android/hw-kmsg.h"
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -070056#include "android/charmap.h"
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -070057#include "android/globals.h"
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -070058#include "android/utils/bufprint.h"
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -080059#include "android/display-core.h"
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -080060#include "android/utils/timezone.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070061#include "targphys.h"
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -070062#include "tcpdump.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070063
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -070064#ifdef CONFIG_MEMCHECK
65#include "memcheck/memcheck.h"
66#endif // CONFIG_MEMCHECK
67
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070068#include <unistd.h>
69#include <fcntl.h>
70#include <signal.h>
71#include <time.h>
72#include <errno.h>
73#include <sys/time.h>
74#include <zlib.h>
75
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070076/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070077#include "config-host.h"
78
79#ifndef _WIN32
80#include <libgen.h>
81#include <pwd.h>
82#include <sys/times.h>
83#include <sys/wait.h>
84#include <termios.h>
85#include <sys/mman.h>
86#include <sys/ioctl.h>
87#include <sys/resource.h>
88#include <sys/socket.h>
89#include <netinet/in.h>
90#include <net/if.h>
91#if defined(__NetBSD__)
92#include <net/if_tap.h>
93#endif
94#ifdef __linux__
95#include <linux/if_tun.h>
96#endif
97#include <arpa/inet.h>
98#include <dirent.h>
99#include <netdb.h>
100#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -0700101#ifdef CONFIG_BSD
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700102#include <sys/stat.h>
103#if defined(__FreeBSD__) || defined(__DragonFly__)
104#include <libutil.h>
105#else
106#include <util.h>
107#endif
108#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
109#include <freebsd/stdlib.h>
110#else
111#ifdef __linux__
112#include <pty.h>
113#include <malloc.h>
114#include <linux/rtc.h>
115
116/* For the benefit of older linux systems which don't supply it,
117 we use a local copy of hpet.h. */
118/* #include <linux/hpet.h> */
119#include "hpet.h"
120
121#include <linux/ppdev.h>
122#include <linux/parport.h>
123#endif
124#ifdef __sun__
125#include <sys/stat.h>
126#include <sys/ethernet.h>
127#include <sys/sockio.h>
128#include <netinet/arp.h>
129#include <netinet/in.h>
130#include <netinet/in_systm.h>
131#include <netinet/ip.h>
132#include <netinet/ip_icmp.h> // must come after ip.h
133#include <netinet/udp.h>
134#include <netinet/tcp.h>
135#include <net/if.h>
136#include <syslog.h>
137#include <stropts.h>
138#endif
139#endif
140#endif
141
142#if defined(__OpenBSD__)
143#include <util.h>
144#endif
145
146#if defined(CONFIG_VDE)
147#include <libvdeplug.h>
148#endif
149
150#ifdef _WIN32
151#include <windows.h>
152#include <malloc.h>
153#include <sys/timeb.h>
154#include <mmsystem.h>
155#define getopt_long_only getopt_long
156#define memalign(align, size) malloc(size)
157#endif
158
159
160#ifdef CONFIG_COCOA
161#undef main
162#define main qemu_main
163#endif /* CONFIG_COCOA */
164
165#include "hw/hw.h"
166#include "hw/boards.h"
167#include "hw/usb.h"
168#include "hw/pcmcia.h"
169#include "hw/pc.h"
170#include "hw/audiodev.h"
171#include "hw/isa.h"
172#include "hw/baum.h"
173#include "hw/bt.h"
174#include "hw/watchdog.h"
175#include "hw/smbios.h"
176#include "hw/xen.h"
177#include "bt-host.h"
178#include "net.h"
179#include "monitor.h"
180#include "console.h"
181#include "sysemu.h"
182#include "gdbstub.h"
183#include "qemu-timer.h"
184#include "qemu-char.h"
185#include "cache-utils.h"
186#include "block.h"
187#include "dma.h"
188#include "audio/audio.h"
189#include "migration.h"
190#include "kvm.h"
191#include "balloon.h"
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700192#include "android/hw-lcd.h"
193#include "android/boot-properties.h"
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700194#include "android/core-init-utils.h"
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +0100195#include "android/audio-test.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700196
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -0700197#ifdef CONFIG_STANDALONE_CORE
198/* Verbose value used by the standalone emulator core (without UI) */
199unsigned long android_verbose;
200#endif // CONFIG_STANDALONE_CORE
201
Vladimir Chtchetkine57584042011-01-20 16:15:30 -0800202#if !defined(CONFIG_STANDALONE_CORE)
203/* in android/qemulator.c */
204extern void android_emulator_set_base_port(int port);
205#endif
206
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700207#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700208#undef main
209#define main qemu_main
210#endif
211
212#include "disas.h"
213
214#include "exec-all.h"
215
216#ifdef CONFIG_TRACE
217#include "trace.h"
218#include "dcache.h"
219#endif
220
221#include "qemu_socket.h"
222
223#if defined(CONFIG_SLIRP)
224#include "libslirp.h"
225#endif
226
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700227
228
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700229#define DEFAULT_RAM_SIZE 128
230
231/* Max number of USB devices that can be specified on the commandline. */
232#define MAX_USB_CMDLINE 8
233
234/* Max number of bluetooth switches on the commandline. */
235#define MAX_BT_CMDLINE 10
236
237/* XXX: use a two level table to limit memory usage */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700238
239static const char *data_dir;
240const char *bios_name = NULL;
241static void *ioport_opaque[MAX_IOPORTS];
242static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
243static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100244#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700245/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
246 to store the VM snapshots */
247DriveInfo drives_table[MAX_DRIVES+1];
248int nb_drives;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100249#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700250enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700251DisplayType display_type = DT_DEFAULT;
252const char* keyboard_layout = NULL;
253int64_t ticks_per_sec;
254ram_addr_t ram_size;
255int nb_nics;
256NICInfo nd_table[MAX_NICS];
257int vm_running;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100258int autostart;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700259static int rtc_utc = 1;
260static int rtc_date_offset = -1; /* -1 means no change */
261int cirrus_vga_enabled = 1;
262int std_vga_enabled = 0;
263int vmsvga_enabled = 0;
264int xenfb_enabled = 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700265QEMUClock *rtc_clock;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700266#ifdef TARGET_SPARC
267int graphic_width = 1024;
268int graphic_height = 768;
269int graphic_depth = 8;
270#else
271int graphic_width = 800;
272int graphic_height = 600;
273int graphic_depth = 15;
274#endif
275static int full_screen = 0;
276#ifdef CONFIG_SDL
277static int no_frame = 0;
278#endif
279int no_quit = 0;
280CharDriverState *serial_hds[MAX_SERIAL_PORTS];
281CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
282CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
283#ifdef TARGET_I386
284int win2k_install_hack = 0;
285int rtc_td_hack = 0;
286#endif
287int usb_enabled = 0;
288int singlestep = 0;
289int smp_cpus = 1;
290const char *vnc_display;
291int acpi_enabled = 1;
292int no_hpet = 0;
293int no_virtio_balloon = 0;
294int fd_bootchk = 1;
295int no_reboot = 0;
296int no_shutdown = 0;
297int cursor_hide = 1;
298int graphic_rotate = 0;
299#ifndef _WIN32
300int daemonize = 0;
301#endif
302WatchdogTimerModel *watchdog = NULL;
303int watchdog_action = WDT_RESET;
304const char *option_rom[MAX_OPTION_ROMS];
305int nb_option_roms;
306int semihosting_enabled = 0;
307#ifdef TARGET_ARM
308int old_param = 0;
309#endif
310const char *qemu_name;
311int alt_grab = 0;
312#if defined(TARGET_SPARC) || defined(TARGET_PPC)
313unsigned int nb_prom_envs = 0;
314const char *prom_envs[MAX_PROM_ENVS];
315#endif
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100316#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700317int nb_drives_opt;
318struct drive_opt drives_opt[MAX_DRIVES];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100319#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700320int nb_numa_nodes;
321uint64_t node_mem[MAX_NODES];
322uint64_t node_cpumask[MAX_NODES];
323
324static CPUState *cur_cpu;
325static CPUState *next_cpu;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700326static QEMUTimer *nographic_timer;
327
328uint8_t qemu_uuid[16];
329
330
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700331int qemu_cpu_delay;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700332extern char* audio_input_source;
333
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700334extern char* android_op_ports;
335extern char* android_op_port;
336extern char* android_op_report_console;
337extern char* op_http_proxy;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700338// Path to the file containing specific key character map.
339char* op_charmap_file = NULL;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700340
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -0700341/* Framebuffer dimensions, passed with -android-gui option. */
342char* android_op_gui = NULL;
343
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -0700344/* Path to hardware initialization file passed with -android-hw option. */
345char* android_op_hwini = NULL;
346
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -0700347/* Memory checker options. */
348char* android_op_memcheck = NULL;
349
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -0700350/* -dns-server option value. */
351char* android_op_dns_server = NULL;
352
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -0700353/* -radio option value. */
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700354char* android_op_radio = NULL;
355
356/* -gps option value. */
357char* android_op_gps = NULL;
358
359/* -audio option value. */
360char* android_op_audio = NULL;
361
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700362/* -cpu-delay option value. */
363char* android_op_cpu_delay = NULL;
364
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -0700365#ifdef CONFIG_NAND_LIMITS
366/* -nand-limits option value. */
367char* android_op_nand_limits = NULL;
368#endif // CONFIG_NAND_LIMITS
369
370/* -netspeed option value. */
371char* android_op_netspeed = NULL;
372
373/* -netdelay option value. */
374char* android_op_netdelay = NULL;
375
376/* -netfast option value. */
377int android_op_netfast = 0;
378
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -0700379/* -tcpdump option value. */
380char* android_op_tcpdump = NULL;
381
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700382/* -lcd-density option value. */
383char* android_op_lcd_density = NULL;
384
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700385/* -ui-port option value. This port will be used to report the core
386 * initialization completion.
387 */
388char* android_op_ui_port = NULL;
389
390/* -ui-settings option value. This value will be passed to the UI when new UI
391 * process is attaching to the core.
392 */
393char* android_op_ui_settings = NULL;
394
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -0800395/* -android-avdname option value. */
396char* android_op_avd_name = "unknown";
397
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -0700398extern int android_display_width;
399extern int android_display_height;
400extern int android_display_bpp;
401
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700402extern void dprint( const char* format, ... );
403
Tim Baverstock24204cc2010-11-25 11:37:43 +0000404#if CONFIG_ANDROID_SNAPSHOTS
405const char* savevm_on_exit = NULL;
406#endif
407
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700408#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
409
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700410/* Reports the core initialization failure to the error stdout and to the UI
411 * socket before exiting the application.
412 * Parameters that are passed to this macro are used to format the error
413 * mesage using sprintf routine.
414 */
415#ifdef CONFIG_ANDROID
416#define PANIC(...) android_core_init_failure(__VA_ARGS__)
417#else
418#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
419 exit(1); \
420 } while (0)
421#endif // CONFIG_ANDROID
422
423/* Exits the core during initialization. */
424#ifdef CONFIG_ANDROID
425#define QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
426#else
427#define QEMU_EXIT(exit_code) exit(exit_code)
428#endif // CONFIG_ANDROID
429
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700430/***********************************************************/
431/* x86 ISA bus support */
432
433target_phys_addr_t isa_mem_base = 0;
434PicState2 *isa_pic;
435
436static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
437static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
438
439static uint32_t ioport_read(int index, uint32_t address)
440{
441 static IOPortReadFunc *default_func[3] = {
442 default_ioport_readb,
443 default_ioport_readw,
444 default_ioport_readl
445 };
446 IOPortReadFunc *func = ioport_read_table[index][address];
447 if (!func)
448 func = default_func[index];
449 return func(ioport_opaque[address], address);
450}
451
452static void ioport_write(int index, uint32_t address, uint32_t data)
453{
454 static IOPortWriteFunc *default_func[3] = {
455 default_ioport_writeb,
456 default_ioport_writew,
457 default_ioport_writel
458 };
459 IOPortWriteFunc *func = ioport_write_table[index][address];
460 if (!func)
461 func = default_func[index];
462 func(ioport_opaque[address], address, data);
463}
464
465static uint32_t default_ioport_readb(void *opaque, uint32_t address)
466{
467#ifdef DEBUG_UNUSED_IOPORT
468 fprintf(stderr, "unused inb: port=0x%04x\n", address);
469#endif
470 return 0xff;
471}
472
473static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
474{
475#ifdef DEBUG_UNUSED_IOPORT
476 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
477#endif
478}
479
480/* default is to make two byte accesses */
481static uint32_t default_ioport_readw(void *opaque, uint32_t address)
482{
483 uint32_t data;
484 data = ioport_read(0, address);
485 address = (address + 1) & (MAX_IOPORTS - 1);
486 data |= ioport_read(0, address) << 8;
487 return data;
488}
489
490static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
491{
492 ioport_write(0, address, data & 0xff);
493 address = (address + 1) & (MAX_IOPORTS - 1);
494 ioport_write(0, address, (data >> 8) & 0xff);
495}
496
497static uint32_t default_ioport_readl(void *opaque, uint32_t address)
498{
499#ifdef DEBUG_UNUSED_IOPORT
500 fprintf(stderr, "unused inl: port=0x%04x\n", address);
501#endif
502 return 0xffffffff;
503}
504
505static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
506{
507#ifdef DEBUG_UNUSED_IOPORT
508 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
509#endif
510}
511
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -0700512/* Parses -android-gui command line option, extracting width, height and bits
513 * per pixel parameters for the GUI console used in this session of the
514 * emulator. -android-gui option contains exactly three comma-separated positive
515 * integer numbers in strict order: width goes first, width goes next, and bits
516 * per pixel goes third. This routine verifies that format and return 0 if all
517 * three numbers were extracted, or -1 if string format was incorrect for that
518 * option. Note that this routine does not verify that extracted values are
519 * correct!
520 */
521static int
522parse_androig_gui_option(const char* op, int* width, int* height, int* bpp)
523{
524 char val[128];
525
526 if (get_param_value(val, 128, "width", op)) {
527 *width = strtol(val, NULL, 0);
528 } else {
529 fprintf(stderr, "option -android-gui is missing width parameter\n");
530 return -1;
531 }
532 if (get_param_value(val, 128, "height", op)) {
533 *height = strtol(val, NULL, 0);
534 } else {
535 fprintf(stderr, "option -android-gui is missing height parameter\n");
536 return -1;
537 }
538 if (get_param_value(val, 128, "bpp", op)) {
539 *bpp = strtol(val, NULL, 0);
540 } else {
541 fprintf(stderr, "option -android-gui is missing bpp parameter\n");
542 return -1;
543 }
544
545 return 0;
546}
547
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700548/***********************************************************/
549void hw_error(const char *fmt, ...)
550{
551 va_list ap;
552 CPUState *env;
553
554 va_start(ap, fmt);
555 fprintf(stderr, "qemu: hardware error: ");
556 vfprintf(stderr, fmt, ap);
557 fprintf(stderr, "\n");
558 for(env = first_cpu; env != NULL; env = env->next_cpu) {
559 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
560#ifdef TARGET_I386
561 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
562#else
563 cpu_dump_state(env, stderr, fprintf, 0);
564#endif
565 }
566 va_end(ap);
567 abort();
568}
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +0200569
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700570/***************/
571/* ballooning */
572
573static QEMUBalloonEvent *qemu_balloon_event;
574void *qemu_balloon_event_opaque;
575
576void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
577{
578 qemu_balloon_event = func;
579 qemu_balloon_event_opaque = opaque;
580}
581
582void qemu_balloon(ram_addr_t target)
583{
584 if (qemu_balloon_event)
585 qemu_balloon_event(qemu_balloon_event_opaque, target);
586}
587
588ram_addr_t qemu_balloon_status(void)
589{
590 if (qemu_balloon_event)
591 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
592 return 0;
593}
594
595/***********************************************************/
David Turner025c32f2010-09-10 14:52:42 +0200596/* real time host monotonic timer */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700597
598/* compute with 96 bit intermediate result: (a*b)/c */
599uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
600{
601 union {
602 uint64_t ll;
603 struct {
David 'Digit' Turner20894ae2010-05-10 17:07:36 -0700604#ifdef HOST_WORDS_BIGENDIAN
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700605 uint32_t high, low;
606#else
607 uint32_t low, high;
608#endif
609 } l;
610 } u, res;
611 uint64_t rl, rh;
612
613 u.ll = a;
614 rl = (uint64_t)u.l.low * (uint64_t)b;
615 rh = (uint64_t)u.l.high * (uint64_t)b;
616 rh += (rl >> 32);
617 res.l.high = rh / c;
618 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
619 return res.ll;
620}
621
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700622/***********************************************************/
623/* host time/date access */
624void qemu_get_timedate(struct tm *tm, int offset)
625{
626 time_t ti;
627 struct tm *ret;
628
629 time(&ti);
630 ti += offset;
631 if (rtc_date_offset == -1) {
632 if (rtc_utc)
633 ret = gmtime(&ti);
634 else
635 ret = localtime(&ti);
636 } else {
637 ti -= rtc_date_offset;
638 ret = gmtime(&ti);
639 }
640
641 memcpy(tm, ret, sizeof(struct tm));
642}
643
644int qemu_timedate_diff(struct tm *tm)
645{
646 time_t seconds;
647
648 if (rtc_date_offset == -1)
649 if (rtc_utc)
650 seconds = mktimegm(tm);
651 else
652 seconds = mktime(tm);
653 else
654 seconds = mktimegm(tm) + rtc_date_offset;
655
656 return seconds - time(NULL);
657}
658
659
660#ifdef CONFIG_TRACE
661static int tbflush_requested;
662static int exit_requested;
663
664void start_tracing()
665{
666 if (trace_filename == NULL)
667 return;
668 if (!tracing) {
669 fprintf(stderr,"-- start tracing --\n");
670 start_time = Now();
671 }
672 tracing = 1;
673 tbflush_requested = 1;
674 qemu_notify_event();
675}
676
677void stop_tracing()
678{
679 if (trace_filename == NULL)
680 return;
681 if (tracing) {
682 end_time = Now();
683 elapsed_usecs += end_time - start_time;
684 fprintf(stderr,"-- stop tracing --\n");
685 }
686 tracing = 0;
687 tbflush_requested = 1;
688 qemu_notify_event();
689}
690
691#ifndef _WIN32
692/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
693 * SIGUSR1 turns tracing on. SIGUSR2 turns tracing off.
694 */
695void sigusr_handler(int sig)
696{
697 if (sig == SIGUSR1)
698 start_tracing();
699 else
700 stop_tracing();
701}
702#endif
703
704/* This is the handler to catch control-C so that we can exit cleanly.
705 * This is needed when tracing to flush the buffers to disk.
706 */
707void sigint_handler(int sig)
708{
709 exit_requested = 1;
710 qemu_notify_event();
711}
712#endif /* CONFIG_TRACE */
713
714
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700715/***********************************************************/
716/* Bluetooth support */
717static int nb_hcis;
718static int cur_hci;
719static struct HCIInfo *hci_table[MAX_NICS];
720
721static struct bt_vlan_s {
722 struct bt_scatternet_s net;
723 int id;
724 struct bt_vlan_s *next;
725} *first_bt_vlan;
726
727/* find or alloc a new bluetooth "VLAN" */
728static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
729{
730 struct bt_vlan_s **pvlan, *vlan;
731 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
732 if (vlan->id == id)
733 return &vlan->net;
734 }
735 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
736 vlan->id = id;
737 pvlan = &first_bt_vlan;
738 while (*pvlan != NULL)
739 pvlan = &(*pvlan)->next;
740 *pvlan = vlan;
741 return &vlan->net;
742}
743
744static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
745{
746}
747
748static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
749{
750 return -ENOTSUP;
751}
752
753static struct HCIInfo null_hci = {
754 .cmd_send = null_hci_send,
755 .sco_send = null_hci_send,
756 .acl_send = null_hci_send,
757 .bdaddr_set = null_hci_addr_set,
758};
759
760struct HCIInfo *qemu_next_hci(void)
761{
762 if (cur_hci == nb_hcis)
763 return &null_hci;
764
765 return hci_table[cur_hci++];
766}
767
768static struct HCIInfo *hci_init(const char *str)
769{
770 char *endp;
771 struct bt_scatternet_s *vlan = 0;
772
773 if (!strcmp(str, "null"))
774 /* null */
775 return &null_hci;
776 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
777 /* host[:hciN] */
778 return bt_host_hci(str[4] ? str + 5 : "hci0");
779 else if (!strncmp(str, "hci", 3)) {
780 /* hci[,vlan=n] */
781 if (str[3]) {
782 if (!strncmp(str + 3, ",vlan=", 6)) {
783 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
784 if (*endp)
785 vlan = 0;
786 }
787 } else
788 vlan = qemu_find_bt_vlan(0);
789 if (vlan)
790 return bt_new_hci(vlan);
791 }
792
793 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
794
795 return 0;
796}
797
798static int bt_hci_parse(const char *str)
799{
800 struct HCIInfo *hci;
801 bdaddr_t bdaddr;
802
803 if (nb_hcis >= MAX_NICS) {
804 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
805 return -1;
806 }
807
808 hci = hci_init(str);
809 if (!hci)
810 return -1;
811
812 bdaddr.b[0] = 0x52;
813 bdaddr.b[1] = 0x54;
814 bdaddr.b[2] = 0x00;
815 bdaddr.b[3] = 0x12;
816 bdaddr.b[4] = 0x34;
817 bdaddr.b[5] = 0x56 + nb_hcis;
818 hci->bdaddr_set(hci, bdaddr.b);
819
820 hci_table[nb_hcis++] = hci;
821
822 return 0;
823}
824
825static void bt_vhci_add(int vlan_id)
826{
827 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
828
829 if (!vlan->slave)
830 fprintf(stderr, "qemu: warning: adding a VHCI to "
831 "an empty scatternet %i\n", vlan_id);
832
833 bt_vhci_init(bt_new_hci(vlan));
834}
835
836static struct bt_device_s *bt_device_add(const char *opt)
837{
838 struct bt_scatternet_s *vlan;
839 int vlan_id = 0;
840 char *endp = strstr(opt, ",vlan=");
841 int len = (endp ? endp - opt : strlen(opt)) + 1;
842 char devname[10];
843
844 pstrcpy(devname, MIN(sizeof(devname), len), opt);
845
846 if (endp) {
847 vlan_id = strtol(endp + 6, &endp, 0);
848 if (*endp) {
849 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
850 return 0;
851 }
852 }
853
854 vlan = qemu_find_bt_vlan(vlan_id);
855
856 if (!vlan->slave)
857 fprintf(stderr, "qemu: warning: adding a slave device to "
858 "an empty scatternet %i\n", vlan_id);
859
860 if (!strcmp(devname, "keyboard"))
861 return bt_keyboard_init(vlan);
862
863 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
864 return 0;
865}
866
867static int bt_parse(const char *opt)
868{
869 const char *endp, *p;
870 int vlan;
871
872 if (strstart(opt, "hci", &endp)) {
873 if (!*endp || *endp == ',') {
874 if (*endp)
875 if (!strstart(endp, ",vlan=", 0))
876 opt = endp + 1;
877
878 return bt_hci_parse(opt);
879 }
880 } else if (strstart(opt, "vhci", &endp)) {
881 if (!*endp || *endp == ',') {
882 if (*endp) {
883 if (strstart(endp, ",vlan=", &p)) {
884 vlan = strtol(p, (char **) &endp, 0);
885 if (*endp) {
886 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
887 return 1;
888 }
889 } else {
890 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
891 return 1;
892 }
893 } else
894 vlan = 0;
895
896 bt_vhci_add(vlan);
897 return 0;
898 }
899 } else if (strstart(opt, "device:", &endp))
900 return !bt_device_add(endp);
901
902 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
903 return 1;
904}
905
906/***********************************************************/
907/* QEMU Block devices */
908
909#define HD_ALIAS "index=%d,media=disk"
910#define CDROM_ALIAS "index=2,media=cdrom"
911#define FD_ALIAS "index=%d,if=floppy"
912#define PFLASH_ALIAS "if=pflash"
913#define MTD_ALIAS "if=mtd"
914#define SD_ALIAS "index=0,if=sd"
915
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100916static int drive_init_func(QemuOpts *opts, void *opaque)
917{
918 int *use_scsi = opaque;
919 int fatal_error = 0;
920
921 if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
922 if (fatal_error)
923 return 1;
924 }
925 return 0;
926}
927
928static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
929{
930 if (NULL == qemu_opt_get(opts, "snapshot")) {
931 qemu_opt_set(opts, "snapshot", "on");
932 }
933 return 0;
934}
935
936#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700937static int drive_opt_get_free_idx(void)
938{
939 int index;
940
941 for (index = 0; index < MAX_DRIVES; index++)
942 if (!drives_opt[index].used) {
943 drives_opt[index].used = 1;
944 return index;
945 }
946
947 return -1;
948}
949
950static int drive_get_free_idx(void)
951{
952 int index;
953
954 for (index = 0; index < MAX_DRIVES; index++)
955 if (!drives_table[index].used) {
956 drives_table[index].used = 1;
957 return index;
958 }
959
960 return -1;
961}
962
963int drive_add(const char *file, const char *fmt, ...)
964{
965 va_list ap;
966 int index = drive_opt_get_free_idx();
967
968 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
969 fprintf(stderr, "qemu: too many drives\n");
970 return -1;
971 }
972
973 drives_opt[index].file = file;
974 va_start(ap, fmt);
975 vsnprintf(drives_opt[index].opt,
976 sizeof(drives_opt[0].opt), fmt, ap);
977 va_end(ap);
David 'Digit' Turner92568952010-04-15 15:04:16 -0700978
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700979 nb_drives_opt++;
980 return index;
981}
982
983void drive_remove(int index)
984{
985 drives_opt[index].used = 0;
986 nb_drives_opt--;
987}
988
989int drive_get_index(BlockInterfaceType type, int bus, int unit)
990{
991 int index;
992
993 /* seek interface, bus and unit */
994
995 for (index = 0; index < MAX_DRIVES; index++)
996 if (drives_table[index].type == type &&
997 drives_table[index].bus == bus &&
998 drives_table[index].unit == unit &&
999 drives_table[index].used)
1000 return index;
1001
1002 return -1;
1003}
1004
1005int drive_get_max_bus(BlockInterfaceType type)
1006{
1007 int max_bus;
1008 int index;
1009
1010 max_bus = -1;
1011 for (index = 0; index < nb_drives; index++) {
1012 if(drives_table[index].type == type &&
1013 drives_table[index].bus > max_bus)
1014 max_bus = drives_table[index].bus;
1015 }
1016 return max_bus;
1017}
1018
1019const char *drive_get_serial(BlockDriverState *bdrv)
1020{
1021 int index;
1022
1023 for (index = 0; index < nb_drives; index++)
1024 if (drives_table[index].bdrv == bdrv)
1025 return drives_table[index].serial;
1026
1027 return "\0";
1028}
1029
1030BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
1031{
1032 int index;
1033
1034 for (index = 0; index < nb_drives; index++)
1035 if (drives_table[index].bdrv == bdrv)
1036 return drives_table[index].onerror;
1037
1038 return BLOCK_ERR_STOP_ENOSPC;
1039}
1040
1041static void bdrv_format_print(void *opaque, const char *name)
1042{
1043 fprintf(stderr, " %s", name);
1044}
1045
1046void drive_uninit(BlockDriverState *bdrv)
1047{
1048 int i;
1049
1050 for (i = 0; i < MAX_DRIVES; i++)
1051 if (drives_table[i].bdrv == bdrv) {
1052 drives_table[i].bdrv = NULL;
1053 drives_table[i].used = 0;
1054 drive_remove(drives_table[i].drive_opt_idx);
1055 nb_drives--;
1056 break;
1057 }
1058}
1059
1060int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
1061{
1062 char buf[128];
1063 char file[1024];
1064 char devname[128];
1065 char serial[21];
1066 const char *mediastr = "";
1067 BlockInterfaceType type;
1068 enum { MEDIA_DISK, MEDIA_CDROM } media;
1069 int bus_id, unit_id;
1070 int cyls, heads, secs, translation;
1071 BlockDriverState *bdrv;
1072 BlockDriver *drv = NULL;
1073 QEMUMachine *machine = opaque;
1074 int max_devs;
1075 int index;
1076 int cache;
1077 int bdrv_flags, onerror;
1078 int drives_table_idx;
1079 char *str = arg->opt;
1080 static const char * const params[] = { "bus", "unit", "if", "index",
1081 "cyls", "heads", "secs", "trans",
1082 "media", "snapshot", "file",
1083 "cache", "format", "serial", "werror",
1084 NULL };
1085
1086 if (check_params(buf, sizeof(buf), params, str) < 0) {
1087 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
1088 buf, str);
1089 return -1;
1090 }
1091
1092 file[0] = 0;
1093 cyls = heads = secs = 0;
1094 bus_id = 0;
1095 unit_id = -1;
1096 translation = BIOS_ATA_TRANSLATION_AUTO;
1097 index = -1;
1098 cache = 3;
1099
1100 if (machine->use_scsi) {
1101 type = IF_SCSI;
1102 max_devs = MAX_SCSI_DEVS;
1103 pstrcpy(devname, sizeof(devname), "scsi");
1104 } else {
1105 type = IF_IDE;
1106 max_devs = MAX_IDE_DEVS;
1107 pstrcpy(devname, sizeof(devname), "ide");
1108 }
1109 media = MEDIA_DISK;
1110
1111 /* extract parameters */
1112
1113 if (get_param_value(buf, sizeof(buf), "bus", str)) {
1114 bus_id = strtol(buf, NULL, 0);
1115 if (bus_id < 0) {
1116 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
1117 return -1;
1118 }
1119 }
1120
1121 if (get_param_value(buf, sizeof(buf), "unit", str)) {
1122 unit_id = strtol(buf, NULL, 0);
1123 if (unit_id < 0) {
1124 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
1125 return -1;
1126 }
1127 }
1128
1129 if (get_param_value(buf, sizeof(buf), "if", str)) {
1130 pstrcpy(devname, sizeof(devname), buf);
1131 if (!strcmp(buf, "ide")) {
1132 type = IF_IDE;
1133 max_devs = MAX_IDE_DEVS;
1134 } else if (!strcmp(buf, "scsi")) {
1135 type = IF_SCSI;
1136 max_devs = MAX_SCSI_DEVS;
1137 } else if (!strcmp(buf, "floppy")) {
1138 type = IF_FLOPPY;
1139 max_devs = 0;
1140 } else if (!strcmp(buf, "pflash")) {
1141 type = IF_PFLASH;
1142 max_devs = 0;
1143 } else if (!strcmp(buf, "mtd")) {
1144 type = IF_MTD;
1145 max_devs = 0;
1146 } else if (!strcmp(buf, "sd")) {
1147 type = IF_SD;
1148 max_devs = 0;
1149 } else if (!strcmp(buf, "virtio")) {
1150 type = IF_VIRTIO;
1151 max_devs = 0;
1152 } else if (!strcmp(buf, "xen")) {
1153 type = IF_XEN;
1154 max_devs = 0;
1155 } else {
1156 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
1157 return -1;
1158 }
1159 }
1160
1161 if (get_param_value(buf, sizeof(buf), "index", str)) {
1162 index = strtol(buf, NULL, 0);
1163 if (index < 0) {
1164 fprintf(stderr, "qemu: '%s' invalid index\n", str);
1165 return -1;
1166 }
1167 }
1168
1169 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
1170 cyls = strtol(buf, NULL, 0);
1171 }
1172
1173 if (get_param_value(buf, sizeof(buf), "heads", str)) {
1174 heads = strtol(buf, NULL, 0);
1175 }
1176
1177 if (get_param_value(buf, sizeof(buf), "secs", str)) {
1178 secs = strtol(buf, NULL, 0);
1179 }
1180
1181 if (cyls || heads || secs) {
1182 if (cyls < 1 || cyls > 16383) {
1183 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
1184 return -1;
1185 }
1186 if (heads < 1 || heads > 16) {
1187 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
1188 return -1;
1189 }
1190 if (secs < 1 || secs > 63) {
1191 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
1192 return -1;
1193 }
1194 }
1195
1196 if (get_param_value(buf, sizeof(buf), "trans", str)) {
1197 if (!cyls) {
1198 fprintf(stderr,
1199 "qemu: '%s' trans must be used with cyls,heads and secs\n",
1200 str);
1201 return -1;
1202 }
1203 if (!strcmp(buf, "none"))
1204 translation = BIOS_ATA_TRANSLATION_NONE;
1205 else if (!strcmp(buf, "lba"))
1206 translation = BIOS_ATA_TRANSLATION_LBA;
1207 else if (!strcmp(buf, "auto"))
1208 translation = BIOS_ATA_TRANSLATION_AUTO;
1209 else {
1210 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
1211 return -1;
1212 }
1213 }
1214
1215 if (get_param_value(buf, sizeof(buf), "media", str)) {
1216 if (!strcmp(buf, "disk")) {
1217 media = MEDIA_DISK;
1218 } else if (!strcmp(buf, "cdrom")) {
1219 if (cyls || secs || heads) {
1220 fprintf(stderr,
1221 "qemu: '%s' invalid physical CHS format\n", str);
1222 return -1;
1223 }
1224 media = MEDIA_CDROM;
1225 } else {
1226 fprintf(stderr, "qemu: '%s' invalid media\n", str);
1227 return -1;
1228 }
1229 }
1230
1231 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
1232 if (!strcmp(buf, "on"))
1233 snapshot = 1;
1234 else if (!strcmp(buf, "off"))
1235 snapshot = 0;
1236 else {
1237 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
1238 return -1;
1239 }
1240 }
1241
1242 if (get_param_value(buf, sizeof(buf), "cache", str)) {
1243 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
1244 cache = 0;
1245 else if (!strcmp(buf, "writethrough"))
1246 cache = 1;
1247 else if (!strcmp(buf, "writeback"))
1248 cache = 2;
1249 else {
1250 fprintf(stderr, "qemu: invalid cache option\n");
1251 return -1;
1252 }
1253 }
1254
1255 if (get_param_value(buf, sizeof(buf), "format", str)) {
1256 if (strcmp(buf, "?") == 0) {
1257 fprintf(stderr, "qemu: Supported formats:");
1258 bdrv_iterate_format(bdrv_format_print, NULL);
1259 fprintf(stderr, "\n");
1260 return -1;
1261 }
1262 drv = bdrv_find_format(buf);
1263 if (!drv) {
1264 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
1265 return -1;
1266 }
1267 }
1268
1269 if (arg->file == NULL)
1270 get_param_value(file, sizeof(file), "file", str);
1271 else
1272 pstrcpy(file, sizeof(file), arg->file);
1273
1274 if (!get_param_value(serial, sizeof(serial), "serial", str))
1275 memset(serial, 0, sizeof(serial));
1276
1277 onerror = BLOCK_ERR_STOP_ENOSPC;
1278 if (get_param_value(buf, sizeof(serial), "werror", str)) {
1279 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
1280 fprintf(stderr, "werror is no supported by this format\n");
1281 return -1;
1282 }
1283 if (!strcmp(buf, "ignore"))
1284 onerror = BLOCK_ERR_IGNORE;
1285 else if (!strcmp(buf, "enospc"))
1286 onerror = BLOCK_ERR_STOP_ENOSPC;
1287 else if (!strcmp(buf, "stop"))
1288 onerror = BLOCK_ERR_STOP_ANY;
1289 else if (!strcmp(buf, "report"))
1290 onerror = BLOCK_ERR_REPORT;
1291 else {
1292 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
1293 return -1;
1294 }
1295 }
1296
1297 /* compute bus and unit according index */
1298
1299 if (index != -1) {
1300 if (bus_id != 0 || unit_id != -1) {
1301 fprintf(stderr,
1302 "qemu: '%s' index cannot be used with bus and unit\n", str);
1303 return -1;
1304 }
1305 if (max_devs == 0)
1306 {
1307 unit_id = index;
1308 bus_id = 0;
1309 } else {
1310 unit_id = index % max_devs;
1311 bus_id = index / max_devs;
1312 }
1313 }
1314
1315 /* if user doesn't specify a unit_id,
1316 * try to find the first free
1317 */
1318
1319 if (unit_id == -1) {
1320 unit_id = 0;
1321 while (drive_get_index(type, bus_id, unit_id) != -1) {
1322 unit_id++;
1323 if (max_devs && unit_id >= max_devs) {
1324 unit_id -= max_devs;
1325 bus_id++;
1326 }
1327 }
1328 }
1329
1330 /* check unit id */
1331
1332 if (max_devs && unit_id >= max_devs) {
1333 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
1334 str, unit_id, max_devs - 1);
1335 return -1;
1336 }
1337
1338 /*
1339 * ignore multiple definitions
1340 */
1341
1342 if (drive_get_index(type, bus_id, unit_id) != -1)
1343 return -2;
1344
1345 /* init */
1346
1347 if (type == IF_IDE || type == IF_SCSI)
1348 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
1349 if (max_devs)
1350 snprintf(buf, sizeof(buf), "%s%i%s%i",
1351 devname, bus_id, mediastr, unit_id);
1352 else
1353 snprintf(buf, sizeof(buf), "%s%s%i",
1354 devname, mediastr, unit_id);
1355 bdrv = bdrv_new(buf);
1356 drives_table_idx = drive_get_free_idx();
1357 drives_table[drives_table_idx].bdrv = bdrv;
1358 drives_table[drives_table_idx].type = type;
1359 drives_table[drives_table_idx].bus = bus_id;
1360 drives_table[drives_table_idx].unit = unit_id;
1361 drives_table[drives_table_idx].onerror = onerror;
1362 drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
1363 strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
1364 nb_drives++;
1365
1366 switch(type) {
1367 case IF_IDE:
1368 case IF_SCSI:
1369 case IF_XEN:
1370 switch(media) {
1371 case MEDIA_DISK:
1372 if (cyls != 0) {
1373 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
1374 bdrv_set_translation_hint(bdrv, translation);
1375 }
1376 break;
1377 case MEDIA_CDROM:
1378 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
1379 break;
1380 }
1381 break;
1382 case IF_SD:
1383 /* FIXME: This isn't really a floppy, but it's a reasonable
1384 approximation. */
1385 case IF_FLOPPY:
1386 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
1387 break;
1388 case IF_PFLASH:
1389 case IF_MTD:
1390 case IF_VIRTIO:
1391 break;
1392 case IF_COUNT:
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07001393 case IF_NONE:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001394 abort();
1395 }
1396 if (!file[0])
1397 return -2;
1398 bdrv_flags = 0;
1399 if (snapshot) {
1400 bdrv_flags |= BDRV_O_SNAPSHOT;
1401 cache = 2; /* always use write-back with snapshot */
1402 }
1403 if (cache == 0) /* no caching */
1404 bdrv_flags |= BDRV_O_NOCACHE;
1405 else if (cache == 2) /* write-back */
1406 bdrv_flags |= BDRV_O_CACHE_WB;
1407 else if (cache == 3) /* not specified */
1408 bdrv_flags |= BDRV_O_CACHE_DEF;
1409 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
1410 fprintf(stderr, "qemu: could not open disk image %s\n",
1411 file);
1412 return -1;
1413 }
1414 if (bdrv_key_required(bdrv))
1415 autostart = 0;
1416 return drives_table_idx;
1417}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001418#endif /* MAX_DRIVES */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001419
1420static void numa_add(const char *optarg)
1421{
1422 char option[128];
1423 char *endptr;
1424 unsigned long long value, endvalue;
1425 int nodenr;
1426
1427 optarg = get_opt_name(option, 128, optarg, ',') + 1;
1428 if (!strcmp(option, "node")) {
1429 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
1430 nodenr = nb_numa_nodes;
1431 } else {
1432 nodenr = strtoull(option, NULL, 10);
1433 }
1434
1435 if (get_param_value(option, 128, "mem", optarg) == 0) {
1436 node_mem[nodenr] = 0;
1437 } else {
1438 value = strtoull(option, &endptr, 0);
1439 switch (*endptr) {
1440 case 0: case 'M': case 'm':
1441 value <<= 20;
1442 break;
1443 case 'G': case 'g':
1444 value <<= 30;
1445 break;
1446 }
1447 node_mem[nodenr] = value;
1448 }
1449 if (get_param_value(option, 128, "cpus", optarg) == 0) {
1450 node_cpumask[nodenr] = 0;
1451 } else {
1452 value = strtoull(option, &endptr, 10);
1453 if (value >= 64) {
1454 value = 63;
1455 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
1456 } else {
1457 if (*endptr == '-') {
1458 endvalue = strtoull(endptr+1, &endptr, 10);
1459 if (endvalue >= 63) {
1460 endvalue = 62;
1461 fprintf(stderr,
1462 "only 63 CPUs in NUMA mode supported.\n");
1463 }
1464 value = (1 << (endvalue + 1)) - (1 << value);
1465 } else {
1466 value = 1 << value;
1467 }
1468 }
1469 node_cpumask[nodenr] = value;
1470 }
1471 nb_numa_nodes++;
1472 }
1473 return;
1474}
1475
1476/***********************************************************/
1477/* USB devices */
1478
1479static USBPort *used_usb_ports;
1480static USBPort *free_usb_ports;
1481
1482/* ??? Maybe change this to register a hub to keep track of the topology. */
1483void qemu_register_usb_port(USBPort *port, void *opaque, int index,
1484 usb_attachfn attach)
1485{
1486 port->opaque = opaque;
1487 port->index = index;
1488 port->attach = attach;
1489 port->next = free_usb_ports;
1490 free_usb_ports = port;
1491}
1492
1493int usb_device_add_dev(USBDevice *dev)
1494{
1495 USBPort *port;
1496
1497 /* Find a USB port to add the device to. */
1498 port = free_usb_ports;
1499 if (!port->next) {
1500 USBDevice *hub;
1501
1502 /* Create a new hub and chain it on. */
1503 free_usb_ports = NULL;
1504 port->next = used_usb_ports;
1505 used_usb_ports = port;
1506
1507 hub = usb_hub_init(VM_USB_HUB_SIZE);
1508 usb_attach(port, hub);
1509 port = free_usb_ports;
1510 }
1511
1512 free_usb_ports = port->next;
1513 port->next = used_usb_ports;
1514 used_usb_ports = port;
1515 usb_attach(port, dev);
1516 return 0;
1517}
1518
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001519#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001520static void usb_msd_password_cb(void *opaque, int err)
1521{
1522 USBDevice *dev = opaque;
1523
1524 if (!err)
1525 usb_device_add_dev(dev);
1526 else
1527 dev->handle_destroy(dev);
1528}
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001529#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001530
1531static int usb_device_add(const char *devname, int is_hotplug)
1532{
1533 const char *p;
1534 USBDevice *dev;
1535
1536 if (!free_usb_ports)
1537 return -1;
1538
1539 if (strstart(devname, "host:", &p)) {
1540 dev = usb_host_device_open(p);
1541 } else if (!strcmp(devname, "mouse")) {
1542 dev = usb_mouse_init();
1543 } else if (!strcmp(devname, "tablet")) {
1544 dev = usb_tablet_init();
1545 } else if (!strcmp(devname, "keyboard")) {
1546 dev = usb_keyboard_init();
1547 } else if (strstart(devname, "disk:", &p)) {
1548#if 0
1549 BlockDriverState *bs;
1550#endif
1551 dev = usb_msd_init(p);
1552 if (!dev)
1553 return -1;
1554#if 0
1555 bs = usb_msd_get_bdrv(dev);
1556 if (bdrv_key_required(bs)) {
1557 autostart = 0;
1558 if (is_hotplug) {
1559 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
1560 dev);
1561 return 0;
1562 }
1563 }
1564 } else if (!strcmp(devname, "wacom-tablet")) {
1565 dev = usb_wacom_init();
1566 } else if (strstart(devname, "serial:", &p)) {
1567 dev = usb_serial_init(p);
1568#ifdef CONFIG_BRLAPI
1569 } else if (!strcmp(devname, "braille")) {
1570 dev = usb_baum_init();
1571#endif
1572 } else if (strstart(devname, "net:", &p)) {
1573 int nic = nb_nics;
1574
1575 if (net_client_init("nic", p) < 0)
1576 return -1;
1577 nd_table[nic].model = "usb";
1578 dev = usb_net_init(&nd_table[nic]);
1579 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
1580 dev = usb_bt_init(devname[2] ? hci_init(p) :
1581 bt_new_hci(qemu_find_bt_vlan(0)));
1582#endif
1583 } else {
1584 return -1;
1585 }
1586 if (!dev)
1587 return -1;
1588
1589 return usb_device_add_dev(dev);
1590}
1591
1592int usb_device_del_addr(int bus_num, int addr)
1593{
1594 USBPort *port;
1595 USBPort **lastp;
1596 USBDevice *dev;
1597
1598 if (!used_usb_ports)
1599 return -1;
1600
1601 if (bus_num != 0)
1602 return -1;
1603
1604 lastp = &used_usb_ports;
1605 port = used_usb_ports;
1606 while (port && port->dev->addr != addr) {
1607 lastp = &port->next;
1608 port = port->next;
1609 }
1610
1611 if (!port)
1612 return -1;
1613
1614 dev = port->dev;
1615 *lastp = port->next;
1616 usb_attach(port, NULL);
1617 dev->handle_destroy(dev);
1618 port->next = free_usb_ports;
1619 free_usb_ports = port;
1620 return 0;
1621}
1622
1623static int usb_device_del(const char *devname)
1624{
1625 int bus_num, addr;
1626 const char *p;
1627
1628 if (strstart(devname, "host:", &p))
1629 return usb_host_device_close(p);
1630
1631 if (!used_usb_ports)
1632 return -1;
1633
1634 p = strchr(devname, '.');
1635 if (!p)
1636 return -1;
1637 bus_num = strtoul(devname, NULL, 0);
1638 addr = strtoul(p + 1, NULL, 0);
1639
1640 return usb_device_del_addr(bus_num, addr);
1641}
1642
1643void do_usb_add(Monitor *mon, const char *devname)
1644{
1645 usb_device_add(devname, 1);
1646}
1647
1648void do_usb_del(Monitor *mon, const char *devname)
1649{
1650 usb_device_del(devname);
1651}
1652
1653void usb_info(Monitor *mon)
1654{
1655 USBDevice *dev;
1656 USBPort *port;
1657 const char *speed_str;
1658
1659 if (!usb_enabled) {
1660 monitor_printf(mon, "USB support not enabled\n");
1661 return;
1662 }
1663
1664 for (port = used_usb_ports; port; port = port->next) {
1665 dev = port->dev;
1666 if (!dev)
1667 continue;
1668 switch(dev->speed) {
1669 case USB_SPEED_LOW:
1670 speed_str = "1.5";
1671 break;
1672 case USB_SPEED_FULL:
1673 speed_str = "12";
1674 break;
1675 case USB_SPEED_HIGH:
1676 speed_str = "480";
1677 break;
1678 default:
1679 speed_str = "?";
1680 break;
1681 }
1682 monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
1683 0, dev->addr, speed_str, dev->devname);
1684 }
1685}
1686
1687/***********************************************************/
1688/* PCMCIA/Cardbus */
1689
1690static struct pcmcia_socket_entry_s {
1691 PCMCIASocket *socket;
1692 struct pcmcia_socket_entry_s *next;
1693} *pcmcia_sockets = 0;
1694
1695void pcmcia_socket_register(PCMCIASocket *socket)
1696{
1697 struct pcmcia_socket_entry_s *entry;
1698
1699 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
1700 entry->socket = socket;
1701 entry->next = pcmcia_sockets;
1702 pcmcia_sockets = entry;
1703}
1704
1705void pcmcia_socket_unregister(PCMCIASocket *socket)
1706{
1707 struct pcmcia_socket_entry_s *entry, **ptr;
1708
1709 ptr = &pcmcia_sockets;
1710 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
1711 if (entry->socket == socket) {
1712 *ptr = entry->next;
1713 qemu_free(entry);
1714 }
1715}
1716
1717void pcmcia_info(Monitor *mon)
1718{
1719 struct pcmcia_socket_entry_s *iter;
1720
1721 if (!pcmcia_sockets)
1722 monitor_printf(mon, "No PCMCIA sockets\n");
1723
1724 for (iter = pcmcia_sockets; iter; iter = iter->next)
1725 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
1726 iter->socket->attached ? iter->socket->card_string :
1727 "Empty");
1728}
1729
1730/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001731/* I/O handling */
1732
1733typedef struct IOHandlerRecord {
1734 int fd;
David Turner4143d8f2010-09-10 11:05:02 +02001735 IOCanReadHandler *fd_read_poll;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001736 IOHandler *fd_read;
1737 IOHandler *fd_write;
1738 int deleted;
1739 void *opaque;
1740 /* temporary data */
1741 struct pollfd *ufd;
1742 struct IOHandlerRecord *next;
1743} IOHandlerRecord;
1744
1745static IOHandlerRecord *first_io_handler;
1746
1747/* XXX: fd_read_poll should be suppressed, but an API change is
1748 necessary in the character devices to suppress fd_can_read(). */
1749int qemu_set_fd_handler2(int fd,
David Turner4143d8f2010-09-10 11:05:02 +02001750 IOCanReadHandler *fd_read_poll,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001751 IOHandler *fd_read,
1752 IOHandler *fd_write,
1753 void *opaque)
1754{
1755 IOHandlerRecord **pioh, *ioh;
1756
1757 if (!fd_read && !fd_write) {
1758 pioh = &first_io_handler;
1759 for(;;) {
1760 ioh = *pioh;
1761 if (ioh == NULL)
1762 break;
1763 if (ioh->fd == fd) {
1764 ioh->deleted = 1;
1765 break;
1766 }
1767 pioh = &ioh->next;
1768 }
1769 } else {
1770 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
1771 if (ioh->fd == fd)
1772 goto found;
1773 }
1774 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
1775 ioh->next = first_io_handler;
1776 first_io_handler = ioh;
1777 found:
1778 ioh->fd = fd;
1779 ioh->fd_read_poll = fd_read_poll;
1780 ioh->fd_read = fd_read;
1781 ioh->fd_write = fd_write;
1782 ioh->opaque = opaque;
1783 ioh->deleted = 0;
1784 }
1785 return 0;
1786}
1787
1788int qemu_set_fd_handler(int fd,
1789 IOHandler *fd_read,
1790 IOHandler *fd_write,
1791 void *opaque)
1792{
1793 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
1794}
1795
1796#ifdef _WIN32
1797/***********************************************************/
1798/* Polling handling */
1799
1800typedef struct PollingEntry {
1801 PollingFunc *func;
1802 void *opaque;
1803 struct PollingEntry *next;
1804} PollingEntry;
1805
1806static PollingEntry *first_polling_entry;
1807
1808int qemu_add_polling_cb(PollingFunc *func, void *opaque)
1809{
1810 PollingEntry **ppe, *pe;
1811 pe = qemu_mallocz(sizeof(PollingEntry));
1812 pe->func = func;
1813 pe->opaque = opaque;
1814 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
1815 *ppe = pe;
1816 return 0;
1817}
1818
1819void qemu_del_polling_cb(PollingFunc *func, void *opaque)
1820{
1821 PollingEntry **ppe, *pe;
1822 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
1823 pe = *ppe;
1824 if (pe->func == func && pe->opaque == opaque) {
1825 *ppe = pe->next;
1826 qemu_free(pe);
1827 break;
1828 }
1829 }
1830}
1831
1832/***********************************************************/
1833/* Wait objects support */
1834typedef struct WaitObjects {
1835 int num;
1836 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
1837 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
1838 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
1839} WaitObjects;
1840
1841static WaitObjects wait_objects = {0};
1842
1843int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
1844{
1845 WaitObjects *w = &wait_objects;
1846
1847 if (w->num >= MAXIMUM_WAIT_OBJECTS)
1848 return -1;
1849 w->events[w->num] = handle;
1850 w->func[w->num] = func;
1851 w->opaque[w->num] = opaque;
1852 w->num++;
1853 return 0;
1854}
1855
1856void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
1857{
1858 int i, found;
1859 WaitObjects *w = &wait_objects;
1860
1861 found = 0;
1862 for (i = 0; i < w->num; i++) {
1863 if (w->events[i] == handle)
1864 found = 1;
1865 if (found) {
1866 w->events[i] = w->events[i + 1];
1867 w->func[i] = w->func[i + 1];
1868 w->opaque[i] = w->opaque[i + 1];
1869 }
1870 }
1871 if (found)
1872 w->num--;
1873}
1874#endif
1875
1876/***********************************************************/
1877/* ram save/restore */
1878
1879static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
1880{
1881 int v;
1882
1883 v = qemu_get_byte(f);
1884 switch(v) {
1885 case 0:
1886 if (qemu_get_buffer(f, buf, len) != len)
1887 return -EIO;
1888 break;
1889 case 1:
1890 v = qemu_get_byte(f);
1891 memset(buf, v, len);
1892 break;
1893 default:
1894 return -EINVAL;
1895 }
1896
1897 if (qemu_file_has_error(f))
1898 return -EIO;
1899
1900 return 0;
1901}
1902
1903static int ram_load_v1(QEMUFile *f, void *opaque)
1904{
1905 int ret;
1906 ram_addr_t i;
1907
1908 if (qemu_get_be32(f) != last_ram_offset)
1909 return -EINVAL;
1910 for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
1911 ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
1912 if (ret)
1913 return ret;
1914 }
1915 return 0;
1916}
1917
1918#define BDRV_HASH_BLOCK_SIZE 1024
1919#define IOBUF_SIZE 4096
1920#define RAM_CBLOCK_MAGIC 0xfabe
1921
1922typedef struct RamDecompressState {
1923 z_stream zstream;
1924 QEMUFile *f;
1925 uint8_t buf[IOBUF_SIZE];
1926} RamDecompressState;
1927
1928static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
1929{
1930 int ret;
1931 memset(s, 0, sizeof(*s));
1932 s->f = f;
1933 ret = inflateInit(&s->zstream);
1934 if (ret != Z_OK)
1935 return -1;
1936 return 0;
1937}
1938
1939static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
1940{
1941 int ret, clen;
1942
1943 s->zstream.avail_out = len;
1944 s->zstream.next_out = buf;
1945 while (s->zstream.avail_out > 0) {
1946 if (s->zstream.avail_in == 0) {
1947 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
1948 return -1;
1949 clen = qemu_get_be16(s->f);
1950 if (clen > IOBUF_SIZE)
1951 return -1;
1952 qemu_get_buffer(s->f, s->buf, clen);
1953 s->zstream.avail_in = clen;
1954 s->zstream.next_in = s->buf;
1955 }
1956 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
1957 if (ret != Z_OK && ret != Z_STREAM_END) {
1958 return -1;
1959 }
1960 }
1961 return 0;
1962}
1963
1964static void ram_decompress_close(RamDecompressState *s)
1965{
1966 inflateEnd(&s->zstream);
1967}
1968
1969#define RAM_SAVE_FLAG_FULL 0x01
1970#define RAM_SAVE_FLAG_COMPRESS 0x02
1971#define RAM_SAVE_FLAG_MEM_SIZE 0x04
1972#define RAM_SAVE_FLAG_PAGE 0x08
1973#define RAM_SAVE_FLAG_EOS 0x10
1974
1975static int is_dup_page(uint8_t *page, uint8_t ch)
1976{
1977 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
1978 uint32_t *array = (uint32_t *)page;
1979 int i;
1980
1981 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
1982 if (array[i] != val)
1983 return 0;
1984 }
1985
1986 return 1;
1987}
1988
1989static int ram_save_block(QEMUFile *f)
1990{
1991 static ram_addr_t current_addr = 0;
1992 ram_addr_t saved_addr = current_addr;
1993 ram_addr_t addr = 0;
1994 int found = 0;
1995
1996 while (addr < last_ram_offset) {
1997 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
1998 uint8_t *p;
1999
2000 cpu_physical_memory_reset_dirty(current_addr,
2001 current_addr + TARGET_PAGE_SIZE,
2002 MIGRATION_DIRTY_FLAG);
2003
2004 p = qemu_get_ram_ptr(current_addr);
2005
2006 if (is_dup_page(p, *p)) {
2007 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
2008 qemu_put_byte(f, *p);
2009 } else {
2010 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
2011 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
2012 }
2013
2014 found = 1;
2015 break;
2016 }
2017 addr += TARGET_PAGE_SIZE;
2018 current_addr = (saved_addr + addr) % last_ram_offset;
2019 }
2020
2021 return found;
2022}
2023
2024static uint64_t bytes_transferred = 0;
2025
2026static ram_addr_t ram_save_remaining(void)
2027{
2028 ram_addr_t addr;
2029 ram_addr_t count = 0;
2030
2031 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2032 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2033 count++;
2034 }
2035
2036 return count;
2037}
2038
2039uint64_t ram_bytes_remaining(void)
2040{
2041 return ram_save_remaining() * TARGET_PAGE_SIZE;
2042}
2043
2044uint64_t ram_bytes_transferred(void)
2045{
2046 return bytes_transferred;
2047}
2048
2049uint64_t ram_bytes_total(void)
2050{
2051 return last_ram_offset;
2052}
2053
2054static int ram_save_live(QEMUFile *f, int stage, void *opaque)
2055{
2056 ram_addr_t addr;
2057 uint64_t bytes_transferred_last;
2058 double bwidth = 0;
2059 uint64_t expected_time = 0;
2060
2061 cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX);
2062
2063 if (stage == 1) {
2064 /* Make sure all dirty bits are set */
2065 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2066 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2067 cpu_physical_memory_set_dirty(addr);
2068 }
2069
2070 /* Enable dirty memory tracking */
2071 cpu_physical_memory_set_dirty_tracking(1);
2072
2073 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
2074 }
2075
2076 bytes_transferred_last = bytes_transferred;
David Turner6a9ef172010-09-09 22:54:36 +02002077 bwidth = qemu_get_clock_ns(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002078
2079 while (!qemu_file_rate_limit(f)) {
2080 int ret;
2081
2082 ret = ram_save_block(f);
2083 bytes_transferred += ret * TARGET_PAGE_SIZE;
2084 if (ret == 0) /* no more blocks */
2085 break;
2086 }
2087
David Turner6a9ef172010-09-09 22:54:36 +02002088 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002089 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
2090
2091 /* if we haven't transferred anything this round, force expected_time to a
2092 * a very high value, but without crashing */
2093 if (bwidth == 0)
2094 bwidth = 0.000001;
2095
2096 /* try transferring iterative blocks of memory */
2097
2098 if (stage == 3) {
2099
2100 /* flush all remaining blocks regardless of rate limiting */
2101 while (ram_save_block(f) != 0) {
2102 bytes_transferred += TARGET_PAGE_SIZE;
2103 }
2104 cpu_physical_memory_set_dirty_tracking(0);
2105 }
2106
2107 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
2108
2109 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
2110
2111 return (stage == 2) && (expected_time <= migrate_max_downtime());
2112}
2113
2114static int ram_load_dead(QEMUFile *f, void *opaque)
2115{
2116 RamDecompressState s1, *s = &s1;
2117 uint8_t buf[10];
2118 ram_addr_t i;
2119
2120 if (ram_decompress_open(s, f) < 0)
2121 return -EINVAL;
2122 for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
2123 if (ram_decompress_buf(s, buf, 1) < 0) {
2124 fprintf(stderr, "Error while reading ram block header\n");
2125 goto error;
2126 }
2127 if (buf[0] == 0) {
2128 if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
2129 BDRV_HASH_BLOCK_SIZE) < 0) {
2130 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
2131 goto error;
2132 }
2133 } else {
2134 error:
2135 printf("Error block header\n");
2136 return -EINVAL;
2137 }
2138 }
2139 ram_decompress_close(s);
2140
2141 return 0;
2142}
2143
2144static int ram_load(QEMUFile *f, void *opaque, int version_id)
2145{
2146 ram_addr_t addr;
2147 int flags;
2148
2149 if (version_id == 1)
2150 return ram_load_v1(f, opaque);
2151
2152 if (version_id == 2) {
2153 if (qemu_get_be32(f) != last_ram_offset)
2154 return -EINVAL;
2155 return ram_load_dead(f, opaque);
2156 }
2157
2158 if (version_id != 3)
2159 return -EINVAL;
2160
2161 do {
2162 addr = qemu_get_be64(f);
2163
2164 flags = addr & ~TARGET_PAGE_MASK;
2165 addr &= TARGET_PAGE_MASK;
2166
2167 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
2168 if (addr != last_ram_offset)
2169 return -EINVAL;
2170 }
2171
2172 if (flags & RAM_SAVE_FLAG_FULL) {
2173 if (ram_load_dead(f, opaque) < 0)
2174 return -EINVAL;
2175 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07002176
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002177 if (flags & RAM_SAVE_FLAG_COMPRESS) {
2178 uint8_t ch = qemu_get_byte(f);
2179 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
2180 } else if (flags & RAM_SAVE_FLAG_PAGE)
2181 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
2182 } while (!(flags & RAM_SAVE_FLAG_EOS));
2183
2184 return 0;
2185}
2186
2187void qemu_service_io(void)
2188{
2189 qemu_notify_event();
2190}
2191
2192/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002193/* machine registration */
2194
2195static QEMUMachine *first_machine = NULL;
2196QEMUMachine *current_machine = NULL;
2197
2198int qemu_register_machine(QEMUMachine *m)
2199{
2200 QEMUMachine **pm;
2201 pm = &first_machine;
2202 while (*pm != NULL)
2203 pm = &(*pm)->next;
2204 m->next = NULL;
2205 *pm = m;
2206 return 0;
2207}
2208
2209static QEMUMachine *find_machine(const char *name)
2210{
2211 QEMUMachine *m;
2212
2213 for(m = first_machine; m != NULL; m = m->next) {
2214 if (!strcmp(m->name, name))
2215 return m;
2216 }
2217 return NULL;
2218}
2219
2220static QEMUMachine *find_default_machine(void)
2221{
2222 QEMUMachine *m;
2223
2224 for(m = first_machine; m != NULL; m = m->next) {
2225 if (m->is_default) {
2226 return m;
2227 }
2228 }
2229 return NULL;
2230}
2231
2232/***********************************************************/
2233/* main execution loop */
2234
2235static void gui_update(void *opaque)
2236{
2237 uint64_t interval = GUI_REFRESH_INTERVAL;
2238 DisplayState *ds = opaque;
2239 DisplayChangeListener *dcl = ds->listeners;
2240
2241 dpy_refresh(ds);
2242
2243 while (dcl != NULL) {
2244 if (dcl->gui_timer_interval &&
2245 dcl->gui_timer_interval < interval)
2246 interval = dcl->gui_timer_interval;
2247 dcl = dcl->next;
2248 }
2249 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
2250}
2251
2252static void nographic_update(void *opaque)
2253{
2254 uint64_t interval = GUI_REFRESH_INTERVAL;
2255
2256 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
2257}
2258
2259struct vm_change_state_entry {
2260 VMChangeStateHandler *cb;
2261 void *opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002262 QLIST_ENTRY (vm_change_state_entry) entries;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002263};
2264
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002265static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002266
2267VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
2268 void *opaque)
2269{
2270 VMChangeStateEntry *e;
2271
2272 e = qemu_mallocz(sizeof (*e));
2273
2274 e->cb = cb;
2275 e->opaque = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002276 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002277 return e;
2278}
2279
2280void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
2281{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002282 QLIST_REMOVE (e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002283 qemu_free (e);
2284}
2285
2286static void vm_state_notify(int running, int reason)
2287{
2288 VMChangeStateEntry *e;
2289
2290 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
2291 e->cb(e->opaque, running, reason);
2292 }
2293}
2294
2295static void resume_all_vcpus(void);
2296static void pause_all_vcpus(void);
2297
2298void vm_start(void)
2299{
2300 if (!vm_running) {
2301 cpu_enable_ticks();
2302 vm_running = 1;
2303 vm_state_notify(1, 0);
David Turner6a9ef172010-09-09 22:54:36 +02002304 //qemu_rearm_alarm_timer(alarm_timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002305 resume_all_vcpus();
2306 }
2307}
2308
2309/* reset/shutdown handler */
2310
2311typedef struct QEMUResetEntry {
2312 QEMUResetHandler *func;
2313 void *opaque;
2314 int order;
2315 struct QEMUResetEntry *next;
2316} QEMUResetEntry;
2317
2318static QEMUResetEntry *first_reset_entry;
2319static int reset_requested;
2320static int shutdown_requested;
2321static int powerdown_requested;
2322static int debug_requested;
2323static int vmstop_requested;
2324
2325int qemu_shutdown_requested(void)
2326{
2327 int r = shutdown_requested;
2328 shutdown_requested = 0;
2329 return r;
2330}
2331
2332int qemu_reset_requested(void)
2333{
2334 int r = reset_requested;
2335 reset_requested = 0;
2336 return r;
2337}
2338
2339int qemu_powerdown_requested(void)
2340{
2341 int r = powerdown_requested;
2342 powerdown_requested = 0;
2343 return r;
2344}
2345
2346static int qemu_debug_requested(void)
2347{
2348 int r = debug_requested;
2349 debug_requested = 0;
2350 return r;
2351}
2352
2353static int qemu_vmstop_requested(void)
2354{
2355 int r = vmstop_requested;
2356 vmstop_requested = 0;
2357 return r;
2358}
2359
2360static void do_vm_stop(int reason)
2361{
2362 if (vm_running) {
2363 cpu_disable_ticks();
2364 vm_running = 0;
2365 pause_all_vcpus();
2366 vm_state_notify(0, reason);
2367 }
2368}
2369
2370void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
2371{
2372 QEMUResetEntry **pre, *re;
2373
2374 pre = &first_reset_entry;
2375 while (*pre != NULL && (*pre)->order >= order) {
2376 pre = &(*pre)->next;
2377 }
2378 re = qemu_mallocz(sizeof(QEMUResetEntry));
2379 re->func = func;
2380 re->opaque = opaque;
2381 re->order = order;
2382 re->next = NULL;
2383 *pre = re;
2384}
2385
2386void qemu_system_reset(void)
2387{
2388 QEMUResetEntry *re;
2389
2390 /* reset all devices */
2391 for(re = first_reset_entry; re != NULL; re = re->next) {
2392 re->func(re->opaque);
2393 }
2394}
2395
2396void qemu_system_reset_request(void)
2397{
2398 if (no_reboot) {
2399 shutdown_requested = 1;
2400 } else {
2401 reset_requested = 1;
2402 }
2403 qemu_notify_event();
2404}
2405
2406void qemu_system_shutdown_request(void)
2407{
2408 shutdown_requested = 1;
2409 qemu_notify_event();
2410}
2411
2412void qemu_system_powerdown_request(void)
2413{
2414 powerdown_requested = 1;
2415 qemu_notify_event();
2416}
2417
2418#ifdef CONFIG_IOTHREAD
2419static void qemu_system_vmstop_request(int reason)
2420{
2421 vmstop_requested = reason;
2422 qemu_notify_event();
2423}
2424#endif
2425
2426#ifndef _WIN32
2427static int io_thread_fd = -1;
2428
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002429#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002430static void qemu_event_increment(void)
2431{
2432 static const char byte = 0;
2433
2434 if (io_thread_fd == -1)
2435 return;
2436
2437 write(io_thread_fd, &byte, sizeof(byte));
2438}
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002439#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002440
2441static void qemu_event_read(void *opaque)
2442{
2443 int fd = (unsigned long)opaque;
2444 ssize_t len;
2445
2446 /* Drain the notify pipe */
2447 do {
2448 char buffer[512];
2449 len = read(fd, buffer, sizeof(buffer));
2450 } while ((len == -1 && errno == EINTR) || len > 0);
2451}
2452
2453static int qemu_event_init(void)
2454{
2455 int err;
2456 int fds[2];
2457
2458 err = pipe(fds);
2459 if (err == -1)
2460 return -errno;
2461
2462 err = fcntl_setfl(fds[0], O_NONBLOCK);
2463 if (err < 0)
2464 goto fail;
2465
2466 err = fcntl_setfl(fds[1], O_NONBLOCK);
2467 if (err < 0)
2468 goto fail;
2469
2470 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
2471 (void *)(unsigned long)fds[0]);
2472
2473 io_thread_fd = fds[1];
2474 return 0;
2475
2476fail:
2477 close(fds[0]);
2478 close(fds[1]);
2479 return err;
2480}
2481#else
2482HANDLE qemu_event_handle;
2483
2484static void dummy_event_handler(void *opaque)
2485{
2486}
2487
2488static int qemu_event_init(void)
2489{
2490 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
2491 if (!qemu_event_handle) {
2492 perror("Failed CreateEvent");
2493 return -1;
2494 }
2495 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
2496 return 0;
2497}
2498
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02002499#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002500static void qemu_event_increment(void)
2501{
2502 SetEvent(qemu_event_handle);
2503}
2504#endif
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02002505#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002506
2507static int cpu_can_run(CPUState *env)
2508{
2509 if (env->stop)
2510 return 0;
2511 if (env->stopped)
2512 return 0;
2513 return 1;
2514}
2515
2516#ifndef CONFIG_IOTHREAD
2517static int qemu_init_main_loop(void)
2518{
2519 return qemu_event_init();
2520}
2521
2522void qemu_init_vcpu(void *_env)
2523{
2524 CPUState *env = _env;
2525
2526 if (kvm_enabled())
2527 kvm_init_vcpu(env);
2528 return;
2529}
2530
2531int qemu_cpu_self(void *env)
2532{
2533 return 1;
2534}
2535
2536static void resume_all_vcpus(void)
2537{
2538}
2539
2540static void pause_all_vcpus(void)
2541{
2542}
2543
2544void qemu_cpu_kick(void *env)
2545{
2546 return;
2547}
2548
2549void qemu_notify_event(void)
2550{
2551 CPUState *env = cpu_single_env;
2552
2553 if (env) {
2554 cpu_exit(env);
2555#ifdef USE_KQEMU
2556 if (env->kqemu_enabled)
2557 kqemu_cpu_interrupt(env);
2558#endif
2559 }
2560}
2561
2562#define qemu_mutex_lock_iothread() do { } while (0)
2563#define qemu_mutex_unlock_iothread() do { } while (0)
2564
2565void vm_stop(int reason)
2566{
2567 do_vm_stop(reason);
2568}
2569
2570#else /* CONFIG_IOTHREAD */
2571
2572#include "qemu-thread.h"
2573
2574QemuMutex qemu_global_mutex;
2575static QemuMutex qemu_fair_mutex;
2576
2577static QemuThread io_thread;
2578
2579static QemuThread *tcg_cpu_thread;
2580static QemuCond *tcg_halt_cond;
2581
2582static int qemu_system_ready;
2583/* cpu creation */
2584static QemuCond qemu_cpu_cond;
2585/* system init */
2586static QemuCond qemu_system_cond;
2587static QemuCond qemu_pause_cond;
2588
2589static void block_io_signals(void);
2590static void unblock_io_signals(void);
2591static int tcg_has_work(void);
2592
2593static int qemu_init_main_loop(void)
2594{
2595 int ret;
2596
2597 ret = qemu_event_init();
2598 if (ret)
2599 return ret;
2600
2601 qemu_cond_init(&qemu_pause_cond);
2602 qemu_mutex_init(&qemu_fair_mutex);
2603 qemu_mutex_init(&qemu_global_mutex);
2604 qemu_mutex_lock(&qemu_global_mutex);
2605
2606 unblock_io_signals();
2607 qemu_thread_self(&io_thread);
2608
2609 return 0;
2610}
2611
2612static void qemu_wait_io_event(CPUState *env)
2613{
2614 while (!tcg_has_work())
2615 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
2616
2617 qemu_mutex_unlock(&qemu_global_mutex);
2618
2619 /*
2620 * Users of qemu_global_mutex can be starved, having no chance
2621 * to acquire it since this path will get to it first.
2622 * So use another lock to provide fairness.
2623 */
2624 qemu_mutex_lock(&qemu_fair_mutex);
2625 qemu_mutex_unlock(&qemu_fair_mutex);
2626
2627 qemu_mutex_lock(&qemu_global_mutex);
2628 if (env->stop) {
2629 env->stop = 0;
2630 env->stopped = 1;
2631 qemu_cond_signal(&qemu_pause_cond);
2632 }
2633}
2634
2635static int qemu_cpu_exec(CPUState *env);
2636
2637static void *kvm_cpu_thread_fn(void *arg)
2638{
2639 CPUState *env = arg;
2640
2641 block_io_signals();
2642 qemu_thread_self(env->thread);
2643
2644 /* signal CPU creation */
2645 qemu_mutex_lock(&qemu_global_mutex);
2646 env->created = 1;
2647 qemu_cond_signal(&qemu_cpu_cond);
2648
2649 /* and wait for machine initialization */
2650 while (!qemu_system_ready)
2651 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2652
2653 while (1) {
2654 if (cpu_can_run(env))
2655 qemu_cpu_exec(env);
2656 qemu_wait_io_event(env);
2657 }
2658
2659 return NULL;
2660}
2661
2662static void tcg_cpu_exec(void);
2663
2664static void *tcg_cpu_thread_fn(void *arg)
2665{
2666 CPUState *env = arg;
2667
2668 block_io_signals();
2669 qemu_thread_self(env->thread);
2670
2671 /* signal CPU creation */
2672 qemu_mutex_lock(&qemu_global_mutex);
2673 for (env = first_cpu; env != NULL; env = env->next_cpu)
2674 env->created = 1;
2675 qemu_cond_signal(&qemu_cpu_cond);
2676
2677 /* and wait for machine initialization */
2678 while (!qemu_system_ready)
2679 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2680
2681 while (1) {
2682 tcg_cpu_exec();
2683 qemu_wait_io_event(cur_cpu);
2684 }
2685
2686 return NULL;
2687}
2688
2689void qemu_cpu_kick(void *_env)
2690{
2691 CPUState *env = _env;
2692 qemu_cond_broadcast(env->halt_cond);
2693 if (kvm_enabled())
2694 qemu_thread_signal(env->thread, SIGUSR1);
2695}
2696
2697int qemu_cpu_self(void *env)
2698{
2699 return (cpu_single_env != NULL);
2700}
2701
2702static void cpu_signal(int sig)
2703{
2704 if (cpu_single_env)
2705 cpu_exit(cpu_single_env);
2706}
2707
2708static void block_io_signals(void)
2709{
2710 sigset_t set;
2711 struct sigaction sigact;
2712
2713 sigemptyset(&set);
2714 sigaddset(&set, SIGUSR2);
2715 sigaddset(&set, SIGIO);
2716 sigaddset(&set, SIGALRM);
2717 pthread_sigmask(SIG_BLOCK, &set, NULL);
2718
2719 sigemptyset(&set);
2720 sigaddset(&set, SIGUSR1);
2721 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2722
2723 memset(&sigact, 0, sizeof(sigact));
2724 sigact.sa_handler = cpu_signal;
2725 sigaction(SIGUSR1, &sigact, NULL);
2726}
2727
2728static void unblock_io_signals(void)
2729{
2730 sigset_t set;
2731
2732 sigemptyset(&set);
2733 sigaddset(&set, SIGUSR2);
2734 sigaddset(&set, SIGIO);
2735 sigaddset(&set, SIGALRM);
2736 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2737
2738 sigemptyset(&set);
2739 sigaddset(&set, SIGUSR1);
2740 pthread_sigmask(SIG_BLOCK, &set, NULL);
2741}
2742
2743static void qemu_signal_lock(unsigned int msecs)
2744{
2745 qemu_mutex_lock(&qemu_fair_mutex);
2746
2747 while (qemu_mutex_trylock(&qemu_global_mutex)) {
2748 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
2749 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
2750 break;
2751 }
2752 qemu_mutex_unlock(&qemu_fair_mutex);
2753}
2754
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002755void qemu_mutex_lock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002756{
2757 if (kvm_enabled()) {
2758 qemu_mutex_lock(&qemu_fair_mutex);
2759 qemu_mutex_lock(&qemu_global_mutex);
2760 qemu_mutex_unlock(&qemu_fair_mutex);
2761 } else
2762 qemu_signal_lock(100);
2763}
2764
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002765void qemu_mutex_unlock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002766{
2767 qemu_mutex_unlock(&qemu_global_mutex);
2768}
2769
2770static int all_vcpus_paused(void)
2771{
2772 CPUState *penv = first_cpu;
2773
2774 while (penv) {
2775 if (!penv->stopped)
2776 return 0;
2777 penv = (CPUState *)penv->next_cpu;
2778 }
2779
2780 return 1;
2781}
2782
2783static void pause_all_vcpus(void)
2784{
2785 CPUState *penv = first_cpu;
2786
2787 while (penv) {
2788 penv->stop = 1;
2789 qemu_thread_signal(penv->thread, SIGUSR1);
2790 qemu_cpu_kick(penv);
2791 penv = (CPUState *)penv->next_cpu;
2792 }
2793
2794 while (!all_vcpus_paused()) {
2795 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
2796 penv = first_cpu;
2797 while (penv) {
2798 qemu_thread_signal(penv->thread, SIGUSR1);
2799 penv = (CPUState *)penv->next_cpu;
2800 }
2801 }
2802}
2803
2804static void resume_all_vcpus(void)
2805{
2806 CPUState *penv = first_cpu;
2807
2808 while (penv) {
2809 penv->stop = 0;
2810 penv->stopped = 0;
2811 qemu_thread_signal(penv->thread, SIGUSR1);
2812 qemu_cpu_kick(penv);
2813 penv = (CPUState *)penv->next_cpu;
2814 }
2815}
2816
2817static void tcg_init_vcpu(void *_env)
2818{
2819 CPUState *env = _env;
2820 /* share a single thread for all cpus with TCG */
2821 if (!tcg_cpu_thread) {
2822 env->thread = qemu_mallocz(sizeof(QemuThread));
2823 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
2824 qemu_cond_init(env->halt_cond);
2825 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
2826 while (env->created == 0)
2827 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2828 tcg_cpu_thread = env->thread;
2829 tcg_halt_cond = env->halt_cond;
2830 } else {
2831 env->thread = tcg_cpu_thread;
2832 env->halt_cond = tcg_halt_cond;
2833 }
2834}
2835
2836static void kvm_start_vcpu(CPUState *env)
2837{
2838#if 0
2839 kvm_init_vcpu(env);
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, kvm_cpu_thread_fn, env);
2844 while (env->created == 0)
2845 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2846#endif
2847}
2848
2849void qemu_init_vcpu(void *_env)
2850{
2851 CPUState *env = _env;
2852
2853 if (kvm_enabled())
2854 kvm_start_vcpu(env);
2855 else
2856 tcg_init_vcpu(env);
2857}
2858
2859void qemu_notify_event(void)
2860{
2861 qemu_event_increment();
2862}
2863
2864void vm_stop(int reason)
2865{
2866 QemuThread me;
2867 qemu_thread_self(&me);
2868
2869 if (!qemu_thread_equal(&me, &io_thread)) {
2870 qemu_system_vmstop_request(reason);
2871 /*
2872 * FIXME: should not return to device code in case
2873 * vm_stop() has been requested.
2874 */
2875 if (cpu_single_env) {
2876 cpu_exit(cpu_single_env);
2877 cpu_single_env->stop = 1;
2878 }
2879 return;
2880 }
2881 do_vm_stop(reason);
2882}
2883
2884#endif
2885
2886
2887#ifdef _WIN32
2888static void host_main_loop_wait(int *timeout)
2889{
2890 int ret, ret2, i;
2891 PollingEntry *pe;
2892
2893
2894 /* XXX: need to suppress polling by better using win32 events */
2895 ret = 0;
2896 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
2897 ret |= pe->func(pe->opaque);
2898 }
2899 if (ret == 0) {
2900 int err;
2901 WaitObjects *w = &wait_objects;
2902
2903 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
2904 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
2905 if (w->func[ret - WAIT_OBJECT_0])
2906 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
2907
2908 /* Check for additional signaled events */
2909 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
2910
2911 /* Check if event is signaled */
2912 ret2 = WaitForSingleObject(w->events[i], 0);
2913 if(ret2 == WAIT_OBJECT_0) {
2914 if (w->func[i])
2915 w->func[i](w->opaque[i]);
2916 } else if (ret2 == WAIT_TIMEOUT) {
2917 } else {
2918 err = GetLastError();
2919 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
2920 }
2921 }
2922 } else if (ret == WAIT_TIMEOUT) {
2923 } else {
2924 err = GetLastError();
2925 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
2926 }
2927 }
2928
2929 *timeout = 0;
2930}
2931#else
2932static void host_main_loop_wait(int *timeout)
2933{
2934}
2935#endif
2936
2937void main_loop_wait(int timeout)
2938{
2939 IOHandlerRecord *ioh;
2940 fd_set rfds, wfds, xfds;
2941 int ret, nfds;
2942 struct timeval tv;
2943
2944 qemu_bh_update_timeout(&timeout);
2945
2946 host_main_loop_wait(&timeout);
2947
2948 /* poll any events */
2949 /* XXX: separate device handlers from system ones */
2950 nfds = -1;
2951 FD_ZERO(&rfds);
2952 FD_ZERO(&wfds);
2953 FD_ZERO(&xfds);
2954 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2955 if (ioh->deleted)
2956 continue;
2957 if (ioh->fd_read &&
2958 (!ioh->fd_read_poll ||
2959 ioh->fd_read_poll(ioh->opaque) != 0)) {
2960 FD_SET(ioh->fd, &rfds);
2961 if (ioh->fd > nfds)
2962 nfds = ioh->fd;
2963 }
2964 if (ioh->fd_write) {
2965 FD_SET(ioh->fd, &wfds);
2966 if (ioh->fd > nfds)
2967 nfds = ioh->fd;
2968 }
2969 }
2970
2971 tv.tv_sec = timeout / 1000;
2972 tv.tv_usec = (timeout % 1000) * 1000;
2973
2974#if defined(CONFIG_SLIRP)
2975 if (slirp_is_inited()) {
2976 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2977 }
2978#endif
2979 qemu_mutex_unlock_iothread();
2980 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
2981 qemu_mutex_lock_iothread();
2982 if (ret > 0) {
2983 IOHandlerRecord **pioh;
2984
2985 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
2986 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
2987 ioh->fd_read(ioh->opaque);
2988 }
2989 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
2990 ioh->fd_write(ioh->opaque);
2991 }
2992 }
2993
David 'Digit' Turner6b512812010-10-15 15:05:04 +02002994 /* remove deleted IO handlers */
2995 pioh = &first_io_handler;
2996 while (*pioh) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002997 ioh = *pioh;
2998 if (ioh->deleted) {
2999 *pioh = ioh->next;
3000 qemu_free(ioh);
3001 } else
3002 pioh = &ioh->next;
3003 }
3004 }
3005#if defined(CONFIG_SLIRP)
3006 if (slirp_is_inited()) {
3007 if (ret < 0) {
3008 FD_ZERO(&rfds);
3009 FD_ZERO(&wfds);
3010 FD_ZERO(&xfds);
3011 }
3012 slirp_select_poll(&rfds, &wfds, &xfds);
3013 }
3014#endif
3015 charpipe_poll();
3016
David Turner6a9ef172010-09-09 22:54:36 +02003017 qemu_run_all_timers();
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003018
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003019 /* Check bottom-halves last in case any of the earlier events triggered
3020 them. */
3021 qemu_bh_poll();
3022
3023}
3024
3025static int qemu_cpu_exec(CPUState *env)
3026{
3027 int ret;
3028#ifdef CONFIG_PROFILER
3029 int64_t ti;
3030#endif
3031
3032#ifdef CONFIG_PROFILER
3033 ti = profile_getclock();
3034#endif
3035 if (use_icount) {
3036 int64_t count;
3037 int decr;
3038 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3039 env->icount_decr.u16.low = 0;
3040 env->icount_extra = 0;
3041 count = qemu_next_deadline();
3042 count = (count + (1 << icount_time_shift) - 1)
3043 >> icount_time_shift;
3044 qemu_icount += count;
3045 decr = (count > 0xffff) ? 0xffff : count;
3046 count -= decr;
3047 env->icount_decr.u16.low = decr;
3048 env->icount_extra = count;
3049 }
David 'Digit' Turnera577fca2009-10-15 18:18:09 -07003050#ifdef CONFIG_TRACE
3051 if (tbflush_requested) {
3052 tbflush_requested = 0;
3053 tb_flush(env);
3054 return EXCP_INTERRUPT;
3055 }
3056#endif
3057
3058
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003059 ret = cpu_exec(env);
3060#ifdef CONFIG_PROFILER
3061 qemu_time += profile_getclock() - ti;
3062#endif
3063 if (use_icount) {
3064 /* Fold pending instructions back into the
3065 instruction counter, and clear the interrupt flag. */
3066 qemu_icount -= (env->icount_decr.u16.low
3067 + env->icount_extra);
3068 env->icount_decr.u32 = 0;
3069 env->icount_extra = 0;
3070 }
3071 return ret;
3072}
3073
3074static void tcg_cpu_exec(void)
3075{
3076 int ret = 0;
3077
3078 if (next_cpu == NULL)
3079 next_cpu = first_cpu;
3080 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
3081 CPUState *env = cur_cpu = next_cpu;
3082
3083 if (!vm_running)
3084 break;
David 'Digit' Turner6b512812010-10-15 15:05:04 +02003085 if (qemu_timer_alarm_pending()) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003086 break;
3087 }
3088 if (cpu_can_run(env))
3089 ret = qemu_cpu_exec(env);
3090 if (ret == EXCP_DEBUG) {
3091 gdb_set_stop_cpu(env);
3092 debug_requested = 1;
3093 break;
3094 }
3095 }
3096}
3097
3098static int cpu_has_work(CPUState *env)
3099{
3100 if (env->stop)
3101 return 1;
3102 if (env->stopped)
3103 return 0;
3104 if (!env->halted)
3105 return 1;
3106 if (qemu_cpu_has_work(env))
3107 return 1;
3108 return 0;
3109}
3110
David 'Digit' Turner6b512812010-10-15 15:05:04 +02003111int tcg_has_work(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003112{
3113 CPUState *env;
3114
3115 for (env = first_cpu; env != NULL; env = env->next_cpu)
3116 if (cpu_has_work(env))
3117 return 1;
3118 return 0;
3119}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003120
3121static int vm_can_run(void)
3122{
3123 if (powerdown_requested)
3124 return 0;
3125 if (reset_requested)
3126 return 0;
3127 if (shutdown_requested)
3128 return 0;
3129 if (debug_requested)
3130 return 0;
3131 return 1;
3132}
3133
3134static void main_loop(void)
3135{
3136 int r;
3137
3138#ifdef CONFIG_IOTHREAD
3139 qemu_system_ready = 1;
3140 qemu_cond_broadcast(&qemu_system_cond);
3141#endif
3142
3143 for (;;) {
3144 do {
3145#ifdef CONFIG_PROFILER
3146 int64_t ti;
3147#endif
3148#ifndef CONFIG_IOTHREAD
3149 tcg_cpu_exec();
3150#endif
3151#ifdef CONFIG_PROFILER
3152 ti = profile_getclock();
3153#endif
3154 main_loop_wait(qemu_calculate_timeout());
3155#ifdef CONFIG_PROFILER
3156 dev_time += profile_getclock() - ti;
3157#endif
3158 } while (vm_can_run());
3159
3160 if (qemu_debug_requested())
3161 vm_stop(EXCP_DEBUG);
3162 if (qemu_shutdown_requested()) {
3163 if (no_shutdown) {
3164 vm_stop(0);
3165 no_shutdown = 0;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003166 } else {
3167#if CONFIG_ANDROID_SNAPSHOTS
3168 if (savevm_on_exit != NULL) {
3169 do_savevm(cur_mon, savevm_on_exit);
3170 }
3171#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003172 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003173 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003174 }
3175 if (qemu_reset_requested()) {
3176 pause_all_vcpus();
3177 qemu_system_reset();
3178 resume_all_vcpus();
3179 }
3180 if (qemu_powerdown_requested())
3181 qemu_system_powerdown();
3182 if ((r = qemu_vmstop_requested()))
3183 vm_stop(r);
3184 }
3185 pause_all_vcpus();
3186}
3187
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003188void version(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003189{
3190 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3191}
3192
3193void qemu_help(int exitcode)
3194{
3195 version();
3196 printf("usage: %s [options] [disk_image]\n"
3197 "\n"
3198 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
3199 "\n"
3200#define DEF(option, opt_arg, opt_enum, opt_help) \
3201 opt_help
3202#define DEFHEADING(text) stringify(text) "\n"
3203#include "qemu-options.h"
3204#undef DEF
3205#undef DEFHEADING
3206#undef GEN_DOCS
3207 "\n"
3208 "During emulation, the following keys are useful:\n"
3209 "ctrl-alt-f toggle full screen\n"
3210 "ctrl-alt-n switch to virtual console 'n'\n"
3211 "ctrl-alt toggle mouse and keyboard grab\n"
3212 "\n"
3213 "When using -nographic, press 'ctrl-a h' to get some help.\n"
3214 ,
3215 "qemu",
3216 DEFAULT_RAM_SIZE,
3217#ifndef _WIN32
3218 DEFAULT_NETWORK_SCRIPT,
3219 DEFAULT_NETWORK_DOWN_SCRIPT,
3220#endif
3221 DEFAULT_GDBSTUB_PORT,
3222 "/tmp/qemu.log");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003223 QEMU_EXIT(exitcode);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003224}
3225
3226#define HAS_ARG 0x0001
3227
3228enum {
3229#define DEF(option, opt_arg, opt_enum, opt_help) \
3230 opt_enum,
3231#define DEFHEADING(text)
3232#include "qemu-options.h"
3233#undef DEF
3234#undef DEFHEADING
3235#undef GEN_DOCS
3236};
3237
3238typedef struct QEMUOption {
3239 const char *name;
3240 int flags;
3241 int index;
3242} QEMUOption;
3243
3244static const QEMUOption qemu_options[] = {
3245 { "h", 0, QEMU_OPTION_h },
3246#define DEF(option, opt_arg, opt_enum, opt_help) \
3247 { option, opt_arg, opt_enum },
3248#define DEFHEADING(text)
3249#include "qemu-options.h"
3250#undef DEF
3251#undef DEFHEADING
3252#undef GEN_DOCS
3253 { NULL, 0, 0 },
3254};
3255
3256#ifdef HAS_AUDIO
3257struct soundhw soundhw[] = {
3258#ifdef HAS_AUDIO_CHOICE
3259#if defined(TARGET_I386) || defined(TARGET_MIPS)
3260 {
3261 "pcspk",
3262 "PC speaker",
3263 0,
3264 1,
3265 { .init_isa = pcspk_audio_init }
3266 },
3267#endif
3268
3269#ifdef CONFIG_SB16
3270 {
3271 "sb16",
3272 "Creative Sound Blaster 16",
3273 0,
3274 1,
3275 { .init_isa = SB16_init }
3276 },
3277#endif
3278
3279#ifdef CONFIG_CS4231A
3280 {
3281 "cs4231a",
3282 "CS4231A",
3283 0,
3284 1,
3285 { .init_isa = cs4231a_init }
3286 },
3287#endif
3288
3289#ifdef CONFIG_ADLIB
3290 {
3291 "adlib",
3292#ifdef HAS_YMF262
3293 "Yamaha YMF262 (OPL3)",
3294#else
3295 "Yamaha YM3812 (OPL2)",
3296#endif
3297 0,
3298 1,
3299 { .init_isa = Adlib_init }
3300 },
3301#endif
3302
3303#ifdef CONFIG_GUS
3304 {
3305 "gus",
3306 "Gravis Ultrasound GF1",
3307 0,
3308 1,
3309 { .init_isa = GUS_init }
3310 },
3311#endif
3312
3313#ifdef CONFIG_AC97
3314 {
3315 "ac97",
3316 "Intel 82801AA AC97 Audio",
3317 0,
3318 0,
3319 { .init_pci = ac97_init }
3320 },
3321#endif
3322
3323#ifdef CONFIG_ES1370
3324 {
3325 "es1370",
3326 "ENSONIQ AudioPCI ES1370",
3327 0,
3328 0,
3329 { .init_pci = es1370_init }
3330 },
3331#endif
3332
3333#endif /* HAS_AUDIO_CHOICE */
3334
3335 { NULL, NULL, 0, 0, { NULL } }
3336};
3337
3338static void select_soundhw (const char *optarg)
3339{
3340 struct soundhw *c;
3341
3342 if (*optarg == '?') {
3343 show_valid_cards:
3344
3345 printf ("Valid sound card names (comma separated):\n");
3346 for (c = soundhw; c->name; ++c) {
3347 printf ("%-11s %s\n", c->name, c->descr);
3348 }
3349 printf ("\n-soundhw all will enable all of the above\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003350 if (*optarg != '?') {
3351 PANIC("Unknown sound card name: %s", optarg);
3352 } else {
3353 QEMU_EXIT(0);
3354 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003355 }
3356 else {
3357 size_t l;
3358 const char *p;
3359 char *e;
3360 int bad_card = 0;
3361
3362 if (!strcmp (optarg, "all")) {
3363 for (c = soundhw; c->name; ++c) {
3364 c->enabled = 1;
3365 }
3366 return;
3367 }
3368
3369 p = optarg;
3370 while (*p) {
3371 e = strchr (p, ',');
3372 l = !e ? strlen (p) : (size_t) (e - p);
3373
3374 for (c = soundhw; c->name; ++c) {
3375 if (!strncmp (c->name, p, l)) {
3376 c->enabled = 1;
3377 break;
3378 }
3379 }
3380
3381 if (!c->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003382#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003383 if (l > 80) {
3384 fprintf (stderr,
3385 "Unknown sound card name (too big to show)\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003386 } else {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003387 fprintf (stderr, "Unknown sound card name `%.*s'\n",
3388 (int) l, p);
3389 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003390#endif // !CONFIG_ANDROID
3391 bad_card = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003392 }
3393 p += l + (e != NULL);
3394 }
3395
3396 if (bad_card)
3397 goto show_valid_cards;
3398 }
3399}
3400#endif
3401
3402static void select_vgahw (const char *p)
3403{
3404 const char *opts;
3405
3406 cirrus_vga_enabled = 0;
3407 std_vga_enabled = 0;
3408 vmsvga_enabled = 0;
3409 xenfb_enabled = 0;
3410 if (strstart(p, "std", &opts)) {
3411 std_vga_enabled = 1;
3412 } else if (strstart(p, "cirrus", &opts)) {
3413 cirrus_vga_enabled = 1;
3414 } else if (strstart(p, "vmware", &opts)) {
3415 vmsvga_enabled = 1;
3416 } else if (strstart(p, "xenfb", &opts)) {
3417 xenfb_enabled = 1;
3418 } else if (!strstart(p, "none", &opts)) {
3419 invalid_vga:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003420 PANIC("Unknown vga type: %s", p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003421 }
3422 while (*opts) {
3423 const char *nextopt;
3424
3425 if (strstart(opts, ",retrace=", &nextopt)) {
3426 opts = nextopt;
3427 if (strstart(opts, "dumb", &nextopt))
3428 vga_retrace_method = VGA_RETRACE_DUMB;
3429 else if (strstart(opts, "precise", &nextopt))
3430 vga_retrace_method = VGA_RETRACE_PRECISE;
3431 else goto invalid_vga;
3432 } else goto invalid_vga;
3433 opts = nextopt;
3434 }
3435}
3436
3437#ifdef _WIN32
3438static BOOL WINAPI qemu_ctrl_handler(DWORD type)
3439{
3440 exit(STATUS_CONTROL_C_EXIT);
3441 return TRUE;
3442}
3443#endif
3444
3445int qemu_uuid_parse(const char *str, uint8_t *uuid)
3446{
3447 int ret;
3448
3449 if(strlen(str) != 36)
3450 return -1;
3451
3452 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
3453 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
3454 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
3455
3456 if(ret != 16)
3457 return -1;
3458
3459#ifdef TARGET_I386
3460 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
3461#endif
3462
3463 return 0;
3464}
3465
3466#define MAX_NET_CLIENTS 32
3467
3468#ifndef _WIN32
3469
3470static void termsig_handler(int signal)
3471{
3472 qemu_system_shutdown_request();
3473}
3474
3475static void sigchld_handler(int signal)
3476{
3477 waitpid(-1, NULL, WNOHANG);
3478}
3479
3480static void sighandler_setup(void)
3481{
3482 struct sigaction act;
3483
3484 memset(&act, 0, sizeof(act));
3485 act.sa_handler = termsig_handler;
3486 sigaction(SIGINT, &act, NULL);
3487 sigaction(SIGHUP, &act, NULL);
3488 sigaction(SIGTERM, &act, NULL);
3489
3490 act.sa_handler = sigchld_handler;
3491 act.sa_flags = SA_NOCLDSTOP;
3492 sigaction(SIGCHLD, &act, NULL);
3493}
3494
3495#endif
3496
3497#ifdef _WIN32
3498/* Look for support files in the same directory as the executable. */
3499static char *find_datadir(const char *argv0)
3500{
3501 char *p;
3502 char buf[MAX_PATH];
3503 DWORD len;
3504
3505 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
3506 if (len == 0) {
3507 return NULL;
3508 }
3509
3510 buf[len] = 0;
3511 p = buf + len - 1;
3512 while (p != buf && *p != '\\')
3513 p--;
3514 *p = 0;
3515 if (access(buf, R_OK) == 0) {
3516 return qemu_strdup(buf);
3517 }
3518 return NULL;
3519}
3520#else /* !_WIN32 */
3521
3522/* Find a likely location for support files using the location of the binary.
3523 For installed binaries this will be "$bindir/../share/qemu". When
3524 running from the build tree this will be "$bindir/../pc-bios". */
3525#define SHARE_SUFFIX "/share/qemu"
3526#define BUILD_SUFFIX "/pc-bios"
3527static char *find_datadir(const char *argv0)
3528{
3529 char *dir;
3530 char *p = NULL;
3531 char *res;
3532#ifdef PATH_MAX
3533 char buf[PATH_MAX];
3534#endif
3535 size_t max_len;
3536
3537#if defined(__linux__)
3538 {
3539 int len;
3540 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
3541 if (len > 0) {
3542 buf[len] = 0;
3543 p = buf;
3544 }
3545 }
3546#elif defined(__FreeBSD__)
3547 {
3548 int len;
3549 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
3550 if (len > 0) {
3551 buf[len] = 0;
3552 p = buf;
3553 }
3554 }
3555#endif
3556 /* If we don't have any way of figuring out the actual executable
3557 location then try argv[0]. */
3558 if (!p) {
3559#ifdef PATH_MAX
3560 p = buf;
3561#endif
3562 p = realpath(argv0, p);
3563 if (!p) {
3564 return NULL;
3565 }
3566 }
3567 dir = dirname(p);
3568 dir = dirname(dir);
3569
3570 max_len = strlen(dir) +
3571 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
3572 res = qemu_mallocz(max_len);
3573 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
3574 if (access(res, R_OK)) {
3575 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
3576 if (access(res, R_OK)) {
3577 qemu_free(res);
3578 res = NULL;
3579 }
3580 }
3581#ifndef PATH_MAX
3582 free(p);
3583#endif
3584 return res;
3585}
3586#undef SHARE_SUFFIX
3587#undef BUILD_SUFFIX
3588#endif
3589
3590char *qemu_find_file(int type, const char *name)
3591{
3592 int len;
3593 const char *subdir;
3594 char *buf;
3595
3596 /* If name contains path separators then try it as a straight path. */
3597 if ((strchr(name, '/') || strchr(name, '\\'))
3598 && access(name, R_OK) == 0) {
3599 return strdup(name);
3600 }
3601 switch (type) {
3602 case QEMU_FILE_TYPE_BIOS:
3603 subdir = "";
3604 break;
3605 case QEMU_FILE_TYPE_KEYMAP:
3606 subdir = "keymaps/";
3607 break;
3608 default:
3609 abort();
3610 }
3611 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
3612 buf = qemu_mallocz(len);
3613 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
3614 if (access(buf, R_OK)) {
3615 qemu_free(buf);
3616 return NULL;
3617 }
3618 return buf;
3619}
3620
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003621static int
3622add_dns_server( const char* server_name )
3623{
3624 SockAddress addr;
3625
3626 if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
3627 fprintf(stdout,
3628 "### WARNING: can't resolve DNS server name '%s'\n",
3629 server_name );
3630 return -1;
3631 }
3632
3633 fprintf(stderr,
3634 "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
3635
3636 if ( slirp_add_dns_server( &addr ) < 0 ) {
3637 fprintf(stderr,
3638 "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
3639 return -1;
3640 }
3641 return 0;
3642}
3643
3644/* Appends a parameter to a string of parameters separated with space.
3645 * Pararm:
3646 * param_str String containing parameters separated with space.
3647 * param Parameter to append to the string.
3648 * size - Size (in characters) of the buffer addressed by param_str.
3649 */
3650static void
3651append_param(char* param_str, const char* arg, int size)
3652{
3653 if (*param_str) {
3654 strncat(param_str, " ", size);
3655 strncat(param_str, arg, size);
3656 } else {
3657 strncpy(param_str, arg, size);
3658 param_str[size - 1] = '\0';
3659 }
3660}
3661
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003662int main(int argc, char **argv, char **envp)
3663{
3664 const char *gdbstub_dev = NULL;
3665 uint32_t boot_devices_bitmap = 0;
3666 int i;
3667 int snapshot, linux_boot, net_boot;
David Turner6a9ef172010-09-09 22:54:36 +02003668 const char *icount_option = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003669 const char *initrd_filename;
3670 const char *kernel_filename, *kernel_cmdline;
3671 const char *boot_devices = "";
3672 DisplayState *ds;
3673 DisplayChangeListener *dcl;
3674 int cyls, heads, secs, translation;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003675 QemuOpts *hda_opts = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003676 const char *net_clients[MAX_NET_CLIENTS];
3677 int nb_net_clients;
3678 const char *bt_opts[MAX_BT_CMDLINE];
3679 int nb_bt_opts;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003680 int optind;
3681 const char *r, *optarg;
3682 CharDriverState *monitor_hd = NULL;
3683 const char *monitor_device;
3684 const char *serial_devices[MAX_SERIAL_PORTS];
3685 int serial_device_index;
3686 const char *parallel_devices[MAX_PARALLEL_PORTS];
3687 int parallel_device_index;
3688 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
3689 int virtio_console_index;
3690 const char *loadvm = NULL;
3691 QEMUMachine *machine;
3692 const char *cpu_model;
3693 const char *usb_devices[MAX_USB_CMDLINE];
3694 int usb_devices_index;
3695#ifndef _WIN32
3696 int fds[2];
3697#endif
3698 int tb_size;
3699 const char *pid_file = NULL;
3700 const char *incoming = NULL;
3701#ifndef _WIN32
3702 int fd = 0;
3703 struct passwd *pwd = NULL;
3704 const char *chroot_dir = NULL;
3705 const char *run_as = NULL;
3706#endif
3707 CPUState *env;
3708 int show_vnc_port = 0;
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07003709#ifdef CONFIG_STANDALONE_CORE
3710 IniFile* hw_ini = NULL;
3711#endif // CONFIG_STANDALONE_CORE
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003712 /* Container for the kernel initialization parameters collected in this
3713 * routine. */
3714 char kernel_cmdline_append[1024];
3715 /* Combines kernel initialization parameters passed from the UI with
3716 * the parameters collected in this routine. */
3717 char kernel_cmdline_full[1024];
3718 char tmp_str[1024];
3719 int dns_count = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003720
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003721 /* Initialize sockets before anything else, so we can properly report
3722 * initialization failures back to the UI. */
3723#ifdef _WIN32
3724 socket_init();
3725#endif
3726
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003727 init_clocks();
3728
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003729 qemu_cache_utils_init(envp);
3730
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07003731 QLIST_INIT (&vm_change_state_head);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003732#ifndef _WIN32
3733 {
3734 struct sigaction act;
3735 sigfillset(&act.sa_mask);
3736 act.sa_flags = 0;
3737 act.sa_handler = SIG_IGN;
3738 sigaction(SIGPIPE, &act, NULL);
3739 }
3740#else
3741 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
3742 /* Note: cpu_interrupt() is currently not SMP safe, so we force
3743 QEMU to run on a single CPU */
3744 {
3745 HANDLE h;
3746 DWORD mask, smask;
3747 int i;
3748 h = GetCurrentProcess();
3749 if (GetProcessAffinityMask(h, &mask, &smask)) {
3750 for(i = 0; i < 32; i++) {
3751 if (mask & (1 << i))
3752 break;
3753 }
3754 if (i != 32) {
3755 mask = 1 << i;
3756 SetProcessAffinityMask(h, mask);
3757 }
3758 }
3759 }
3760#endif
3761
3762 module_call_init(MODULE_INIT_MACHINE);
3763 machine = find_default_machine();
3764 cpu_model = NULL;
3765 initrd_filename = NULL;
3766 ram_size = 0;
3767 snapshot = 0;
3768 kernel_filename = NULL;
3769 kernel_cmdline = "";
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003770 kernel_cmdline_append[0] = '\0';
3771 kernel_cmdline_full[0] = '\0';
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003772 cyls = heads = secs = 0;
3773 translation = BIOS_ATA_TRANSLATION_AUTO;
3774 monitor_device = "vc:80Cx24C";
3775
3776 serial_devices[0] = "vc:80Cx24C";
3777 for(i = 1; i < MAX_SERIAL_PORTS; i++)
3778 serial_devices[i] = NULL;
3779 serial_device_index = 0;
3780
3781 parallel_devices[0] = "vc:80Cx24C";
3782 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3783 parallel_devices[i] = NULL;
3784 parallel_device_index = 0;
3785
3786 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
3787 virtio_consoles[i] = NULL;
3788 virtio_console_index = 0;
3789
3790 for (i = 0; i < MAX_NODES; i++) {
3791 node_mem[i] = 0;
3792 node_cpumask[i] = 0;
3793 }
3794
3795 usb_devices_index = 0;
3796
3797 nb_net_clients = 0;
3798 nb_bt_opts = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003799#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003800 nb_drives = 0;
3801 nb_drives_opt = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003802#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003803 nb_numa_nodes = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003804
3805 nb_nics = 0;
3806
3807 tb_size = 0;
3808 autostart= 1;
3809
3810 register_watchdogs();
3811
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07003812 /* Initialize boot properties. */
3813 boot_property_init_service();
3814
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003815 optind = 1;
3816 for(;;) {
3817 if (optind >= argc)
3818 break;
3819 r = argv[optind];
3820 if (r[0] != '-') {
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003821 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003822 } else {
3823 const QEMUOption *popt;
3824
3825 optind++;
3826 /* Treat --foo the same as -foo. */
3827 if (r[1] == '-')
3828 r++;
3829 popt = qemu_options;
3830 for(;;) {
3831 if (!popt->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003832 PANIC("%s: invalid option -- '%s'",
3833 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003834 }
3835 if (!strcmp(popt->name, r + 1))
3836 break;
3837 popt++;
3838 }
3839 if (popt->flags & HAS_ARG) {
3840 if (optind >= argc) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003841 PANIC("%s: option '%s' requires an argument",
3842 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003843 }
3844 optarg = argv[optind++];
3845 } else {
3846 optarg = NULL;
3847 }
3848
3849 switch(popt->index) {
3850 case QEMU_OPTION_M:
3851 machine = find_machine(optarg);
3852 if (!machine) {
3853 QEMUMachine *m;
3854 printf("Supported machines are:\n");
3855 for(m = first_machine; m != NULL; m = m->next) {
3856 printf("%-10s %s%s\n",
3857 m->name, m->desc,
3858 m->is_default ? " (default)" : "");
3859 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003860 if (*optarg != '?') {
3861 PANIC("Invalid machine parameter: %s",
3862 optarg);
3863 } else {
3864 QEMU_EXIT(0);
3865 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003866 }
3867 break;
3868 case QEMU_OPTION_cpu:
3869 /* hw initialization will check this */
3870 if (*optarg == '?') {
3871/* XXX: implement xxx_cpu_list for targets that still miss it */
3872#if defined(cpu_list)
3873 cpu_list(stdout, &fprintf);
3874#endif
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003875 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003876 } else {
3877 cpu_model = optarg;
3878 }
3879 break;
3880 case QEMU_OPTION_initrd:
3881 initrd_filename = optarg;
3882 break;
3883 case QEMU_OPTION_hda:
3884 if (cyls == 0)
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003885 hda_opts = drive_add(optarg, HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003886 else
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003887 hda_opts = drive_add(optarg, HD_ALIAS
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003888 ",cyls=%d,heads=%d,secs=%d%s",
3889 0, cyls, heads, secs,
3890 translation == BIOS_ATA_TRANSLATION_LBA ?
3891 ",trans=lba" :
3892 translation == BIOS_ATA_TRANSLATION_NONE ?
3893 ",trans=none" : "");
3894 break;
3895 case QEMU_OPTION_hdb:
3896 case QEMU_OPTION_hdc:
3897 case QEMU_OPTION_hdd:
3898 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
3899 break;
3900 case QEMU_OPTION_drive:
3901 drive_add(NULL, "%s", optarg);
3902 break;
3903 case QEMU_OPTION_mtdblock:
3904 drive_add(optarg, MTD_ALIAS);
3905 break;
3906 case QEMU_OPTION_sd:
3907 drive_add(optarg, SD_ALIAS);
3908 break;
3909 case QEMU_OPTION_pflash:
3910 drive_add(optarg, PFLASH_ALIAS);
3911 break;
3912 case QEMU_OPTION_snapshot:
3913 snapshot = 1;
3914 break;
3915 case QEMU_OPTION_hdachs:
3916 {
3917 const char *p;
3918 p = optarg;
3919 cyls = strtol(p, (char **)&p, 0);
3920 if (cyls < 1 || cyls > 16383)
3921 goto chs_fail;
3922 if (*p != ',')
3923 goto chs_fail;
3924 p++;
3925 heads = strtol(p, (char **)&p, 0);
3926 if (heads < 1 || heads > 16)
3927 goto chs_fail;
3928 if (*p != ',')
3929 goto chs_fail;
3930 p++;
3931 secs = strtol(p, (char **)&p, 0);
3932 if (secs < 1 || secs > 63)
3933 goto chs_fail;
3934 if (*p == ',') {
3935 p++;
3936 if (!strcmp(p, "none"))
3937 translation = BIOS_ATA_TRANSLATION_NONE;
3938 else if (!strcmp(p, "lba"))
3939 translation = BIOS_ATA_TRANSLATION_LBA;
3940 else if (!strcmp(p, "auto"))
3941 translation = BIOS_ATA_TRANSLATION_AUTO;
3942 else
3943 goto chs_fail;
3944 } else if (*p != '\0') {
3945 chs_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003946 PANIC("qemu: invalid physical CHS format");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003947 }
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003948 if (hda_opts != NULL) {
3949 char num[16];
3950 snprintf(num, sizeof(num), "%d", cyls);
3951 qemu_opt_set(hda_opts, "cyls", num);
3952 snprintf(num, sizeof(num), "%d", heads);
3953 qemu_opt_set(hda_opts, "heads", num);
3954 snprintf(num, sizeof(num), "%d", secs);
3955 qemu_opt_set(hda_opts, "secs", num);
3956 if (translation == BIOS_ATA_TRANSLATION_LBA)
3957 qemu_opt_set(hda_opts, "trans", "lba");
3958 if (translation == BIOS_ATA_TRANSLATION_NONE)
3959 qemu_opt_set(hda_opts, "trans", "none");
3960 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003961 }
3962 break;
3963 case QEMU_OPTION_numa:
3964 if (nb_numa_nodes >= MAX_NODES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003965 PANIC("qemu: too many NUMA nodes");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003966 }
3967 numa_add(optarg);
3968 break;
3969 case QEMU_OPTION_nographic:
3970 display_type = DT_NOGRAPHIC;
3971 break;
3972#ifdef CONFIG_CURSES
3973 case QEMU_OPTION_curses:
3974 display_type = DT_CURSES;
3975 break;
3976#endif
3977 case QEMU_OPTION_portrait:
3978 graphic_rotate = 1;
3979 break;
3980 case QEMU_OPTION_kernel:
3981 kernel_filename = optarg;
3982 break;
3983 case QEMU_OPTION_append:
3984 kernel_cmdline = optarg;
3985 break;
3986 case QEMU_OPTION_cdrom:
3987 drive_add(optarg, CDROM_ALIAS);
3988 break;
3989 case QEMU_OPTION_boot:
3990 boot_devices = optarg;
3991 /* We just do some generic consistency checks */
3992 {
3993 /* Could easily be extended to 64 devices if needed */
3994 const char *p;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07003995
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003996 boot_devices_bitmap = 0;
3997 for (p = boot_devices; *p != '\0'; p++) {
3998 /* Allowed boot devices are:
3999 * a b : floppy disk drives
4000 * c ... f : IDE disk drives
4001 * g ... m : machine implementation dependant drives
4002 * n ... p : network devices
4003 * It's up to each machine implementation to check
4004 * if the given boot devices match the actual hardware
4005 * implementation and firmware features.
4006 */
4007 if (*p < 'a' || *p > 'q') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004008 PANIC("Invalid boot device '%c'", *p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004009 }
4010 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004011 PANIC(
4012 "Boot device '%c' was given twice",*p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004013 }
4014 boot_devices_bitmap |= 1 << (*p - 'a');
4015 }
4016 }
4017 break;
4018 case QEMU_OPTION_fda:
4019 case QEMU_OPTION_fdb:
4020 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
4021 break;
4022#ifdef TARGET_I386
4023 case QEMU_OPTION_no_fd_bootchk:
4024 fd_bootchk = 0;
4025 break;
4026#endif
4027 case QEMU_OPTION_net:
4028 if (nb_net_clients >= MAX_NET_CLIENTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004029 PANIC("qemu: too many network clients");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004030 }
4031 net_clients[nb_net_clients] = optarg;
4032 nb_net_clients++;
4033 break;
4034#ifdef CONFIG_SLIRP
4035 case QEMU_OPTION_tftp:
4036 tftp_prefix = optarg;
4037 break;
4038 case QEMU_OPTION_bootp:
4039 bootp_filename = optarg;
4040 break;
4041#if 0 /* ANDROID disabled */
4042#ifndef _WIN32
4043 case QEMU_OPTION_smb:
4044 net_slirp_smb(optarg);
4045 break;
4046#endif
4047#endif /* ANDROID */
4048 case QEMU_OPTION_redir:
4049 net_slirp_redir(NULL, optarg, NULL);
4050 break;
4051#endif
4052 case QEMU_OPTION_bt:
4053 if (nb_bt_opts >= MAX_BT_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004054 PANIC("qemu: too many bluetooth options");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004055 }
4056 bt_opts[nb_bt_opts++] = optarg;
4057 break;
4058#ifdef HAS_AUDIO
4059 case QEMU_OPTION_audio_help:
4060 AUD_help ();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004061 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004062 break;
4063 case QEMU_OPTION_soundhw:
4064 select_soundhw (optarg);
4065 break;
4066#endif
4067 case QEMU_OPTION_h:
4068 qemu_help(0);
4069 break;
4070 case QEMU_OPTION_version:
4071 version();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004072 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004073 break;
4074 case QEMU_OPTION_m: {
4075 uint64_t value;
4076 char *ptr;
4077
4078 value = strtoul(optarg, &ptr, 10);
4079 switch (*ptr) {
4080 case 0: case 'M': case 'm':
4081 value <<= 20;
4082 break;
4083 case 'G': case 'g':
4084 value <<= 30;
4085 break;
4086 default:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004087 PANIC("qemu: invalid ram size: %s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004088 }
4089
4090 /* On 32-bit hosts, QEMU is limited by virtual address space */
4091 if (value > (2047 << 20)
4092#ifndef CONFIG_KQEMU
4093 && HOST_LONG_BITS == 32
4094#endif
4095 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004096 PANIC("qemu: at most 2047 MB RAM can be simulated");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004097 }
4098 if (value != (uint64_t)(ram_addr_t)value) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004099 PANIC("qemu: ram size too large");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004100 }
4101 ram_size = value;
4102 break;
4103 }
4104 case QEMU_OPTION_d:
4105 {
4106 int mask;
4107 const CPULogItem *item;
4108
4109 mask = cpu_str_to_log_mask(optarg);
4110 if (!mask) {
4111 printf("Log items (comma separated):\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004112 for(item = cpu_log_items; item->mask != 0; item++) {
4113 printf("%-10s %s\n", item->name, item->help);
4114 }
4115 PANIC("Invalid parameter -d=%s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004116 }
4117 cpu_set_log(mask);
4118 }
4119 break;
4120 case QEMU_OPTION_s:
4121 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
4122 break;
4123 case QEMU_OPTION_gdb:
4124 gdbstub_dev = optarg;
4125 break;
4126 case QEMU_OPTION_L:
4127 data_dir = optarg;
4128 break;
4129 case QEMU_OPTION_bios:
4130 bios_name = optarg;
4131 break;
4132 case QEMU_OPTION_singlestep:
4133 singlestep = 1;
4134 break;
4135 case QEMU_OPTION_S:
4136#if 0 /* ANDROID */
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004137 PANIC("Sorry, stopped launch is not supported in the Android emulator" );
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004138#endif
4139 autostart = 0;
4140 break;
4141#ifndef _WIN32
4142 case QEMU_OPTION_k:
4143 keyboard_layout = optarg;
4144 break;
4145#endif
4146 case QEMU_OPTION_localtime:
4147 rtc_utc = 0;
4148 break;
4149 case QEMU_OPTION_vga:
4150 select_vgahw (optarg);
4151 break;
4152#if defined(TARGET_PPC) || defined(TARGET_SPARC)
4153 case QEMU_OPTION_g:
4154 {
4155 const char *p;
4156 int w, h, depth;
4157 p = optarg;
4158 w = strtol(p, (char **)&p, 10);
4159 if (w <= 0) {
4160 graphic_error:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004161 PANIC("qemu: invalid resolution or depth");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004162 }
4163 if (*p != 'x')
4164 goto graphic_error;
4165 p++;
4166 h = strtol(p, (char **)&p, 10);
4167 if (h <= 0)
4168 goto graphic_error;
4169 if (*p == 'x') {
4170 p++;
4171 depth = strtol(p, (char **)&p, 10);
4172 if (depth != 8 && depth != 15 && depth != 16 &&
4173 depth != 24 && depth != 32)
4174 goto graphic_error;
4175 } else if (*p == '\0') {
4176 depth = graphic_depth;
4177 } else {
4178 goto graphic_error;
4179 }
4180
4181 graphic_width = w;
4182 graphic_height = h;
4183 graphic_depth = depth;
4184 }
4185 break;
4186#endif
4187 case QEMU_OPTION_echr:
4188 {
4189 char *r;
4190 term_escape_char = strtol(optarg, &r, 0);
4191 if (r == optarg)
4192 printf("Bad argument to echr\n");
4193 break;
4194 }
4195 case QEMU_OPTION_monitor:
4196 monitor_device = optarg;
4197 break;
4198 case QEMU_OPTION_serial:
4199 if (serial_device_index >= MAX_SERIAL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004200 PANIC("qemu: too many serial ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004201 }
4202 serial_devices[serial_device_index] = optarg;
4203 serial_device_index++;
4204 break;
4205 case QEMU_OPTION_watchdog:
4206 i = select_watchdog(optarg);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004207 if (i > 0) {
4208 if (i == 1) {
4209 PANIC("Invalid watchdog parameter: %s",
4210 optarg);
4211 } else {
4212 QEMU_EXIT(0);
4213 }
4214 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004215 break;
4216 case QEMU_OPTION_watchdog_action:
4217 if (select_watchdog_action(optarg) == -1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004218 PANIC("Unknown -watchdog-action parameter");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004219 }
4220 break;
4221 case QEMU_OPTION_virtiocon:
4222 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004223 PANIC("qemu: too many virtio consoles");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004224 }
4225 virtio_consoles[virtio_console_index] = optarg;
4226 virtio_console_index++;
4227 break;
4228 case QEMU_OPTION_parallel:
4229 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004230 PANIC("qemu: too many parallel ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004231 }
4232 parallel_devices[parallel_device_index] = optarg;
4233 parallel_device_index++;
4234 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00004235 case QEMU_OPTION_loadvm:
4236 loadvm = optarg;
4237 break;
4238#if CONFIG_ANDROID_SNAPSHOTS
4239 case QEMU_OPTION_savevm_on_exit:
4240 savevm_on_exit = optarg;
4241 break;
4242#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004243 case QEMU_OPTION_full_screen:
4244 full_screen = 1;
4245 break;
4246#ifdef CONFIG_SDL
4247 case QEMU_OPTION_no_frame:
4248 no_frame = 1;
4249 break;
4250 case QEMU_OPTION_alt_grab:
4251 alt_grab = 1;
4252 break;
4253 case QEMU_OPTION_no_quit:
4254 no_quit = 1;
4255 break;
4256 case QEMU_OPTION_sdl:
4257 display_type = DT_SDL;
4258 break;
4259#endif
4260 case QEMU_OPTION_pidfile:
4261 pid_file = optarg;
4262 break;
4263#ifdef TARGET_I386
4264 case QEMU_OPTION_win2k_hack:
4265 win2k_install_hack = 1;
4266 break;
4267 case QEMU_OPTION_rtc_td_hack:
4268 rtc_td_hack = 1;
4269 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08004270#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004271 case QEMU_OPTION_acpitable:
4272 if(acpi_table_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004273 PANIC("Wrong acpi table provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004274 }
4275 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08004276#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004277 case QEMU_OPTION_smbios:
4278 if(smbios_entry_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004279 PANIC("Wrong smbios provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004280 }
4281 break;
4282#endif
4283#ifdef CONFIG_KQEMU
4284 case QEMU_OPTION_no_kqemu:
4285 kqemu_allowed = 0;
4286 break;
4287 case QEMU_OPTION_kernel_kqemu:
4288 kqemu_allowed = 2;
4289 break;
4290#endif
4291#ifdef CONFIG_KVM
4292 case QEMU_OPTION_enable_kvm:
4293 kvm_allowed = 1;
4294#ifdef CONFIG_KQEMU
4295 kqemu_allowed = 0;
4296#endif
4297 break;
4298#endif
4299 case QEMU_OPTION_usb:
4300 usb_enabled = 1;
4301 break;
4302 case QEMU_OPTION_usbdevice:
4303 usb_enabled = 1;
4304 if (usb_devices_index >= MAX_USB_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004305 PANIC("Too many USB devices");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004306 }
4307 usb_devices[usb_devices_index] = optarg;
4308 usb_devices_index++;
4309 break;
4310 case QEMU_OPTION_smp:
4311 smp_cpus = atoi(optarg);
4312 if (smp_cpus < 1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004313 PANIC("Invalid number of CPUs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004314 }
4315 break;
4316 case QEMU_OPTION_vnc:
4317 display_type = DT_VNC;
4318 vnc_display = optarg;
4319 break;
4320#ifdef TARGET_I386
4321 case QEMU_OPTION_no_acpi:
4322 acpi_enabled = 0;
4323 break;
4324 case QEMU_OPTION_no_hpet:
4325 no_hpet = 1;
4326 break;
4327 case QEMU_OPTION_no_virtio_balloon:
4328 no_virtio_balloon = 1;
4329 break;
4330#endif
4331 case QEMU_OPTION_no_reboot:
4332 no_reboot = 1;
4333 break;
4334 case QEMU_OPTION_no_shutdown:
4335 no_shutdown = 1;
4336 break;
4337 case QEMU_OPTION_show_cursor:
4338 cursor_hide = 0;
4339 break;
4340 case QEMU_OPTION_uuid:
4341 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004342 PANIC("Fail to parse UUID string. Wrong format.");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004343 }
4344 break;
4345#ifndef _WIN32
4346 case QEMU_OPTION_daemonize:
4347 daemonize = 1;
4348 break;
4349#endif
4350 case QEMU_OPTION_option_rom:
4351 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004352 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004353 }
4354 option_rom[nb_option_roms] = optarg;
4355 nb_option_roms++;
4356 break;
4357#if defined(TARGET_ARM) || defined(TARGET_M68K)
4358 case QEMU_OPTION_semihosting:
4359 semihosting_enabled = 1;
4360 break;
4361#endif
4362 case QEMU_OPTION_name:
4363 qemu_name = optarg;
4364 break;
4365#if defined(TARGET_SPARC) || defined(TARGET_PPC)
4366 case QEMU_OPTION_prom_env:
4367 if (nb_prom_envs >= MAX_PROM_ENVS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004368 PANIC("Too many prom variables");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004369 }
4370 prom_envs[nb_prom_envs] = optarg;
4371 nb_prom_envs++;
4372 break;
4373#endif
4374#ifdef TARGET_ARM
4375 case QEMU_OPTION_old_param:
4376 old_param = 1;
4377 break;
4378#endif
4379 case QEMU_OPTION_clock:
4380 configure_alarms(optarg);
4381 break;
4382 case QEMU_OPTION_startdate:
4383 {
4384 struct tm tm;
David 'Digit' Turnerdc468202010-10-27 02:34:46 +02004385 time_t rtc_start_date = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004386 if (!strcmp(optarg, "now")) {
4387 rtc_date_offset = -1;
4388 } else {
4389 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
4390 &tm.tm_year,
4391 &tm.tm_mon,
4392 &tm.tm_mday,
4393 &tm.tm_hour,
4394 &tm.tm_min,
4395 &tm.tm_sec) == 6) {
4396 /* OK */
4397 } else if (sscanf(optarg, "%d-%d-%d",
4398 &tm.tm_year,
4399 &tm.tm_mon,
4400 &tm.tm_mday) == 3) {
4401 tm.tm_hour = 0;
4402 tm.tm_min = 0;
4403 tm.tm_sec = 0;
4404 } else {
4405 goto date_fail;
4406 }
4407 tm.tm_year -= 1900;
4408 tm.tm_mon--;
4409 rtc_start_date = mktimegm(&tm);
4410 if (rtc_start_date == -1) {
4411 date_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004412 PANIC("Invalid date format. Valid format are:\n"
4413 "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004414 }
4415 rtc_date_offset = time(NULL) - rtc_start_date;
4416 }
4417 }
4418 break;
4419 case QEMU_OPTION_tb_size:
4420 tb_size = strtol(optarg, NULL, 0);
4421 if (tb_size < 0)
4422 tb_size = 0;
4423 break;
4424 case QEMU_OPTION_icount:
David Turner6a9ef172010-09-09 22:54:36 +02004425 icount_option = optarg;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004426 break;
4427 case QEMU_OPTION_incoming:
4428 incoming = optarg;
4429 break;
4430#ifndef _WIN32
4431 case QEMU_OPTION_chroot:
4432 chroot_dir = optarg;
4433 break;
4434 case QEMU_OPTION_runas:
4435 run_as = optarg;
4436 break;
4437#endif
4438#ifdef CONFIG_XEN
4439 case QEMU_OPTION_xen_domid:
4440 xen_domid = atoi(optarg);
4441 break;
4442 case QEMU_OPTION_xen_create:
4443 xen_mode = XEN_CREATE;
4444 break;
4445 case QEMU_OPTION_xen_attach:
4446 xen_mode = XEN_ATTACH;
4447 break;
4448#endif
4449
4450
4451 case QEMU_OPTION_mic:
4452 audio_input_source = (char*)optarg;
4453 break;
4454#ifdef CONFIG_TRACE
David 'Digit' Turnera577fca2009-10-15 18:18:09 -07004455 case QEMU_OPTION_trace:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004456 trace_filename = optarg;
4457 tracing = 1;
4458 break;
4459#if 0
4460 case QEMU_OPTION_trace_miss:
4461 trace_cache_miss = 1;
4462 break;
4463 case QEMU_OPTION_trace_addr:
4464 trace_all_addr = 1;
4465 break;
4466#endif
4467 case QEMU_OPTION_tracing:
4468 if (strcmp(optarg, "off") == 0)
4469 tracing = 0;
4470 else if (strcmp(optarg, "on") == 0 && trace_filename)
4471 tracing = 1;
4472 else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004473 PANIC("Unexpected option to -tracing ('%s')",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004474 optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004475 }
4476 break;
4477#if 0
4478 case QEMU_OPTION_dcache_load_miss:
4479 dcache_load_miss_penalty = atoi(optarg);
4480 break;
4481 case QEMU_OPTION_dcache_store_miss:
4482 dcache_store_miss_penalty = atoi(optarg);
4483 break;
4484#endif
4485#endif
4486#ifdef CONFIG_NAND
4487 case QEMU_OPTION_nand:
4488 nand_add_dev(optarg);
4489 break;
4490#endif
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07004491 case QEMU_OPTION_android_ports:
4492 android_op_ports = (char*)optarg;
4493 break;
4494
4495 case QEMU_OPTION_android_port:
4496 android_op_port = (char*)optarg;
4497 break;
4498
4499 case QEMU_OPTION_android_report_console:
4500 android_op_report_console = (char*)optarg;
4501 break;
4502
4503 case QEMU_OPTION_http_proxy:
4504 op_http_proxy = (char*)optarg;
4505 break;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004506
4507 case QEMU_OPTION_charmap:
4508 op_charmap_file = (char*)optarg;
4509 break;
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07004510
4511 case QEMU_OPTION_android_gui:
4512 android_op_gui = (char*)optarg;
4513 break;
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004514
4515 case QEMU_OPTION_android_hw:
4516 android_op_hwini = (char*)optarg;
4517 break;
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07004518
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004519 case QEMU_OPTION_dns_server:
4520 android_op_dns_server = (char*)optarg;
4521 break;
4522
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004523 case QEMU_OPTION_radio:
4524 android_op_radio = (char*)optarg;
4525 break;
4526
4527 case QEMU_OPTION_gps:
4528 android_op_gps = (char*)optarg;
4529 break;
4530
4531 case QEMU_OPTION_audio:
4532 android_op_audio = (char*)optarg;
4533 break;
4534
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004535 case QEMU_OPTION_cpu_delay:
4536 android_op_cpu_delay = (char*)optarg;
4537 break;
4538
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07004539 case QEMU_OPTION_show_kernel:
4540 android_kmsg_init(ANDROID_KMSG_PRINT_MESSAGES);
4541 break;
4542
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004543#ifdef CONFIG_NAND_LIMITS
4544 case QEMU_OPTION_nand_limits:
4545 android_op_nand_limits = (char*)optarg;
4546 break;
4547#endif // CONFIG_NAND_LIMITS
4548
4549 case QEMU_OPTION_netspeed:
4550 android_op_netspeed = (char*)optarg;
4551 break;
4552
4553 case QEMU_OPTION_netdelay:
4554 android_op_netdelay = (char*)optarg;
4555 break;
4556
4557 case QEMU_OPTION_netfast:
4558 android_op_netfast = 1;
4559 break;
4560
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07004561 case QEMU_OPTION_tcpdump:
4562 android_op_tcpdump = (char*)optarg;
4563 break;
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004564
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004565 case QEMU_OPTION_boot_property:
4566 boot_property_parse_option((char*)optarg);
4567 break;
4568
4569 case QEMU_OPTION_lcd_density:
4570 android_op_lcd_density = (char*)optarg;
4571 break;
4572
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004573 case QEMU_OPTION_ui_port:
4574 android_op_ui_port = (char*)optarg;
4575 break;
4576
4577 case QEMU_OPTION_ui_settings:
4578 android_op_ui_settings = (char*)optarg;
4579 break;
4580
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +01004581 case QEMU_OPTION_audio_test_out:
4582 android_audio_test_start_out();
4583 break;
4584
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -08004585 case QEMU_OPTION_android_avdname:
4586 android_op_avd_name = (char*)optarg;
4587 break;
4588
4589 case QEMU_OPTION_timezone:
4590 if (timezone_set((char*)optarg)) {
4591 fprintf(stderr, "emulator: it seems the timezone '%s' is not in zoneinfo format\n",
4592 (char*)optarg);
4593 }
4594 break;
4595
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004596#ifdef CONFIG_MEMCHECK
4597 case QEMU_OPTION_android_memcheck:
4598 android_op_memcheck = (char*)optarg;
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004599 snprintf(tmp_str, sizeof(tmp_str), "memcheck=%s",
4600 android_op_memcheck);
4601 tmp_str[sizeof(tmp_str) - 1] = '\0';
4602 /* This will set ro.kernel.memcheck system property
4603 * to memcheck's tracing flags. */
4604 append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004605 break;
4606#endif // CONFIG_MEMCHECK
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004607 }
4608 }
4609 }
4610
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08004611 /* Parse GUI option early, so when we init framebuffer in goldfish we have
4612 * saved display parameters. */
4613 if (android_op_gui) {
4614 if (parse_androig_gui_option(android_op_gui,
4615 &android_display_width,
4616 &android_display_height,
4617 &android_display_bpp)) {
4618 PANIC("Unable to parse -android-gui parameter: %s", android_op_gui);
4619 }
4620 }
4621
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004622 /* Initialize character map. */
4623 if (android_charmap_setup(op_charmap_file)) {
4624 if (op_charmap_file) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004625 PANIC(
4626 "Unable to initialize character map from file %s.",
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004627 op_charmap_file);
4628 } else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004629 PANIC(
4630 "Unable to initialize default character map.");
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004631 }
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07004632 }
4633
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004634 /* If no data_dir is specified then try to find it relative to the
4635 executable path. */
4636 if (!data_dir) {
4637 data_dir = find_datadir(argv[0]);
4638 }
4639 /* If all else fails use the install patch specified when building. */
4640 if (!data_dir) {
4641 data_dir = CONFIG_QEMU_SHAREDIR;
4642 }
4643
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004644#ifdef CONFIG_STANDALONE_CORE
4645 /* Initialize hardware configuration. */
4646 if (android_op_hwini) {
4647 hw_ini = iniFile_newFromFile(android_op_hwini);
4648 if (hw_ini == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004649 PANIC("Could not find %s file.", android_op_hwini);
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004650 }
4651 } else {
4652 hw_ini = iniFile_newFromMemory("", 0);
4653 }
4654
4655 androidHwConfig_read(android_hw, hw_ini);
4656 iniFile_free(hw_ini);
4657#endif // CONFIG_STANDALONE_CORE
4658
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004659#ifdef CONFIG_NAND_LIMITS
4660 /* Init nand stuff. */
4661 if (android_op_nand_limits) {
4662 parse_nand_limits(android_op_nand_limits);
4663 }
4664#endif // CONFIG_NAND_LIMITS
4665
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004666 /* Set the VM's max heap size, passed as a boot property */
4667 if (android_hw->vm_heapSize > 0) {
4668 char tmp[64];
4669 snprintf(tmp, sizeof(tmp), "%dm", android_hw->vm_heapSize);
4670 boot_property_add("dalvik.vm.heapsize",tmp);
4671 }
4672
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004673 /* Initialize net speed and delays stuff. */
4674 if (android_parse_network_speed(android_op_netspeed) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004675 PANIC("invalid -netspeed parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004676 android_op_netspeed);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004677 }
4678
4679 if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004680 PANIC("invalid -netdelay parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004681 android_op_netdelay);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004682 }
4683
4684 if (android_op_netfast) {
4685 qemu_net_download_speed = 0;
4686 qemu_net_upload_speed = 0;
4687 qemu_net_min_latency = 0;
4688 qemu_net_max_latency = 0;
4689 }
4690
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004691 /* Initialize LCD density */
4692 if (android_op_lcd_density) {
4693 char* end;
4694 long density = strtol(android_op_lcd_density, &end, 0);
4695 if (end == NULL || *end || density < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004696 PANIC("option -lcd-density must be a positive integer");
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004697 }
4698 hwLcd_setBootProperty(density);
4699 }
4700
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07004701 /* Initialize TCP dump */
4702 if (android_op_tcpdump) {
4703 if (qemu_tcpdump_start(android_op_tcpdump) < 0) {
4704 fprintf(stdout, "could not start packet capture: %s\n", strerror(errno));
4705 }
4706 }
4707
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004708 /* Initialize modem */
4709 if (android_op_radio) {
4710 CharDriverState* cs = qemu_chr_open("radio", android_op_radio, NULL);
4711 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004712 PANIC("unsupported character device specification: %s\n"
4713 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004714 android_op_radio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004715 }
4716 android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
4717 } else if (android_hw->hw_gsmModem != 0 ) {
4718 if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004719 PANIC("could not initialize qemud 'gsm' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004720 }
4721 }
4722
4723 /* Initialize GPS */
4724 if (android_op_gps) {
4725 CharDriverState* cs = qemu_chr_open("gps", android_op_gps, NULL);
4726 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004727 PANIC("unsupported character device specification: %s\n"
4728 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004729 android_op_gps);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004730 }
4731 android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
4732 } else if (android_hw->hw_gps != 0) {
4733 if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004734 PANIC("could not initialize qemud 'gps' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004735 }
4736 }
4737
4738 /* Initialize audio. */
4739 if (android_op_audio) {
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004740 if ( !audio_check_backend_name( 0, android_op_audio ) ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004741 PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004742 android_op_audio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004743 }
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004744 }
4745
4746 if (android_op_cpu_delay) {
4747 char* end;
4748 long delay = strtol(android_op_cpu_delay, &end, 0);
4749 if (end == NULL || *end || delay < 0 || delay > 1000 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004750 PANIC("option -cpu-delay must be an integer between 0 and 1000" );
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004751 }
4752 if (delay > 0)
4753 delay = (1000-delay);
4754
4755 qemu_cpu_delay = (int) delay;
4756 }
4757
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004758 if (android_op_dns_server) {
4759 char* x = strchr(android_op_dns_server, ',');
4760 dns_count = 0;
4761 if (x == NULL)
4762 {
4763 if ( add_dns_server( android_op_dns_server ) == 0 )
4764 dns_count = 1;
4765 }
4766 else
4767 {
4768 x = android_op_dns_server;
4769 while (*x) {
4770 char* y = strchr(x, ',');
4771
4772 if (y != NULL) {
4773 *y = 0;
4774 y++;
4775 } else {
4776 y = x + strlen(x);
4777 }
4778
4779 if (y > x && add_dns_server( x ) == 0) {
4780 dns_count += 1;
4781 }
4782 x = y;
4783 }
4784 }
4785 if (dns_count == 0)
4786 fprintf( stdout, "### WARNING: will use system default DNS server\n" );
4787 }
4788
4789 if (dns_count == 0)
4790 dns_count = slirp_get_system_dns_servers();
4791 if (dns_count) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004792 snprintf(tmp_str, sizeof(tmp_str), "ndns=%d", dns_count);
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004793 append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
4794 }
4795
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004796#ifdef CONFIG_MEMCHECK
4797 if (android_op_memcheck) {
4798 memcheck_init(android_op_memcheck);
4799 }
4800#endif // CONFIG_MEMCHECK
4801
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004802#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
4803 if (kvm_allowed && kqemu_allowed) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004804 PANIC(
4805 "You can not enable both KVM and kqemu at the same time");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004806 }
4807#endif
4808
4809 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
4810 if (smp_cpus > machine->max_cpus) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004811 PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
4812 "supported by machine `%s' (%d)", smp_cpus, machine->name,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004813 machine->max_cpus);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004814 }
4815
4816 if (display_type == DT_NOGRAPHIC) {
4817 if (serial_device_index == 0)
4818 serial_devices[0] = "stdio";
4819 if (parallel_device_index == 0)
4820 parallel_devices[0] = "null";
4821 if (strncmp(monitor_device, "vc", 2) == 0)
4822 monitor_device = "stdio";
4823 }
4824
4825#ifndef _WIN32
4826 if (daemonize) {
4827 pid_t pid;
4828
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004829 if (pipe(fds) == -1) {
4830 PANIC("Unable to aquire pidfile");
4831 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004832
4833 pid = fork();
4834 if (pid > 0) {
4835 uint8_t status;
4836 ssize_t len;
4837
4838 close(fds[1]);
4839
4840 again:
4841 len = read(fds[0], &status, 1);
4842 if (len == -1 && (errno == EINTR))
4843 goto again;
4844
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004845 if (len != 1) {
4846 PANIC("Error when aquiring pidfile");
4847 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004848 else if (status == 1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004849 PANIC("Could not acquire pidfile");
4850 } else {
4851 QEMU_EXIT(0);
4852 }
4853 } else if (pid < 0) {
4854 PANIC("Unable to daemonize");
4855 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004856
4857 setsid();
4858
4859 pid = fork();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004860 if (pid > 0) {
4861 QEMU_EXIT(0);
4862 } else if (pid < 0) {
4863 PANIC("Could not acquire pid file");
4864 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004865
4866 umask(027);
4867
4868 signal(SIGTSTP, SIG_IGN);
4869 signal(SIGTTOU, SIG_IGN);
4870 signal(SIGTTIN, SIG_IGN);
4871 }
4872
4873 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
4874 if (daemonize) {
4875 uint8_t status = 1;
David 'Digit' Turner4e024bb2010-09-22 14:19:28 +02004876 int ret;
4877 do {
4878 ret = write(fds[1], &status, 1);
4879 } while (ret < 0 && errno == EINTR);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004880 PANIC("Could not acquire pid file");
4881 } else {
4882 PANIC("Could not acquire pid file");
4883 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004884 }
4885#endif
4886
4887#ifdef CONFIG_KQEMU
4888 if (smp_cpus > 1)
4889 kqemu_allowed = 0;
4890#endif
4891 if (qemu_init_main_loop()) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004892 PANIC("qemu_init_main_loop failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004893 }
4894 linux_boot = (kernel_filename != NULL);
4895 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
4896
4897 if (!linux_boot && *kernel_cmdline != '\0') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004898 PANIC("-append only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004899 }
4900
4901 if (!linux_boot && initrd_filename != NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004902 PANIC("-initrd only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004903 }
4904
4905 /* boot to floppy or the default cd if no hard disk defined yet */
4906 if (!boot_devices[0]) {
4907 boot_devices = "cad";
4908 }
4909 setvbuf(stdout, NULL, _IOLBF, 0);
4910
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004911 if (init_timer_alarm() < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004912 PANIC("could not initialize alarm timer");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004913 }
David Turner6a9ef172010-09-09 22:54:36 +02004914 configure_icount(icount_option);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004915
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004916 /* init network clients */
4917 if (nb_net_clients == 0) {
4918 /* if no clients, we use a default config */
4919 net_clients[nb_net_clients++] = "nic";
4920#ifdef CONFIG_SLIRP
4921 net_clients[nb_net_clients++] = "user";
4922#endif
4923 }
4924
4925 for(i = 0;i < nb_net_clients; i++) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004926 if (net_client_parse(net_clients[i]) < 0) {
4927 PANIC("Unable to parse net clients");
4928 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004929 }
4930 net_client_check();
4931
4932#ifdef TARGET_I386
4933 /* XXX: this should be moved in the PC machine instantiation code */
4934 if (net_boot != 0) {
4935 int netroms = 0;
4936 for (i = 0; i < nb_nics && i < 4; i++) {
4937 const char *model = nd_table[i].model;
4938 char buf[1024];
4939 char *filename;
4940 if (net_boot & (1 << i)) {
4941 if (model == NULL)
4942 model = "ne2k_pci";
4943 snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
4944 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
4945 if (filename && get_image_size(filename) > 0) {
4946 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004947 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004948 }
4949 option_rom[nb_option_roms] = qemu_strdup(buf);
4950 nb_option_roms++;
4951 netroms++;
4952 }
4953 if (filename) {
4954 qemu_free(filename);
4955 }
4956 }
4957 }
4958 if (netroms == 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004959 PANIC("No valid PXE rom found for network device");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004960 }
4961 }
4962#endif
4963
4964 /* init the bluetooth world */
4965 for (i = 0; i < nb_bt_opts; i++)
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004966 if (bt_parse(bt_opts[i])) {
4967 PANIC("Unable to parse bluetooth options");
4968 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004969
4970 /* init the memory */
4971 if (ram_size == 0)
4972 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
4973
4974#ifdef CONFIG_KQEMU
4975 /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
4976 guest ram allocation. It needs to go away. */
4977 if (kqemu_allowed) {
4978 kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
4979 kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
4980 if (!kqemu_phys_ram_base) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004981 PANIC("Could not allocate physical memory");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004982 }
4983 }
4984#endif
4985
4986 /* init the dynamic translator */
4987 cpu_exec_init_all(tb_size * 1024 * 1024);
4988
4989 bdrv_init();
4990
4991 /* we always create the cdrom drive, even if no disk is there */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004992#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004993 if (nb_drives_opt < MAX_DRIVES)
4994 drive_add(NULL, CDROM_ALIAS);
4995
4996 /* we always create at least one floppy */
4997
4998 if (nb_drives_opt < MAX_DRIVES)
4999 drive_add(NULL, FD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005000 /* we always create one sd slot, even if no card is in it */
5001
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005002 if (1) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005003 drive_add(NULL, SD_ALIAS);
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005004 }
5005#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005006
5007 /* open the virtual block devices */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01005008 if (snapshot)
5009 qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
5010 if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
5011 exit(1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005012
David Turner6a9ef172010-09-09 22:54:36 +02005013 //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005014 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
5015
5016#ifndef _WIN32
5017 /* must be after terminal init, SDL library changes signal handlers */
5018 sighandler_setup();
5019#endif
5020
5021 /* Maintain compatibility with multiple stdio monitors */
5022 if (!strcmp(monitor_device,"stdio")) {
5023 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
5024 const char *devname = serial_devices[i];
5025 if (devname && !strcmp(devname,"mon:stdio")) {
5026 monitor_device = NULL;
5027 break;
5028 } else if (devname && !strcmp(devname,"stdio")) {
5029 monitor_device = NULL;
5030 serial_devices[i] = "mon:stdio";
5031 break;
5032 }
5033 }
5034 }
5035
5036 if (nb_numa_nodes > 0) {
5037 int i;
5038
5039 if (nb_numa_nodes > smp_cpus) {
5040 nb_numa_nodes = smp_cpus;
5041 }
5042
5043 /* If no memory size if given for any node, assume the default case
5044 * and distribute the available memory equally across all nodes
5045 */
5046 for (i = 0; i < nb_numa_nodes; i++) {
5047 if (node_mem[i] != 0)
5048 break;
5049 }
5050 if (i == nb_numa_nodes) {
5051 uint64_t usedmem = 0;
5052
5053 /* On Linux, the each node's border has to be 8MB aligned,
5054 * the final node gets the rest.
5055 */
5056 for (i = 0; i < nb_numa_nodes - 1; i++) {
5057 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
5058 usedmem += node_mem[i];
5059 }
5060 node_mem[i] = ram_size - usedmem;
5061 }
5062
5063 for (i = 0; i < nb_numa_nodes; i++) {
5064 if (node_cpumask[i] != 0)
5065 break;
5066 }
5067 /* assigning the VCPUs round-robin is easier to implement, guest OSes
5068 * must cope with this anyway, because there are BIOSes out there in
5069 * real machines which also use this scheme.
5070 */
5071 if (i == nb_numa_nodes) {
5072 for (i = 0; i < smp_cpus; i++) {
5073 node_cpumask[i % nb_numa_nodes] |= 1 << i;
5074 }
5075 }
5076 }
5077
5078 if (kvm_enabled()) {
5079 int ret;
5080
5081 ret = kvm_init(smp_cpus);
5082 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005083 PANIC("failed to initialize KVM");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005084 }
5085 }
5086
5087 if (monitor_device) {
5088 monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
5089 if (!monitor_hd) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005090 PANIC("qemu: could not open monitor device '%s'",
5091 monitor_device);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005092 }
5093 }
5094
5095 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5096 const char *devname = serial_devices[i];
5097 if (devname && strcmp(devname, "none")) {
5098 char label[32];
5099 snprintf(label, sizeof(label), "serial%d", i);
5100 serial_hds[i] = qemu_chr_open(label, devname, NULL);
5101 if (!serial_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005102 PANIC("qemu: could not open serial device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005103 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005104 }
5105 }
5106 }
5107
5108 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5109 const char *devname = parallel_devices[i];
5110 if (devname && strcmp(devname, "none")) {
5111 char label[32];
5112 snprintf(label, sizeof(label), "parallel%d", i);
5113 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
5114 if (!parallel_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005115 PANIC("qemu: could not open parallel device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005116 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005117 }
5118 }
5119 }
5120
5121 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5122 const char *devname = virtio_consoles[i];
5123 if (devname && strcmp(devname, "none")) {
5124 char label[32];
5125 snprintf(label, sizeof(label), "virtcon%d", i);
5126 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
5127 if (!virtcon_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005128 PANIC("qemu: could not open virtio console '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005129 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005130 }
5131 }
5132 }
5133
5134 module_call_init(MODULE_INIT_DEVICE);
5135
5136
5137#ifdef CONFIG_TRACE
5138 if (trace_filename) {
5139 trace_init(trace_filename);
5140#if 0
5141 // We don't need the dcache code until we can get load and store tracing
5142 // working again.
5143 dcache_init(dcache_size, dcache_ways, dcache_line_size,
5144 dcache_replace_policy, dcache_load_miss_penalty,
5145 dcache_store_miss_penalty);
5146#endif
5147 fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
5148 }
5149#endif
5150
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005151 /* Combine kernel command line passed from the UI with parameters
5152 * collected during initialization. */
5153 if (*kernel_cmdline) {
5154 if (kernel_cmdline_append[0]) {
5155 snprintf(kernel_cmdline_full, sizeof(kernel_cmdline_full), "%s %s",
5156 kernel_cmdline, kernel_cmdline_append);
5157 } else {
5158 strncpy(kernel_cmdline_full, kernel_cmdline, sizeof(kernel_cmdline_full));
5159 kernel_cmdline_full[sizeof(kernel_cmdline_full) - 1] = '\0';
5160 }
5161 } else if (kernel_cmdline_append[0]) {
5162 strncpy(kernel_cmdline_full, kernel_cmdline_append, sizeof(kernel_cmdline_full));
5163 }
5164
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005165 machine->init(ram_size, boot_devices,
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07005166 kernel_filename, kernel_cmdline_full, initrd_filename, cpu_model);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005167
5168
5169 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5170 for (i = 0; i < nb_numa_nodes; i++) {
5171 if (node_cpumask[i] & (1 << env->cpu_index)) {
5172 env->numa_node = i;
5173 }
5174 }
5175 }
5176
5177 current_machine = machine;
5178
5179 /* Set KVM's vcpu state to qemu's initial CPUState. */
5180 if (kvm_enabled()) {
5181 int ret;
5182
5183 ret = kvm_sync_vcpus();
5184 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005185 PANIC("failed to initialize vcpus");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005186 }
5187 }
5188
5189 /* init USB devices */
5190 if (usb_enabled) {
5191 for(i = 0; i < usb_devices_index; i++) {
5192 if (usb_device_add(usb_devices[i], 0) < 0) {
5193 fprintf(stderr, "Warning: could not add USB device %s\n",
5194 usb_devices[i]);
5195 }
5196 }
5197 }
5198
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08005199 /* just use the first displaystate for the moment */
David 'Digit' Turner94702b02011-01-20 02:46:33 +01005200 ds = get_displaystate();
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08005201
David 'Digit' Turner94702b02011-01-20 02:46:33 +01005202 if (android_op_gui) {
5203 /* Initialize display from the command line parameters. */
5204 android_display_reset(ds,
5205 android_display_width,
5206 android_display_height,
5207 android_display_bpp);
5208 } else {
5209 /* By default, use 320x480x16 */
5210 android_display_reset(ds, 320, 480, 16);
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07005211 }
5212
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005213 if (display_type == DT_DEFAULT) {
5214#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
5215 display_type = DT_SDL;
5216#else
5217 display_type = DT_VNC;
5218 vnc_display = "localhost:0,to=99";
5219 show_vnc_port = 1;
5220#endif
5221 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07005222
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005223
5224 switch (display_type) {
5225 case DT_NOGRAPHIC:
5226 break;
5227#if defined(CONFIG_CURSES)
5228 case DT_CURSES:
5229 curses_display_init(ds, full_screen);
5230 break;
5231#endif
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07005232#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005233 case DT_SDL:
5234 sdl_display_init(ds, full_screen, no_frame);
5235 break;
5236#elif defined(CONFIG_COCOA)
5237 case DT_SDL:
5238 cocoa_display_init(ds, full_screen);
5239 break;
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08005240#elif defined(CONFIG_STANDALONE_CORE)
5241 case DT_SDL:
Vladimir Chtchetkinee95660a2010-12-20 08:28:03 -08005242 coredisplay_init(ds);
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08005243 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005244#endif
5245 case DT_VNC:
5246 vnc_display_init(ds);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005247 if (vnc_display_open(ds, vnc_display) < 0) {
5248 PANIC("Unable to initialize VNC display");
5249 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005250
5251 if (show_vnc_port) {
5252 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
5253 }
5254 break;
5255 default:
5256 break;
5257 }
5258 dpy_resize(ds);
5259
5260 dcl = ds->listeners;
5261 while (dcl != NULL) {
5262 if (dcl->dpy_refresh != NULL) {
5263 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5264 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
5265 }
5266 dcl = dcl->next;
5267 }
5268
5269 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
5270 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5271 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5272 }
5273
David 'Digit' Turner94702b02011-01-20 02:46:33 +01005274 text_consoles_set_display(ds);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005275 qemu_chr_initial_reset();
5276
5277 if (monitor_device && monitor_hd)
5278 monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
5279
5280 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5281 const char *devname = serial_devices[i];
5282 if (devname && strcmp(devname, "none")) {
5283 if (strstart(devname, "vc", 0))
5284 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
5285 }
5286 }
5287
5288 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5289 const char *devname = parallel_devices[i];
5290 if (devname && strcmp(devname, "none")) {
5291 if (strstart(devname, "vc", 0))
5292 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
5293 }
5294 }
5295
5296 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5297 const char *devname = virtio_consoles[i];
5298 if (virtcon_hds[i] && devname) {
5299 if (strstart(devname, "vc", 0))
5300 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
5301 }
5302 }
5303
5304 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005305 PANIC("qemu: could not open gdbserver on device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005306 gdbstub_dev);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005307 }
5308
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005309 /* call android-specific setup function */
5310 android_emulation_setup();
5311
Vladimir Chtchetkine57584042011-01-20 16:15:30 -08005312#if !defined(CONFIG_STANDALONE_CORE)
5313 // For the standalone emulator (UI+core in one executable) we need to
5314 // set the window title here.
5315 android_emulator_set_base_port(android_base_port);
5316#endif
5317
Ot ten Thije871da2a2010-09-20 10:29:22 +01005318 if (loadvm)
5319 do_loadvm(cur_mon, loadvm);
5320
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005321 if (incoming) {
5322 autostart = 0; /* fixme how to deal with -daemonize */
5323 qemu_start_incoming_migration(incoming);
5324 }
5325
5326 if (autostart)
5327 vm_start();
5328
5329#ifndef _WIN32
5330 if (daemonize) {
5331 uint8_t status = 0;
5332 ssize_t len;
5333
5334 again1:
5335 len = write(fds[1], &status, 1);
5336 if (len == -1 && (errno == EINTR))
5337 goto again1;
5338
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005339 if (len != 1) {
5340 PANIC("Unable to daemonize");
5341 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005342
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005343 if (chdir("/")) {
5344 perror("not able to chdir to /");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005345 PANIC("not able to chdir to /");
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005346 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005347 TFR(fd = open("/dev/null", O_RDWR));
5348 if (fd == -1)
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005349 PANIC("open(\"/dev/null\") failed: %s", errno_str);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005350 }
5351
5352 if (run_as) {
5353 pwd = getpwnam(run_as);
5354 if (!pwd) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005355 PANIC("User \"%s\" doesn't exist", run_as);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005356 }
5357 }
5358
5359 if (chroot_dir) {
5360 if (chroot(chroot_dir) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005361 PANIC("chroot failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005362 }
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005363 if (chdir("/")) {
5364 perror("not able to chdir to /");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005365 PANIC("not able to chdir to /");
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005366 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005367 }
5368
5369 if (run_as) {
5370 if (setgid(pwd->pw_gid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005371 PANIC("Failed to setgid(%d)", pwd->pw_gid);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005372 }
5373 if (setuid(pwd->pw_uid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005374 PANIC("Failed to setuid(%d)", pwd->pw_uid);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005375 }
5376 if (setuid(0) != -1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005377 PANIC("Dropping privileges failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005378 }
5379 }
5380
5381 if (daemonize) {
5382 dup2(fd, 0);
5383 dup2(fd, 1);
5384 dup2(fd, 2);
5385
5386 close(fd);
5387 }
5388#endif
5389
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07005390#ifdef CONFIG_ANDROID
5391 // This will notify the UI that the core is successfuly initialized
5392 android_core_init_completed();
5393#endif // CONFIG_ANDROID
5394
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005395 main_loop();
5396 quit_timers();
5397 net_cleanup();
5398 android_emulation_teardown();
5399 return 0;
5400}
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07005401
5402void
5403android_emulation_teardown(void)
5404{
5405 android_charmap_done();
5406}