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