blob: c85aff5b5544fe756c6d78d424fb3158b2e464e4 [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"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070054#include "android/hw-kmsg.h"
David 'Digit' Turnerc0ac7332011-05-02 15:05:35 +020055#include "android/hw-pipe-net.h"
56#include "android/hw-qemud.h"
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -070057#include "android/charmap.h"
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -070058#include "android/globals.h"
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -070059#include "android/utils/bufprint.h"
David 'Digit' Turner5f824112011-03-01 14:00:26 +010060#include "android/utils/debug.h"
David 'Digit' Turner48a3c662011-03-01 14:03:20 +010061#include "android/utils/filelock.h"
62#include "android/utils/path.h"
David 'Digit' Turner5f824112011-03-01 14:00:26 +010063#include "android/utils/stralloc.h"
David 'Digit' Turner40841b22011-03-01 14:04:00 +010064#include "android/utils/tempfile.h"
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -080065#include "android/display-core.h"
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -080066#include "android/utils/timezone.h"
David 'Digit' Turnerbdb6f2d2011-02-23 15:57:25 +010067#include "android/snapshot.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070068#include "targphys.h"
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -070069#include "tcpdump.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070070
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -070071#ifdef CONFIG_MEMCHECK
72#include "memcheck/memcheck.h"
73#endif // CONFIG_MEMCHECK
74
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070075#include <unistd.h>
76#include <fcntl.h>
77#include <signal.h>
78#include <time.h>
79#include <errno.h>
80#include <sys/time.h>
81#include <zlib.h>
82
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070083/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070084#include "config-host.h"
85
86#ifndef _WIN32
87#include <libgen.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070088#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
David 'Digit' Turner23ca2ae2011-06-01 16:14:53 +0200165#include "cpus.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700166
167#ifdef CONFIG_COCOA
168#undef main
169#define main qemu_main
170#endif /* CONFIG_COCOA */
171
172#include "hw/hw.h"
173#include "hw/boards.h"
174#include "hw/usb.h"
175#include "hw/pcmcia.h"
176#include "hw/pc.h"
177#include "hw/audiodev.h"
178#include "hw/isa.h"
179#include "hw/baum.h"
180#include "hw/bt.h"
181#include "hw/watchdog.h"
182#include "hw/smbios.h"
183#include "hw/xen.h"
184#include "bt-host.h"
185#include "net.h"
186#include "monitor.h"
187#include "console.h"
188#include "sysemu.h"
189#include "gdbstub.h"
190#include "qemu-timer.h"
191#include "qemu-char.h"
192#include "cache-utils.h"
193#include "block.h"
194#include "dma.h"
195#include "audio/audio.h"
196#include "migration.h"
197#include "kvm.h"
David 'Digit' Turner36597752011-05-20 01:18:01 +0200198#ifdef CONFIG_KVM
199#include "kvm-android.h"
200#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700201#include "balloon.h"
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700202#include "android/hw-lcd.h"
203#include "android/boot-properties.h"
David 'Digit' Turnerca950592011-04-27 12:26:15 +0200204#include "android/hw-control.h"
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700205#include "android/core-init-utils.h"
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +0100206#include "android/audio-test.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700207
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -0700208#ifdef CONFIG_STANDALONE_CORE
209/* Verbose value used by the standalone emulator core (without UI) */
210unsigned long android_verbose;
211#endif // CONFIG_STANDALONE_CORE
212
Vladimir Chtchetkine57584042011-01-20 16:15:30 -0800213#if !defined(CONFIG_STANDALONE_CORE)
214/* in android/qemulator.c */
215extern void android_emulator_set_base_port(int port);
216#endif
217
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700218#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700219#undef main
220#define main qemu_main
221#endif
222
223#include "disas.h"
224
225#include "exec-all.h"
226
227#ifdef CONFIG_TRACE
228#include "trace.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700229#endif
230
231#include "qemu_socket.h"
232
233#if defined(CONFIG_SLIRP)
234#include "libslirp.h"
235#endif
236
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700237
238
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700239#define DEFAULT_RAM_SIZE 128
240
241/* Max number of USB devices that can be specified on the commandline. */
242#define MAX_USB_CMDLINE 8
243
244/* Max number of bluetooth switches on the commandline. */
245#define MAX_BT_CMDLINE 10
246
247/* XXX: use a two level table to limit memory usage */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700248
249static const char *data_dir;
250const char *bios_name = NULL;
251static void *ioport_opaque[MAX_IOPORTS];
252static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
253static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100254#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700255/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
256 to store the VM snapshots */
257DriveInfo drives_table[MAX_DRIVES+1];
258int nb_drives;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100259#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700260enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700261DisplayType display_type = DT_DEFAULT;
262const char* keyboard_layout = NULL;
263int64_t ticks_per_sec;
264ram_addr_t ram_size;
265int nb_nics;
266NICInfo nd_table[MAX_NICS];
267int vm_running;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100268int autostart;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700269static int rtc_utc = 1;
270static int rtc_date_offset = -1; /* -1 means no change */
271int cirrus_vga_enabled = 1;
272int std_vga_enabled = 0;
273int vmsvga_enabled = 0;
274int xenfb_enabled = 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700275QEMUClock *rtc_clock;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700276#ifdef TARGET_SPARC
277int graphic_width = 1024;
278int graphic_height = 768;
279int graphic_depth = 8;
280#else
281int graphic_width = 800;
282int graphic_height = 600;
283int graphic_depth = 15;
284#endif
285static int full_screen = 0;
286#ifdef CONFIG_SDL
287static int no_frame = 0;
288#endif
289int no_quit = 0;
290CharDriverState *serial_hds[MAX_SERIAL_PORTS];
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +0100291int serial_hds_count;
292
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700293CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
294CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
295#ifdef TARGET_I386
296int win2k_install_hack = 0;
297int rtc_td_hack = 0;
298#endif
299int usb_enabled = 0;
300int singlestep = 0;
301int smp_cpus = 1;
302const char *vnc_display;
303int acpi_enabled = 1;
304int no_hpet = 0;
305int no_virtio_balloon = 0;
306int fd_bootchk = 1;
307int no_reboot = 0;
308int no_shutdown = 0;
309int cursor_hide = 1;
310int graphic_rotate = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700311WatchdogTimerModel *watchdog = NULL;
312int watchdog_action = WDT_RESET;
313const char *option_rom[MAX_OPTION_ROMS];
314int nb_option_roms;
315int semihosting_enabled = 0;
316#ifdef TARGET_ARM
317int old_param = 0;
318#endif
319const char *qemu_name;
320int alt_grab = 0;
321#if defined(TARGET_SPARC) || defined(TARGET_PPC)
322unsigned int nb_prom_envs = 0;
323const char *prom_envs[MAX_PROM_ENVS];
324#endif
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100325#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700326int nb_drives_opt;
327struct drive_opt drives_opt[MAX_DRIVES];
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100328#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700329int nb_numa_nodes;
330uint64_t node_mem[MAX_NODES];
331uint64_t node_cpumask[MAX_NODES];
332
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700333static QEMUTimer *nographic_timer;
334
335uint8_t qemu_uuid[16];
336
337
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700338int qemu_cpu_delay;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700339extern char* audio_input_source;
340
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700341extern char* android_op_ports;
342extern char* android_op_port;
343extern char* android_op_report_console;
344extern char* op_http_proxy;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -0700345// Path to the file containing specific key character map.
346char* op_charmap_file = NULL;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -0700347
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -0700348/* Path to hardware initialization file passed with -android-hw option. */
349char* android_op_hwini = NULL;
350
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -0700351/* Memory checker options. */
352char* android_op_memcheck = NULL;
353
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -0700354/* -dns-server option value. */
355char* android_op_dns_server = NULL;
356
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -0700357/* -radio option value. */
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700358char* android_op_radio = NULL;
359
360/* -gps option value. */
361char* android_op_gps = NULL;
362
363/* -audio option value. */
364char* android_op_audio = NULL;
365
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -0700366/* -cpu-delay option value. */
367char* android_op_cpu_delay = NULL;
368
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -0700369#ifdef CONFIG_NAND_LIMITS
370/* -nand-limits option value. */
371char* android_op_nand_limits = NULL;
372#endif // CONFIG_NAND_LIMITS
373
374/* -netspeed option value. */
375char* android_op_netspeed = NULL;
376
377/* -netdelay option value. */
378char* android_op_netdelay = NULL;
379
380/* -netfast option value. */
381int android_op_netfast = 0;
382
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -0700383/* -tcpdump option value. */
384char* android_op_tcpdump = NULL;
385
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -0700386/* -lcd-density option value. */
387char* android_op_lcd_density = NULL;
388
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700389/* -ui-port option value. This port will be used to report the core
390 * initialization completion.
391 */
392char* android_op_ui_port = NULL;
393
394/* -ui-settings option value. This value will be passed to the UI when new UI
395 * process is attaching to the core.
396 */
397char* android_op_ui_settings = NULL;
398
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -0800399/* -android-avdname option value. */
400char* android_op_avd_name = "unknown";
401
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -0700402extern int android_display_width;
403extern int android_display_height;
404extern int android_display_bpp;
405
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700406extern void dprint( const char* format, ... );
407
rich canningsd952f282011-03-01 15:40:09 -0800408const char* dns_log_filename = NULL;
409const char* drop_log_filename = NULL;
410static int rotate_logs_requested = 0;
411
Tim Baverstock24204cc2010-11-25 11:37:43 +0000412const char* savevm_on_exit = NULL;
Tim Baverstock24204cc2010-11-25 11:37:43 +0000413
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700414#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
415
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -0700416/* Reports the core initialization failure to the error stdout and to the UI
417 * socket before exiting the application.
418 * Parameters that are passed to this macro are used to format the error
419 * mesage using sprintf routine.
420 */
421#ifdef CONFIG_ANDROID
422#define PANIC(...) android_core_init_failure(__VA_ARGS__)
423#else
424#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
425 exit(1); \
426 } while (0)
427#endif // CONFIG_ANDROID
428
429/* Exits the core during initialization. */
430#ifdef CONFIG_ANDROID
431#define QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
432#else
433#define QEMU_EXIT(exit_code) exit(exit_code)
434#endif // CONFIG_ANDROID
435
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700436/***********************************************************/
437/* x86 ISA bus support */
438
439target_phys_addr_t isa_mem_base = 0;
440PicState2 *isa_pic;
441
442static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
443static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
444
445static uint32_t ioport_read(int index, uint32_t address)
446{
447 static IOPortReadFunc *default_func[3] = {
448 default_ioport_readb,
449 default_ioport_readw,
450 default_ioport_readl
451 };
452 IOPortReadFunc *func = ioport_read_table[index][address];
453 if (!func)
454 func = default_func[index];
455 return func(ioport_opaque[address], address);
456}
457
458static void ioport_write(int index, uint32_t address, uint32_t data)
459{
460 static IOPortWriteFunc *default_func[3] = {
461 default_ioport_writeb,
462 default_ioport_writew,
463 default_ioport_writel
464 };
465 IOPortWriteFunc *func = ioport_write_table[index][address];
466 if (!func)
467 func = default_func[index];
468 func(ioport_opaque[address], address, data);
469}
470
471static uint32_t default_ioport_readb(void *opaque, uint32_t address)
472{
473#ifdef DEBUG_UNUSED_IOPORT
474 fprintf(stderr, "unused inb: port=0x%04x\n", address);
475#endif
476 return 0xff;
477}
478
479static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
480{
481#ifdef DEBUG_UNUSED_IOPORT
482 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
483#endif
484}
485
486/* default is to make two byte accesses */
487static uint32_t default_ioport_readw(void *opaque, uint32_t address)
488{
489 uint32_t data;
490 data = ioport_read(0, address);
491 address = (address + 1) & (MAX_IOPORTS - 1);
492 data |= ioport_read(0, address) << 8;
493 return data;
494}
495
496static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
497{
498 ioport_write(0, address, data & 0xff);
499 address = (address + 1) & (MAX_IOPORTS - 1);
500 ioport_write(0, address, (data >> 8) & 0xff);
501}
502
503static uint32_t default_ioport_readl(void *opaque, uint32_t address)
504{
505#ifdef DEBUG_UNUSED_IOPORT
506 fprintf(stderr, "unused inl: port=0x%04x\n", address);
507#endif
508 return 0xffffffff;
509}
510
511static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
512{
513#ifdef DEBUG_UNUSED_IOPORT
514 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
515#endif
516}
517
rich canningsd952f282011-03-01 15:40:09 -0800518/*
519 * Sets a flag (rotate_logs_requested) to clear both the DNS and the
520 * drop logs upon receiving a SIGUSR1 signal. We need to clear the logs
521 * between the tasks that do not require restarting Qemu.
522 */
523void rotate_qemu_logs_handler(int signum) {
524 rotate_logs_requested = 1;
525}
526
527/*
528 * Resets the rotate_log_requested_flag. Normally called after qemu
529 * logs has been rotated.
530 */
531void reset_rotate_qemu_logs_request(void) {
532 rotate_logs_requested = 0;
533}
534
535/*
536 * Clears the passed qemu log when the rotate_logs_requested
537 * is set. We need to clear the logs between the tasks that do not
538 * require restarting Qemu.
539 */
540FILE* rotate_qemu_log(FILE* old_log_fd, const char* filename) {
541 FILE* new_log_fd = NULL;
542 if (old_log_fd) {
543 if (fclose(old_log_fd) == -1) {
544 fprintf(stderr, "Cannot close old_log fd\n");
545 exit(errno);
546 }
547 }
548
549 if (!filename) {
550 fprintf(stderr, "The log filename to be rotated is not provided");
551 exit(-1);
552 }
553
554 new_log_fd = fopen(filename , "wb+");
555 if (new_log_fd == NULL) {
556 fprintf(stderr, "Cannot open the log file: %s for write.\n",
557 filename);
558 exit(1);
559 }
560
561 return new_log_fd;
562}
563
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700564/***************/
565/* ballooning */
566
567static QEMUBalloonEvent *qemu_balloon_event;
568void *qemu_balloon_event_opaque;
569
570void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
571{
572 qemu_balloon_event = func;
573 qemu_balloon_event_opaque = opaque;
574}
575
576void qemu_balloon(ram_addr_t target)
577{
578 if (qemu_balloon_event)
579 qemu_balloon_event(qemu_balloon_event_opaque, target);
580}
581
582ram_addr_t qemu_balloon_status(void)
583{
584 if (qemu_balloon_event)
585 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
586 return 0;
587}
588
589/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700590/* host time/date access */
591void qemu_get_timedate(struct tm *tm, int offset)
592{
593 time_t ti;
594 struct tm *ret;
595
596 time(&ti);
597 ti += offset;
598 if (rtc_date_offset == -1) {
599 if (rtc_utc)
600 ret = gmtime(&ti);
601 else
602 ret = localtime(&ti);
603 } else {
604 ti -= rtc_date_offset;
605 ret = gmtime(&ti);
606 }
607
608 memcpy(tm, ret, sizeof(struct tm));
609}
610
611int qemu_timedate_diff(struct tm *tm)
612{
613 time_t seconds;
614
615 if (rtc_date_offset == -1)
616 if (rtc_utc)
617 seconds = mktimegm(tm);
618 else
619 seconds = mktime(tm);
620 else
621 seconds = mktimegm(tm) + rtc_date_offset;
622
623 return seconds - time(NULL);
624}
625
626
627#ifdef CONFIG_TRACE
David 'Digit' Turner23ca2ae2011-06-01 16:14:53 +0200628int tbflush_requested;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700629static int exit_requested;
630
631void start_tracing()
632{
633 if (trace_filename == NULL)
634 return;
635 if (!tracing) {
636 fprintf(stderr,"-- start tracing --\n");
637 start_time = Now();
638 }
639 tracing = 1;
640 tbflush_requested = 1;
641 qemu_notify_event();
642}
643
644void stop_tracing()
645{
646 if (trace_filename == NULL)
647 return;
648 if (tracing) {
649 end_time = Now();
650 elapsed_usecs += end_time - start_time;
651 fprintf(stderr,"-- stop tracing --\n");
652 }
653 tracing = 0;
654 tbflush_requested = 1;
655 qemu_notify_event();
656}
657
658#ifndef _WIN32
659/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
660 * SIGUSR1 turns tracing on. SIGUSR2 turns tracing off.
661 */
662void sigusr_handler(int sig)
663{
664 if (sig == SIGUSR1)
665 start_tracing();
666 else
667 stop_tracing();
668}
669#endif
670
671/* This is the handler to catch control-C so that we can exit cleanly.
672 * This is needed when tracing to flush the buffers to disk.
673 */
674void sigint_handler(int sig)
675{
676 exit_requested = 1;
677 qemu_notify_event();
678}
679#endif /* CONFIG_TRACE */
680
681
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700682/***********************************************************/
683/* Bluetooth support */
684static int nb_hcis;
685static int cur_hci;
686static struct HCIInfo *hci_table[MAX_NICS];
687
688static struct bt_vlan_s {
689 struct bt_scatternet_s net;
690 int id;
691 struct bt_vlan_s *next;
692} *first_bt_vlan;
693
694/* find or alloc a new bluetooth "VLAN" */
695static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
696{
697 struct bt_vlan_s **pvlan, *vlan;
698 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
699 if (vlan->id == id)
700 return &vlan->net;
701 }
702 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
703 vlan->id = id;
704 pvlan = &first_bt_vlan;
705 while (*pvlan != NULL)
706 pvlan = &(*pvlan)->next;
707 *pvlan = vlan;
708 return &vlan->net;
709}
710
711static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
712{
713}
714
715static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
716{
717 return -ENOTSUP;
718}
719
720static struct HCIInfo null_hci = {
721 .cmd_send = null_hci_send,
722 .sco_send = null_hci_send,
723 .acl_send = null_hci_send,
724 .bdaddr_set = null_hci_addr_set,
725};
726
727struct HCIInfo *qemu_next_hci(void)
728{
729 if (cur_hci == nb_hcis)
730 return &null_hci;
731
732 return hci_table[cur_hci++];
733}
734
735static struct HCIInfo *hci_init(const char *str)
736{
737 char *endp;
738 struct bt_scatternet_s *vlan = 0;
739
740 if (!strcmp(str, "null"))
741 /* null */
742 return &null_hci;
743 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
744 /* host[:hciN] */
745 return bt_host_hci(str[4] ? str + 5 : "hci0");
746 else if (!strncmp(str, "hci", 3)) {
747 /* hci[,vlan=n] */
748 if (str[3]) {
749 if (!strncmp(str + 3, ",vlan=", 6)) {
750 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
751 if (*endp)
752 vlan = 0;
753 }
754 } else
755 vlan = qemu_find_bt_vlan(0);
756 if (vlan)
757 return bt_new_hci(vlan);
758 }
759
760 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
761
762 return 0;
763}
764
765static int bt_hci_parse(const char *str)
766{
767 struct HCIInfo *hci;
768 bdaddr_t bdaddr;
769
770 if (nb_hcis >= MAX_NICS) {
771 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
772 return -1;
773 }
774
775 hci = hci_init(str);
776 if (!hci)
777 return -1;
778
779 bdaddr.b[0] = 0x52;
780 bdaddr.b[1] = 0x54;
781 bdaddr.b[2] = 0x00;
782 bdaddr.b[3] = 0x12;
783 bdaddr.b[4] = 0x34;
784 bdaddr.b[5] = 0x56 + nb_hcis;
785 hci->bdaddr_set(hci, bdaddr.b);
786
787 hci_table[nb_hcis++] = hci;
788
789 return 0;
790}
791
792static void bt_vhci_add(int vlan_id)
793{
794 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
795
796 if (!vlan->slave)
797 fprintf(stderr, "qemu: warning: adding a VHCI to "
798 "an empty scatternet %i\n", vlan_id);
799
800 bt_vhci_init(bt_new_hci(vlan));
801}
802
803static struct bt_device_s *bt_device_add(const char *opt)
804{
805 struct bt_scatternet_s *vlan;
806 int vlan_id = 0;
807 char *endp = strstr(opt, ",vlan=");
808 int len = (endp ? endp - opt : strlen(opt)) + 1;
809 char devname[10];
810
811 pstrcpy(devname, MIN(sizeof(devname), len), opt);
812
813 if (endp) {
814 vlan_id = strtol(endp + 6, &endp, 0);
815 if (*endp) {
816 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
817 return 0;
818 }
819 }
820
821 vlan = qemu_find_bt_vlan(vlan_id);
822
823 if (!vlan->slave)
824 fprintf(stderr, "qemu: warning: adding a slave device to "
825 "an empty scatternet %i\n", vlan_id);
826
827 if (!strcmp(devname, "keyboard"))
828 return bt_keyboard_init(vlan);
829
830 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
831 return 0;
832}
833
834static int bt_parse(const char *opt)
835{
836 const char *endp, *p;
837 int vlan;
838
839 if (strstart(opt, "hci", &endp)) {
840 if (!*endp || *endp == ',') {
841 if (*endp)
842 if (!strstart(endp, ",vlan=", 0))
843 opt = endp + 1;
844
845 return bt_hci_parse(opt);
846 }
847 } else if (strstart(opt, "vhci", &endp)) {
848 if (!*endp || *endp == ',') {
849 if (*endp) {
850 if (strstart(endp, ",vlan=", &p)) {
851 vlan = strtol(p, (char **) &endp, 0);
852 if (*endp) {
853 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
854 return 1;
855 }
856 } else {
857 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
858 return 1;
859 }
860 } else
861 vlan = 0;
862
863 bt_vhci_add(vlan);
864 return 0;
865 }
866 } else if (strstart(opt, "device:", &endp))
867 return !bt_device_add(endp);
868
869 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
870 return 1;
871}
872
873/***********************************************************/
874/* QEMU Block devices */
875
876#define HD_ALIAS "index=%d,media=disk"
877#define CDROM_ALIAS "index=2,media=cdrom"
878#define FD_ALIAS "index=%d,if=floppy"
879#define PFLASH_ALIAS "if=pflash"
880#define MTD_ALIAS "if=mtd"
881#define SD_ALIAS "index=0,if=sd"
882
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100883static int drive_init_func(QemuOpts *opts, void *opaque)
884{
885 int *use_scsi = opaque;
886 int fatal_error = 0;
887
888 if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
889 if (fatal_error)
890 return 1;
891 }
892 return 0;
893}
894
895static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
896{
897 if (NULL == qemu_opt_get(opts, "snapshot")) {
898 qemu_opt_set(opts, "snapshot", "on");
899 }
900 return 0;
901}
902
903#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700904static int drive_opt_get_free_idx(void)
905{
906 int index;
907
908 for (index = 0; index < MAX_DRIVES; index++)
909 if (!drives_opt[index].used) {
910 drives_opt[index].used = 1;
911 return index;
912 }
913
914 return -1;
915}
916
917static int drive_get_free_idx(void)
918{
919 int index;
920
921 for (index = 0; index < MAX_DRIVES; index++)
922 if (!drives_table[index].used) {
923 drives_table[index].used = 1;
924 return index;
925 }
926
927 return -1;
928}
929
930int drive_add(const char *file, const char *fmt, ...)
931{
932 va_list ap;
933 int index = drive_opt_get_free_idx();
934
935 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
936 fprintf(stderr, "qemu: too many drives\n");
937 return -1;
938 }
939
940 drives_opt[index].file = file;
941 va_start(ap, fmt);
942 vsnprintf(drives_opt[index].opt,
943 sizeof(drives_opt[0].opt), fmt, ap);
944 va_end(ap);
David 'Digit' Turner92568952010-04-15 15:04:16 -0700945
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700946 nb_drives_opt++;
947 return index;
948}
949
950void drive_remove(int index)
951{
952 drives_opt[index].used = 0;
953 nb_drives_opt--;
954}
955
956int drive_get_index(BlockInterfaceType type, int bus, int unit)
957{
958 int index;
959
960 /* seek interface, bus and unit */
961
962 for (index = 0; index < MAX_DRIVES; index++)
963 if (drives_table[index].type == type &&
964 drives_table[index].bus == bus &&
965 drives_table[index].unit == unit &&
966 drives_table[index].used)
967 return index;
968
969 return -1;
970}
971
972int drive_get_max_bus(BlockInterfaceType type)
973{
974 int max_bus;
975 int index;
976
977 max_bus = -1;
978 for (index = 0; index < nb_drives; index++) {
979 if(drives_table[index].type == type &&
980 drives_table[index].bus > max_bus)
981 max_bus = drives_table[index].bus;
982 }
983 return max_bus;
984}
985
986const char *drive_get_serial(BlockDriverState *bdrv)
987{
988 int index;
989
990 for (index = 0; index < nb_drives; index++)
991 if (drives_table[index].bdrv == bdrv)
992 return drives_table[index].serial;
993
994 return "\0";
995}
996
997BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
998{
999 int index;
1000
1001 for (index = 0; index < nb_drives; index++)
1002 if (drives_table[index].bdrv == bdrv)
1003 return drives_table[index].onerror;
1004
1005 return BLOCK_ERR_STOP_ENOSPC;
1006}
1007
1008static void bdrv_format_print(void *opaque, const char *name)
1009{
1010 fprintf(stderr, " %s", name);
1011}
1012
1013void drive_uninit(BlockDriverState *bdrv)
1014{
1015 int i;
1016
1017 for (i = 0; i < MAX_DRIVES; i++)
1018 if (drives_table[i].bdrv == bdrv) {
1019 drives_table[i].bdrv = NULL;
1020 drives_table[i].used = 0;
1021 drive_remove(drives_table[i].drive_opt_idx);
1022 nb_drives--;
1023 break;
1024 }
1025}
1026
1027int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
1028{
1029 char buf[128];
1030 char file[1024];
1031 char devname[128];
1032 char serial[21];
1033 const char *mediastr = "";
1034 BlockInterfaceType type;
1035 enum { MEDIA_DISK, MEDIA_CDROM } media;
1036 int bus_id, unit_id;
1037 int cyls, heads, secs, translation;
1038 BlockDriverState *bdrv;
1039 BlockDriver *drv = NULL;
1040 QEMUMachine *machine = opaque;
1041 int max_devs;
1042 int index;
1043 int cache;
1044 int bdrv_flags, onerror;
1045 int drives_table_idx;
1046 char *str = arg->opt;
1047 static const char * const params[] = { "bus", "unit", "if", "index",
1048 "cyls", "heads", "secs", "trans",
1049 "media", "snapshot", "file",
1050 "cache", "format", "serial", "werror",
1051 NULL };
1052
1053 if (check_params(buf, sizeof(buf), params, str) < 0) {
1054 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
1055 buf, str);
1056 return -1;
1057 }
1058
1059 file[0] = 0;
1060 cyls = heads = secs = 0;
1061 bus_id = 0;
1062 unit_id = -1;
1063 translation = BIOS_ATA_TRANSLATION_AUTO;
1064 index = -1;
1065 cache = 3;
1066
1067 if (machine->use_scsi) {
1068 type = IF_SCSI;
1069 max_devs = MAX_SCSI_DEVS;
1070 pstrcpy(devname, sizeof(devname), "scsi");
1071 } else {
1072 type = IF_IDE;
1073 max_devs = MAX_IDE_DEVS;
1074 pstrcpy(devname, sizeof(devname), "ide");
1075 }
1076 media = MEDIA_DISK;
1077
1078 /* extract parameters */
1079
1080 if (get_param_value(buf, sizeof(buf), "bus", str)) {
1081 bus_id = strtol(buf, NULL, 0);
1082 if (bus_id < 0) {
1083 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
1084 return -1;
1085 }
1086 }
1087
1088 if (get_param_value(buf, sizeof(buf), "unit", str)) {
1089 unit_id = strtol(buf, NULL, 0);
1090 if (unit_id < 0) {
1091 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
1092 return -1;
1093 }
1094 }
1095
1096 if (get_param_value(buf, sizeof(buf), "if", str)) {
1097 pstrcpy(devname, sizeof(devname), buf);
1098 if (!strcmp(buf, "ide")) {
1099 type = IF_IDE;
1100 max_devs = MAX_IDE_DEVS;
1101 } else if (!strcmp(buf, "scsi")) {
1102 type = IF_SCSI;
1103 max_devs = MAX_SCSI_DEVS;
1104 } else if (!strcmp(buf, "floppy")) {
1105 type = IF_FLOPPY;
1106 max_devs = 0;
1107 } else if (!strcmp(buf, "pflash")) {
1108 type = IF_PFLASH;
1109 max_devs = 0;
1110 } else if (!strcmp(buf, "mtd")) {
1111 type = IF_MTD;
1112 max_devs = 0;
1113 } else if (!strcmp(buf, "sd")) {
1114 type = IF_SD;
1115 max_devs = 0;
1116 } else if (!strcmp(buf, "virtio")) {
1117 type = IF_VIRTIO;
1118 max_devs = 0;
1119 } else if (!strcmp(buf, "xen")) {
1120 type = IF_XEN;
1121 max_devs = 0;
1122 } else {
1123 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
1124 return -1;
1125 }
1126 }
1127
1128 if (get_param_value(buf, sizeof(buf), "index", str)) {
1129 index = strtol(buf, NULL, 0);
1130 if (index < 0) {
1131 fprintf(stderr, "qemu: '%s' invalid index\n", str);
1132 return -1;
1133 }
1134 }
1135
1136 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
1137 cyls = strtol(buf, NULL, 0);
1138 }
1139
1140 if (get_param_value(buf, sizeof(buf), "heads", str)) {
1141 heads = strtol(buf, NULL, 0);
1142 }
1143
1144 if (get_param_value(buf, sizeof(buf), "secs", str)) {
1145 secs = strtol(buf, NULL, 0);
1146 }
1147
1148 if (cyls || heads || secs) {
1149 if (cyls < 1 || cyls > 16383) {
1150 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
1151 return -1;
1152 }
1153 if (heads < 1 || heads > 16) {
1154 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
1155 return -1;
1156 }
1157 if (secs < 1 || secs > 63) {
1158 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
1159 return -1;
1160 }
1161 }
1162
1163 if (get_param_value(buf, sizeof(buf), "trans", str)) {
1164 if (!cyls) {
1165 fprintf(stderr,
1166 "qemu: '%s' trans must be used with cyls,heads and secs\n",
1167 str);
1168 return -1;
1169 }
1170 if (!strcmp(buf, "none"))
1171 translation = BIOS_ATA_TRANSLATION_NONE;
1172 else if (!strcmp(buf, "lba"))
1173 translation = BIOS_ATA_TRANSLATION_LBA;
1174 else if (!strcmp(buf, "auto"))
1175 translation = BIOS_ATA_TRANSLATION_AUTO;
1176 else {
1177 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
1178 return -1;
1179 }
1180 }
1181
1182 if (get_param_value(buf, sizeof(buf), "media", str)) {
1183 if (!strcmp(buf, "disk")) {
1184 media = MEDIA_DISK;
1185 } else if (!strcmp(buf, "cdrom")) {
1186 if (cyls || secs || heads) {
1187 fprintf(stderr,
1188 "qemu: '%s' invalid physical CHS format\n", str);
1189 return -1;
1190 }
1191 media = MEDIA_CDROM;
1192 } else {
1193 fprintf(stderr, "qemu: '%s' invalid media\n", str);
1194 return -1;
1195 }
1196 }
1197
1198 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
1199 if (!strcmp(buf, "on"))
1200 snapshot = 1;
1201 else if (!strcmp(buf, "off"))
1202 snapshot = 0;
1203 else {
1204 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
1205 return -1;
1206 }
1207 }
1208
1209 if (get_param_value(buf, sizeof(buf), "cache", str)) {
1210 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
1211 cache = 0;
1212 else if (!strcmp(buf, "writethrough"))
1213 cache = 1;
1214 else if (!strcmp(buf, "writeback"))
1215 cache = 2;
1216 else {
1217 fprintf(stderr, "qemu: invalid cache option\n");
1218 return -1;
1219 }
1220 }
1221
1222 if (get_param_value(buf, sizeof(buf), "format", str)) {
1223 if (strcmp(buf, "?") == 0) {
1224 fprintf(stderr, "qemu: Supported formats:");
1225 bdrv_iterate_format(bdrv_format_print, NULL);
1226 fprintf(stderr, "\n");
1227 return -1;
1228 }
1229 drv = bdrv_find_format(buf);
1230 if (!drv) {
1231 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
1232 return -1;
1233 }
1234 }
1235
1236 if (arg->file == NULL)
1237 get_param_value(file, sizeof(file), "file", str);
1238 else
1239 pstrcpy(file, sizeof(file), arg->file);
1240
1241 if (!get_param_value(serial, sizeof(serial), "serial", str))
1242 memset(serial, 0, sizeof(serial));
1243
1244 onerror = BLOCK_ERR_STOP_ENOSPC;
1245 if (get_param_value(buf, sizeof(serial), "werror", str)) {
1246 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
1247 fprintf(stderr, "werror is no supported by this format\n");
1248 return -1;
1249 }
1250 if (!strcmp(buf, "ignore"))
1251 onerror = BLOCK_ERR_IGNORE;
1252 else if (!strcmp(buf, "enospc"))
1253 onerror = BLOCK_ERR_STOP_ENOSPC;
1254 else if (!strcmp(buf, "stop"))
1255 onerror = BLOCK_ERR_STOP_ANY;
1256 else if (!strcmp(buf, "report"))
1257 onerror = BLOCK_ERR_REPORT;
1258 else {
1259 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
1260 return -1;
1261 }
1262 }
1263
1264 /* compute bus and unit according index */
1265
1266 if (index != -1) {
1267 if (bus_id != 0 || unit_id != -1) {
1268 fprintf(stderr,
1269 "qemu: '%s' index cannot be used with bus and unit\n", str);
1270 return -1;
1271 }
1272 if (max_devs == 0)
1273 {
1274 unit_id = index;
1275 bus_id = 0;
1276 } else {
1277 unit_id = index % max_devs;
1278 bus_id = index / max_devs;
1279 }
1280 }
1281
1282 /* if user doesn't specify a unit_id,
1283 * try to find the first free
1284 */
1285
1286 if (unit_id == -1) {
1287 unit_id = 0;
1288 while (drive_get_index(type, bus_id, unit_id) != -1) {
1289 unit_id++;
1290 if (max_devs && unit_id >= max_devs) {
1291 unit_id -= max_devs;
1292 bus_id++;
1293 }
1294 }
1295 }
1296
1297 /* check unit id */
1298
1299 if (max_devs && unit_id >= max_devs) {
1300 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
1301 str, unit_id, max_devs - 1);
1302 return -1;
1303 }
1304
1305 /*
1306 * ignore multiple definitions
1307 */
1308
1309 if (drive_get_index(type, bus_id, unit_id) != -1)
1310 return -2;
1311
1312 /* init */
1313
1314 if (type == IF_IDE || type == IF_SCSI)
1315 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
1316 if (max_devs)
1317 snprintf(buf, sizeof(buf), "%s%i%s%i",
1318 devname, bus_id, mediastr, unit_id);
1319 else
1320 snprintf(buf, sizeof(buf), "%s%s%i",
1321 devname, mediastr, unit_id);
1322 bdrv = bdrv_new(buf);
1323 drives_table_idx = drive_get_free_idx();
1324 drives_table[drives_table_idx].bdrv = bdrv;
1325 drives_table[drives_table_idx].type = type;
1326 drives_table[drives_table_idx].bus = bus_id;
1327 drives_table[drives_table_idx].unit = unit_id;
1328 drives_table[drives_table_idx].onerror = onerror;
1329 drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
1330 strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
1331 nb_drives++;
1332
1333 switch(type) {
1334 case IF_IDE:
1335 case IF_SCSI:
1336 case IF_XEN:
1337 switch(media) {
1338 case MEDIA_DISK:
1339 if (cyls != 0) {
1340 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
1341 bdrv_set_translation_hint(bdrv, translation);
1342 }
1343 break;
1344 case MEDIA_CDROM:
1345 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
1346 break;
1347 }
1348 break;
1349 case IF_SD:
1350 /* FIXME: This isn't really a floppy, but it's a reasonable
1351 approximation. */
1352 case IF_FLOPPY:
1353 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
1354 break;
1355 case IF_PFLASH:
1356 case IF_MTD:
1357 case IF_VIRTIO:
1358 break;
1359 case IF_COUNT:
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07001360 case IF_NONE:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001361 abort();
1362 }
1363 if (!file[0])
1364 return -2;
1365 bdrv_flags = 0;
1366 if (snapshot) {
1367 bdrv_flags |= BDRV_O_SNAPSHOT;
1368 cache = 2; /* always use write-back with snapshot */
1369 }
1370 if (cache == 0) /* no caching */
1371 bdrv_flags |= BDRV_O_NOCACHE;
1372 else if (cache == 2) /* write-back */
1373 bdrv_flags |= BDRV_O_CACHE_WB;
1374 else if (cache == 3) /* not specified */
1375 bdrv_flags |= BDRV_O_CACHE_DEF;
1376 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
1377 fprintf(stderr, "qemu: could not open disk image %s\n",
1378 file);
1379 return -1;
1380 }
1381 if (bdrv_key_required(bdrv))
1382 autostart = 0;
1383 return drives_table_idx;
1384}
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01001385#endif /* MAX_DRIVES */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001386
1387static void numa_add(const char *optarg)
1388{
1389 char option[128];
1390 char *endptr;
1391 unsigned long long value, endvalue;
1392 int nodenr;
1393
1394 optarg = get_opt_name(option, 128, optarg, ',') + 1;
1395 if (!strcmp(option, "node")) {
1396 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
1397 nodenr = nb_numa_nodes;
1398 } else {
1399 nodenr = strtoull(option, NULL, 10);
1400 }
1401
1402 if (get_param_value(option, 128, "mem", optarg) == 0) {
1403 node_mem[nodenr] = 0;
1404 } else {
1405 value = strtoull(option, &endptr, 0);
1406 switch (*endptr) {
1407 case 0: case 'M': case 'm':
1408 value <<= 20;
1409 break;
1410 case 'G': case 'g':
1411 value <<= 30;
1412 break;
1413 }
1414 node_mem[nodenr] = value;
1415 }
1416 if (get_param_value(option, 128, "cpus", optarg) == 0) {
1417 node_cpumask[nodenr] = 0;
1418 } else {
1419 value = strtoull(option, &endptr, 10);
1420 if (value >= 64) {
1421 value = 63;
1422 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
1423 } else {
1424 if (*endptr == '-') {
1425 endvalue = strtoull(endptr+1, &endptr, 10);
1426 if (endvalue >= 63) {
1427 endvalue = 62;
1428 fprintf(stderr,
1429 "only 63 CPUs in NUMA mode supported.\n");
1430 }
1431 value = (1 << (endvalue + 1)) - (1 << value);
1432 } else {
1433 value = 1 << value;
1434 }
1435 }
1436 node_cpumask[nodenr] = value;
1437 }
1438 nb_numa_nodes++;
1439 }
1440 return;
1441}
1442
1443/***********************************************************/
1444/* USB devices */
1445
1446static USBPort *used_usb_ports;
1447static USBPort *free_usb_ports;
1448
1449/* ??? Maybe change this to register a hub to keep track of the topology. */
1450void qemu_register_usb_port(USBPort *port, void *opaque, int index,
1451 usb_attachfn attach)
1452{
1453 port->opaque = opaque;
1454 port->index = index;
1455 port->attach = attach;
1456 port->next = free_usb_ports;
1457 free_usb_ports = port;
1458}
1459
1460int usb_device_add_dev(USBDevice *dev)
1461{
1462 USBPort *port;
1463
1464 /* Find a USB port to add the device to. */
1465 port = free_usb_ports;
1466 if (!port->next) {
1467 USBDevice *hub;
1468
1469 /* Create a new hub and chain it on. */
1470 free_usb_ports = NULL;
1471 port->next = used_usb_ports;
1472 used_usb_ports = port;
1473
1474 hub = usb_hub_init(VM_USB_HUB_SIZE);
1475 usb_attach(port, hub);
1476 port = free_usb_ports;
1477 }
1478
1479 free_usb_ports = port->next;
1480 port->next = used_usb_ports;
1481 used_usb_ports = port;
1482 usb_attach(port, dev);
1483 return 0;
1484}
1485
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001486#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001487static void usb_msd_password_cb(void *opaque, int err)
1488{
1489 USBDevice *dev = opaque;
1490
1491 if (!err)
1492 usb_device_add_dev(dev);
1493 else
1494 dev->handle_destroy(dev);
1495}
David 'Digit' Turner3266b512010-05-10 18:44:56 -07001496#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001497
1498static int usb_device_add(const char *devname, int is_hotplug)
1499{
1500 const char *p;
1501 USBDevice *dev;
1502
1503 if (!free_usb_ports)
1504 return -1;
1505
1506 if (strstart(devname, "host:", &p)) {
1507 dev = usb_host_device_open(p);
1508 } else if (!strcmp(devname, "mouse")) {
1509 dev = usb_mouse_init();
1510 } else if (!strcmp(devname, "tablet")) {
1511 dev = usb_tablet_init();
1512 } else if (!strcmp(devname, "keyboard")) {
1513 dev = usb_keyboard_init();
1514 } else if (strstart(devname, "disk:", &p)) {
1515#if 0
1516 BlockDriverState *bs;
1517#endif
1518 dev = usb_msd_init(p);
1519 if (!dev)
1520 return -1;
1521#if 0
1522 bs = usb_msd_get_bdrv(dev);
1523 if (bdrv_key_required(bs)) {
1524 autostart = 0;
1525 if (is_hotplug) {
1526 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
1527 dev);
1528 return 0;
1529 }
1530 }
1531 } else if (!strcmp(devname, "wacom-tablet")) {
1532 dev = usb_wacom_init();
1533 } else if (strstart(devname, "serial:", &p)) {
1534 dev = usb_serial_init(p);
1535#ifdef CONFIG_BRLAPI
1536 } else if (!strcmp(devname, "braille")) {
1537 dev = usb_baum_init();
1538#endif
1539 } else if (strstart(devname, "net:", &p)) {
1540 int nic = nb_nics;
1541
1542 if (net_client_init("nic", p) < 0)
1543 return -1;
1544 nd_table[nic].model = "usb";
1545 dev = usb_net_init(&nd_table[nic]);
1546 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
1547 dev = usb_bt_init(devname[2] ? hci_init(p) :
1548 bt_new_hci(qemu_find_bt_vlan(0)));
1549#endif
1550 } else {
1551 return -1;
1552 }
1553 if (!dev)
1554 return -1;
1555
1556 return usb_device_add_dev(dev);
1557}
1558
1559int usb_device_del_addr(int bus_num, int addr)
1560{
1561 USBPort *port;
1562 USBPort **lastp;
1563 USBDevice *dev;
1564
1565 if (!used_usb_ports)
1566 return -1;
1567
1568 if (bus_num != 0)
1569 return -1;
1570
1571 lastp = &used_usb_ports;
1572 port = used_usb_ports;
1573 while (port && port->dev->addr != addr) {
1574 lastp = &port->next;
1575 port = port->next;
1576 }
1577
1578 if (!port)
1579 return -1;
1580
1581 dev = port->dev;
1582 *lastp = port->next;
1583 usb_attach(port, NULL);
1584 dev->handle_destroy(dev);
1585 port->next = free_usb_ports;
1586 free_usb_ports = port;
1587 return 0;
1588}
1589
1590static int usb_device_del(const char *devname)
1591{
1592 int bus_num, addr;
1593 const char *p;
1594
1595 if (strstart(devname, "host:", &p))
1596 return usb_host_device_close(p);
1597
1598 if (!used_usb_ports)
1599 return -1;
1600
1601 p = strchr(devname, '.');
1602 if (!p)
1603 return -1;
1604 bus_num = strtoul(devname, NULL, 0);
1605 addr = strtoul(p + 1, NULL, 0);
1606
1607 return usb_device_del_addr(bus_num, addr);
1608}
1609
1610void do_usb_add(Monitor *mon, const char *devname)
1611{
1612 usb_device_add(devname, 1);
1613}
1614
1615void do_usb_del(Monitor *mon, const char *devname)
1616{
1617 usb_device_del(devname);
1618}
1619
1620void usb_info(Monitor *mon)
1621{
1622 USBDevice *dev;
1623 USBPort *port;
1624 const char *speed_str;
1625
1626 if (!usb_enabled) {
1627 monitor_printf(mon, "USB support not enabled\n");
1628 return;
1629 }
1630
1631 for (port = used_usb_ports; port; port = port->next) {
1632 dev = port->dev;
1633 if (!dev)
1634 continue;
1635 switch(dev->speed) {
1636 case USB_SPEED_LOW:
1637 speed_str = "1.5";
1638 break;
1639 case USB_SPEED_FULL:
1640 speed_str = "12";
1641 break;
1642 case USB_SPEED_HIGH:
1643 speed_str = "480";
1644 break;
1645 default:
1646 speed_str = "?";
1647 break;
1648 }
1649 monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
1650 0, dev->addr, speed_str, dev->devname);
1651 }
1652}
1653
1654/***********************************************************/
1655/* PCMCIA/Cardbus */
1656
1657static struct pcmcia_socket_entry_s {
1658 PCMCIASocket *socket;
1659 struct pcmcia_socket_entry_s *next;
1660} *pcmcia_sockets = 0;
1661
1662void pcmcia_socket_register(PCMCIASocket *socket)
1663{
1664 struct pcmcia_socket_entry_s *entry;
1665
1666 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
1667 entry->socket = socket;
1668 entry->next = pcmcia_sockets;
1669 pcmcia_sockets = entry;
1670}
1671
1672void pcmcia_socket_unregister(PCMCIASocket *socket)
1673{
1674 struct pcmcia_socket_entry_s *entry, **ptr;
1675
1676 ptr = &pcmcia_sockets;
1677 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
1678 if (entry->socket == socket) {
1679 *ptr = entry->next;
1680 qemu_free(entry);
1681 }
1682}
1683
1684void pcmcia_info(Monitor *mon)
1685{
1686 struct pcmcia_socket_entry_s *iter;
1687
1688 if (!pcmcia_sockets)
1689 monitor_printf(mon, "No PCMCIA sockets\n");
1690
1691 for (iter = pcmcia_sockets; iter; iter = iter->next)
1692 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
1693 iter->socket->attached ? iter->socket->card_string :
1694 "Empty");
1695}
1696
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001697/***********************************************************/
1698/* ram save/restore */
1699
1700static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
1701{
1702 int v;
1703
1704 v = qemu_get_byte(f);
1705 switch(v) {
1706 case 0:
1707 if (qemu_get_buffer(f, buf, len) != len)
1708 return -EIO;
1709 break;
1710 case 1:
1711 v = qemu_get_byte(f);
1712 memset(buf, v, len);
1713 break;
1714 default:
1715 return -EINVAL;
1716 }
1717
1718 if (qemu_file_has_error(f))
1719 return -EIO;
1720
1721 return 0;
1722}
1723
1724static int ram_load_v1(QEMUFile *f, void *opaque)
1725{
1726 int ret;
1727 ram_addr_t i;
1728
1729 if (qemu_get_be32(f) != last_ram_offset)
1730 return -EINVAL;
1731 for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
1732 ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
1733 if (ret)
1734 return ret;
1735 }
1736 return 0;
1737}
1738
1739#define BDRV_HASH_BLOCK_SIZE 1024
1740#define IOBUF_SIZE 4096
1741#define RAM_CBLOCK_MAGIC 0xfabe
1742
1743typedef struct RamDecompressState {
1744 z_stream zstream;
1745 QEMUFile *f;
1746 uint8_t buf[IOBUF_SIZE];
1747} RamDecompressState;
1748
1749static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
1750{
1751 int ret;
1752 memset(s, 0, sizeof(*s));
1753 s->f = f;
1754 ret = inflateInit(&s->zstream);
1755 if (ret != Z_OK)
1756 return -1;
1757 return 0;
1758}
1759
1760static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
1761{
1762 int ret, clen;
1763
1764 s->zstream.avail_out = len;
1765 s->zstream.next_out = buf;
1766 while (s->zstream.avail_out > 0) {
1767 if (s->zstream.avail_in == 0) {
1768 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
1769 return -1;
1770 clen = qemu_get_be16(s->f);
1771 if (clen > IOBUF_SIZE)
1772 return -1;
1773 qemu_get_buffer(s->f, s->buf, clen);
1774 s->zstream.avail_in = clen;
1775 s->zstream.next_in = s->buf;
1776 }
1777 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
1778 if (ret != Z_OK && ret != Z_STREAM_END) {
1779 return -1;
1780 }
1781 }
1782 return 0;
1783}
1784
1785static void ram_decompress_close(RamDecompressState *s)
1786{
1787 inflateEnd(&s->zstream);
1788}
1789
1790#define RAM_SAVE_FLAG_FULL 0x01
1791#define RAM_SAVE_FLAG_COMPRESS 0x02
1792#define RAM_SAVE_FLAG_MEM_SIZE 0x04
1793#define RAM_SAVE_FLAG_PAGE 0x08
1794#define RAM_SAVE_FLAG_EOS 0x10
1795
1796static int is_dup_page(uint8_t *page, uint8_t ch)
1797{
1798 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
1799 uint32_t *array = (uint32_t *)page;
1800 int i;
1801
1802 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
1803 if (array[i] != val)
1804 return 0;
1805 }
1806
1807 return 1;
1808}
1809
1810static int ram_save_block(QEMUFile *f)
1811{
1812 static ram_addr_t current_addr = 0;
1813 ram_addr_t saved_addr = current_addr;
1814 ram_addr_t addr = 0;
1815 int found = 0;
1816
1817 while (addr < last_ram_offset) {
1818 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
1819 uint8_t *p;
1820
1821 cpu_physical_memory_reset_dirty(current_addr,
1822 current_addr + TARGET_PAGE_SIZE,
1823 MIGRATION_DIRTY_FLAG);
1824
1825 p = qemu_get_ram_ptr(current_addr);
1826
1827 if (is_dup_page(p, *p)) {
1828 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
1829 qemu_put_byte(f, *p);
1830 } else {
1831 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
1832 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
1833 }
1834
1835 found = 1;
1836 break;
1837 }
1838 addr += TARGET_PAGE_SIZE;
1839 current_addr = (saved_addr + addr) % last_ram_offset;
1840 }
1841
1842 return found;
1843}
1844
1845static uint64_t bytes_transferred = 0;
1846
1847static ram_addr_t ram_save_remaining(void)
1848{
1849 ram_addr_t addr;
1850 ram_addr_t count = 0;
1851
1852 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
1853 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
1854 count++;
1855 }
1856
1857 return count;
1858}
1859
1860uint64_t ram_bytes_remaining(void)
1861{
1862 return ram_save_remaining() * TARGET_PAGE_SIZE;
1863}
1864
1865uint64_t ram_bytes_transferred(void)
1866{
1867 return bytes_transferred;
1868}
1869
1870uint64_t ram_bytes_total(void)
1871{
1872 return last_ram_offset;
1873}
1874
1875static int ram_save_live(QEMUFile *f, int stage, void *opaque)
1876{
1877 ram_addr_t addr;
1878 uint64_t bytes_transferred_last;
1879 double bwidth = 0;
1880 uint64_t expected_time = 0;
1881
1882 cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX);
1883
1884 if (stage == 1) {
1885 /* Make sure all dirty bits are set */
1886 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
1887 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
1888 cpu_physical_memory_set_dirty(addr);
1889 }
1890
1891 /* Enable dirty memory tracking */
1892 cpu_physical_memory_set_dirty_tracking(1);
1893
1894 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
1895 }
1896
1897 bytes_transferred_last = bytes_transferred;
David Turner6a9ef172010-09-09 22:54:36 +02001898 bwidth = qemu_get_clock_ns(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001899
1900 while (!qemu_file_rate_limit(f)) {
1901 int ret;
1902
1903 ret = ram_save_block(f);
1904 bytes_transferred += ret * TARGET_PAGE_SIZE;
1905 if (ret == 0) /* no more blocks */
1906 break;
1907 }
1908
David Turner6a9ef172010-09-09 22:54:36 +02001909 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001910 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
1911
1912 /* if we haven't transferred anything this round, force expected_time to a
1913 * a very high value, but without crashing */
1914 if (bwidth == 0)
1915 bwidth = 0.000001;
1916
1917 /* try transferring iterative blocks of memory */
1918
1919 if (stage == 3) {
1920
1921 /* flush all remaining blocks regardless of rate limiting */
1922 while (ram_save_block(f) != 0) {
1923 bytes_transferred += TARGET_PAGE_SIZE;
1924 }
1925 cpu_physical_memory_set_dirty_tracking(0);
1926 }
1927
1928 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
1929
1930 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
1931
1932 return (stage == 2) && (expected_time <= migrate_max_downtime());
1933}
1934
1935static int ram_load_dead(QEMUFile *f, void *opaque)
1936{
1937 RamDecompressState s1, *s = &s1;
1938 uint8_t buf[10];
1939 ram_addr_t i;
1940
1941 if (ram_decompress_open(s, f) < 0)
1942 return -EINVAL;
1943 for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
1944 if (ram_decompress_buf(s, buf, 1) < 0) {
1945 fprintf(stderr, "Error while reading ram block header\n");
1946 goto error;
1947 }
1948 if (buf[0] == 0) {
1949 if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
1950 BDRV_HASH_BLOCK_SIZE) < 0) {
1951 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
1952 goto error;
1953 }
1954 } else {
1955 error:
1956 printf("Error block header\n");
1957 return -EINVAL;
1958 }
1959 }
1960 ram_decompress_close(s);
1961
1962 return 0;
1963}
1964
1965static int ram_load(QEMUFile *f, void *opaque, int version_id)
1966{
1967 ram_addr_t addr;
1968 int flags;
1969
1970 if (version_id == 1)
1971 return ram_load_v1(f, opaque);
1972
1973 if (version_id == 2) {
1974 if (qemu_get_be32(f) != last_ram_offset)
1975 return -EINVAL;
1976 return ram_load_dead(f, opaque);
1977 }
1978
1979 if (version_id != 3)
1980 return -EINVAL;
1981
1982 do {
1983 addr = qemu_get_be64(f);
1984
1985 flags = addr & ~TARGET_PAGE_MASK;
1986 addr &= TARGET_PAGE_MASK;
1987
1988 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
1989 if (addr != last_ram_offset)
1990 return -EINVAL;
1991 }
1992
1993 if (flags & RAM_SAVE_FLAG_FULL) {
1994 if (ram_load_dead(f, opaque) < 0)
1995 return -EINVAL;
1996 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07001997
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001998 if (flags & RAM_SAVE_FLAG_COMPRESS) {
1999 uint8_t ch = qemu_get_byte(f);
2000 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
2001 } else if (flags & RAM_SAVE_FLAG_PAGE)
2002 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
2003 } while (!(flags & RAM_SAVE_FLAG_EOS));
2004
2005 return 0;
2006}
2007
2008void qemu_service_io(void)
2009{
2010 qemu_notify_event();
2011}
2012
2013/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002014/* machine registration */
2015
2016static QEMUMachine *first_machine = NULL;
2017QEMUMachine *current_machine = NULL;
2018
2019int qemu_register_machine(QEMUMachine *m)
2020{
2021 QEMUMachine **pm;
2022 pm = &first_machine;
2023 while (*pm != NULL)
2024 pm = &(*pm)->next;
2025 m->next = NULL;
2026 *pm = m;
2027 return 0;
2028}
2029
2030static QEMUMachine *find_machine(const char *name)
2031{
2032 QEMUMachine *m;
2033
2034 for(m = first_machine; m != NULL; m = m->next) {
2035 if (!strcmp(m->name, name))
2036 return m;
2037 }
2038 return NULL;
2039}
2040
2041static QEMUMachine *find_default_machine(void)
2042{
2043 QEMUMachine *m;
2044
2045 for(m = first_machine; m != NULL; m = m->next) {
2046 if (m->is_default) {
2047 return m;
2048 }
2049 }
2050 return NULL;
2051}
2052
2053/***********************************************************/
2054/* main execution loop */
2055
2056static void gui_update(void *opaque)
2057{
2058 uint64_t interval = GUI_REFRESH_INTERVAL;
2059 DisplayState *ds = opaque;
2060 DisplayChangeListener *dcl = ds->listeners;
2061
2062 dpy_refresh(ds);
2063
2064 while (dcl != NULL) {
2065 if (dcl->gui_timer_interval &&
2066 dcl->gui_timer_interval < interval)
2067 interval = dcl->gui_timer_interval;
2068 dcl = dcl->next;
2069 }
David 'Digit' Turner5973c772011-05-10 07:06:00 +02002070 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002071}
2072
2073static void nographic_update(void *opaque)
2074{
2075 uint64_t interval = GUI_REFRESH_INTERVAL;
2076
David 'Digit' Turner5973c772011-05-10 07:06:00 +02002077 qemu_mod_timer(nographic_timer, interval + qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002078}
2079
2080struct vm_change_state_entry {
2081 VMChangeStateHandler *cb;
2082 void *opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002083 QLIST_ENTRY (vm_change_state_entry) entries;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002084};
2085
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002086static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002087
2088VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
2089 void *opaque)
2090{
2091 VMChangeStateEntry *e;
2092
2093 e = qemu_mallocz(sizeof (*e));
2094
2095 e->cb = cb;
2096 e->opaque = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002097 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002098 return e;
2099}
2100
2101void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
2102{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002103 QLIST_REMOVE (e, entries);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002104 qemu_free (e);
2105}
2106
David 'Digit' Turner23ca2ae2011-06-01 16:14:53 +02002107void vm_state_notify(int running, int reason)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002108{
2109 VMChangeStateEntry *e;
2110
2111 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
2112 e->cb(e->opaque, running, reason);
2113 }
2114}
2115
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002116void vm_start(void)
2117{
2118 if (!vm_running) {
2119 cpu_enable_ticks();
2120 vm_running = 1;
2121 vm_state_notify(1, 0);
David Turner6a9ef172010-09-09 22:54:36 +02002122 //qemu_rearm_alarm_timer(alarm_timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002123 resume_all_vcpus();
2124 }
2125}
2126
2127/* reset/shutdown handler */
2128
2129typedef struct QEMUResetEntry {
2130 QEMUResetHandler *func;
2131 void *opaque;
2132 int order;
2133 struct QEMUResetEntry *next;
2134} QEMUResetEntry;
2135
2136static QEMUResetEntry *first_reset_entry;
2137static int reset_requested;
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002138static int shutdown_requested, shutdown_signal = -1;
2139static pid_t shutdown_pid;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002140static int powerdown_requested;
David 'Digit' Turner23ca2ae2011-06-01 16:14:53 +02002141int debug_requested;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002142static int vmstop_requested;
2143
2144int qemu_shutdown_requested(void)
2145{
2146 int r = shutdown_requested;
2147 shutdown_requested = 0;
2148 return r;
2149}
2150
2151int qemu_reset_requested(void)
2152{
2153 int r = reset_requested;
2154 reset_requested = 0;
2155 return r;
2156}
2157
2158int qemu_powerdown_requested(void)
2159{
2160 int r = powerdown_requested;
2161 powerdown_requested = 0;
2162 return r;
2163}
2164
2165static int qemu_debug_requested(void)
2166{
2167 int r = debug_requested;
2168 debug_requested = 0;
2169 return r;
2170}
2171
2172static int qemu_vmstop_requested(void)
2173{
2174 int r = vmstop_requested;
2175 vmstop_requested = 0;
2176 return r;
2177}
2178
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002179void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
2180{
2181 QEMUResetEntry **pre, *re;
2182
2183 pre = &first_reset_entry;
2184 while (*pre != NULL && (*pre)->order >= order) {
2185 pre = &(*pre)->next;
2186 }
2187 re = qemu_mallocz(sizeof(QEMUResetEntry));
2188 re->func = func;
2189 re->opaque = opaque;
2190 re->order = order;
2191 re->next = NULL;
2192 *pre = re;
2193}
2194
2195void qemu_system_reset(void)
2196{
2197 QEMUResetEntry *re;
2198
2199 /* reset all devices */
2200 for(re = first_reset_entry; re != NULL; re = re->next) {
2201 re->func(re->opaque);
2202 }
2203}
2204
2205void qemu_system_reset_request(void)
2206{
2207 if (no_reboot) {
2208 shutdown_requested = 1;
2209 } else {
2210 reset_requested = 1;
2211 }
2212 qemu_notify_event();
2213}
2214
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002215void qemu_system_killed(int signal, pid_t pid)
2216{
2217 shutdown_signal = signal;
2218 shutdown_pid = pid;
2219 qemu_system_shutdown_request();
2220}
2221
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002222void qemu_system_shutdown_request(void)
2223{
2224 shutdown_requested = 1;
2225 qemu_notify_event();
2226}
2227
2228void qemu_system_powerdown_request(void)
2229{
2230 powerdown_requested = 1;
2231 qemu_notify_event();
2232}
2233
2234#ifdef CONFIG_IOTHREAD
2235static void qemu_system_vmstop_request(int reason)
2236{
2237 vmstop_requested = reason;
2238 qemu_notify_event();
2239}
2240#endif
2241
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002242void main_loop_wait(int timeout)
2243{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002244 fd_set rfds, wfds, xfds;
2245 int ret, nfds;
2246 struct timeval tv;
2247
2248 qemu_bh_update_timeout(&timeout);
2249
David 'Digit' Turner23ca2ae2011-06-01 16:14:53 +02002250 os_host_main_loop_wait(&timeout);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002251
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002252
2253 tv.tv_sec = timeout / 1000;
2254 tv.tv_usec = (timeout % 1000) * 1000;
2255
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002256 /* poll any events */
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002257
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002258 /* XXX: separate device handlers from system ones */
2259 nfds = -1;
2260 FD_ZERO(&rfds);
2261 FD_ZERO(&wfds);
2262 FD_ZERO(&xfds);
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002263 qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002264 if (slirp_is_inited()) {
2265 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2266 }
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002267
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002268 qemu_mutex_unlock_iothread();
2269 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
2270 qemu_mutex_lock_iothread();
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002271 qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002272 if (slirp_is_inited()) {
2273 if (ret < 0) {
2274 FD_ZERO(&rfds);
2275 FD_ZERO(&wfds);
2276 FD_ZERO(&xfds);
2277 }
2278 slirp_select_poll(&rfds, &wfds, &xfds);
2279 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002280 charpipe_poll();
2281
David Turner6a9ef172010-09-09 22:54:36 +02002282 qemu_run_all_timers();
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002283
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002284 /* Check bottom-halves last in case any of the earlier events triggered
2285 them. */
2286 qemu_bh_poll();
2287
2288}
2289
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002290static int vm_can_run(void)
2291{
2292 if (powerdown_requested)
2293 return 0;
2294 if (reset_requested)
2295 return 0;
2296 if (shutdown_requested)
2297 return 0;
2298 if (debug_requested)
2299 return 0;
2300 return 1;
2301}
2302
2303static void main_loop(void)
2304{
2305 int r;
2306
2307#ifdef CONFIG_IOTHREAD
2308 qemu_system_ready = 1;
2309 qemu_cond_broadcast(&qemu_system_cond);
2310#endif
2311
2312 for (;;) {
2313 do {
2314#ifdef CONFIG_PROFILER
2315 int64_t ti;
2316#endif
2317#ifndef CONFIG_IOTHREAD
2318 tcg_cpu_exec();
2319#endif
2320#ifdef CONFIG_PROFILER
2321 ti = profile_getclock();
2322#endif
2323 main_loop_wait(qemu_calculate_timeout());
2324#ifdef CONFIG_PROFILER
2325 dev_time += profile_getclock() - ti;
2326#endif
rich canningsd952f282011-03-01 15:40:09 -08002327
2328 if (rotate_logs_requested) {
2329 FILE* new_dns_log_fd = rotate_qemu_log(get_slirp_dns_log_fd(),
2330 dns_log_filename);
2331 FILE* new_drop_log_fd = rotate_qemu_log(get_slirp_drop_log_fd(),
2332 drop_log_filename);
2333 slirp_dns_log_fd(new_dns_log_fd);
2334 slirp_drop_log_fd(new_drop_log_fd);
2335 reset_rotate_qemu_logs_request();
2336 }
2337
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002338 } while (vm_can_run());
2339
2340 if (qemu_debug_requested())
2341 vm_stop(EXCP_DEBUG);
2342 if (qemu_shutdown_requested()) {
2343 if (no_shutdown) {
2344 vm_stop(0);
2345 no_shutdown = 0;
Tim Baverstock24204cc2010-11-25 11:37:43 +00002346 } else {
Tim Baverstock24204cc2010-11-25 11:37:43 +00002347 if (savevm_on_exit != NULL) {
2348 do_savevm(cur_mon, savevm_on_exit);
2349 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002350 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00002351 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002352 }
2353 if (qemu_reset_requested()) {
2354 pause_all_vcpus();
2355 qemu_system_reset();
2356 resume_all_vcpus();
2357 }
2358 if (qemu_powerdown_requested())
2359 qemu_system_powerdown();
2360 if ((r = qemu_vmstop_requested()))
2361 vm_stop(r);
2362 }
2363 pause_all_vcpus();
2364}
2365
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07002366void version(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002367{
2368 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
2369}
2370
2371void qemu_help(int exitcode)
2372{
2373 version();
2374 printf("usage: %s [options] [disk_image]\n"
2375 "\n"
2376 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2377 "\n"
2378#define DEF(option, opt_arg, opt_enum, opt_help) \
2379 opt_help
2380#define DEFHEADING(text) stringify(text) "\n"
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002381#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002382#undef DEF
2383#undef DEFHEADING
2384#undef GEN_DOCS
2385 "\n"
2386 "During emulation, the following keys are useful:\n"
2387 "ctrl-alt-f toggle full screen\n"
2388 "ctrl-alt-n switch to virtual console 'n'\n"
2389 "ctrl-alt toggle mouse and keyboard grab\n"
2390 "\n"
2391 "When using -nographic, press 'ctrl-a h' to get some help.\n"
2392 ,
2393 "qemu",
2394 DEFAULT_RAM_SIZE,
2395#ifndef _WIN32
2396 DEFAULT_NETWORK_SCRIPT,
2397 DEFAULT_NETWORK_DOWN_SCRIPT,
2398#endif
2399 DEFAULT_GDBSTUB_PORT,
2400 "/tmp/qemu.log");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002401 QEMU_EXIT(exitcode);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002402}
2403
2404#define HAS_ARG 0x0001
2405
2406enum {
2407#define DEF(option, opt_arg, opt_enum, opt_help) \
2408 opt_enum,
2409#define DEFHEADING(text)
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002410#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002411#undef DEF
2412#undef DEFHEADING
2413#undef GEN_DOCS
2414};
2415
2416typedef struct QEMUOption {
2417 const char *name;
2418 int flags;
2419 int index;
2420} QEMUOption;
2421
2422static const QEMUOption qemu_options[] = {
2423 { "h", 0, QEMU_OPTION_h },
2424#define DEF(option, opt_arg, opt_enum, opt_help) \
2425 { option, opt_arg, opt_enum },
2426#define DEFHEADING(text)
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002427#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002428#undef DEF
2429#undef DEFHEADING
2430#undef GEN_DOCS
2431 { NULL, 0, 0 },
2432};
2433
2434#ifdef HAS_AUDIO
2435struct soundhw soundhw[] = {
2436#ifdef HAS_AUDIO_CHOICE
2437#if defined(TARGET_I386) || defined(TARGET_MIPS)
2438 {
2439 "pcspk",
2440 "PC speaker",
2441 0,
2442 1,
2443 { .init_isa = pcspk_audio_init }
2444 },
2445#endif
2446
2447#ifdef CONFIG_SB16
2448 {
2449 "sb16",
2450 "Creative Sound Blaster 16",
2451 0,
2452 1,
2453 { .init_isa = SB16_init }
2454 },
2455#endif
2456
2457#ifdef CONFIG_CS4231A
2458 {
2459 "cs4231a",
2460 "CS4231A",
2461 0,
2462 1,
2463 { .init_isa = cs4231a_init }
2464 },
2465#endif
2466
2467#ifdef CONFIG_ADLIB
2468 {
2469 "adlib",
2470#ifdef HAS_YMF262
2471 "Yamaha YMF262 (OPL3)",
2472#else
2473 "Yamaha YM3812 (OPL2)",
2474#endif
2475 0,
2476 1,
2477 { .init_isa = Adlib_init }
2478 },
2479#endif
2480
2481#ifdef CONFIG_GUS
2482 {
2483 "gus",
2484 "Gravis Ultrasound GF1",
2485 0,
2486 1,
2487 { .init_isa = GUS_init }
2488 },
2489#endif
2490
2491#ifdef CONFIG_AC97
2492 {
2493 "ac97",
2494 "Intel 82801AA AC97 Audio",
2495 0,
2496 0,
2497 { .init_pci = ac97_init }
2498 },
2499#endif
2500
2501#ifdef CONFIG_ES1370
2502 {
2503 "es1370",
2504 "ENSONIQ AudioPCI ES1370",
2505 0,
2506 0,
2507 { .init_pci = es1370_init }
2508 },
2509#endif
2510
2511#endif /* HAS_AUDIO_CHOICE */
2512
2513 { NULL, NULL, 0, 0, { NULL } }
2514};
2515
2516static void select_soundhw (const char *optarg)
2517{
2518 struct soundhw *c;
2519
2520 if (*optarg == '?') {
2521 show_valid_cards:
2522
2523 printf ("Valid sound card names (comma separated):\n");
2524 for (c = soundhw; c->name; ++c) {
2525 printf ("%-11s %s\n", c->name, c->descr);
2526 }
2527 printf ("\n-soundhw all will enable all of the above\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002528 if (*optarg != '?') {
2529 PANIC("Unknown sound card name: %s", optarg);
2530 } else {
2531 QEMU_EXIT(0);
2532 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002533 }
2534 else {
2535 size_t l;
2536 const char *p;
2537 char *e;
2538 int bad_card = 0;
2539
2540 if (!strcmp (optarg, "all")) {
2541 for (c = soundhw; c->name; ++c) {
2542 c->enabled = 1;
2543 }
2544 return;
2545 }
2546
2547 p = optarg;
2548 while (*p) {
2549 e = strchr (p, ',');
2550 l = !e ? strlen (p) : (size_t) (e - p);
2551
2552 for (c = soundhw; c->name; ++c) {
2553 if (!strncmp (c->name, p, l)) {
2554 c->enabled = 1;
2555 break;
2556 }
2557 }
2558
2559 if (!c->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002560#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002561 if (l > 80) {
2562 fprintf (stderr,
2563 "Unknown sound card name (too big to show)\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002564 } else {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002565 fprintf (stderr, "Unknown sound card name `%.*s'\n",
2566 (int) l, p);
2567 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002568#endif // !CONFIG_ANDROID
2569 bad_card = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002570 }
2571 p += l + (e != NULL);
2572 }
2573
2574 if (bad_card)
2575 goto show_valid_cards;
2576 }
2577}
2578#endif
2579
2580static void select_vgahw (const char *p)
2581{
2582 const char *opts;
2583
2584 cirrus_vga_enabled = 0;
2585 std_vga_enabled = 0;
2586 vmsvga_enabled = 0;
2587 xenfb_enabled = 0;
2588 if (strstart(p, "std", &opts)) {
2589 std_vga_enabled = 1;
2590 } else if (strstart(p, "cirrus", &opts)) {
2591 cirrus_vga_enabled = 1;
2592 } else if (strstart(p, "vmware", &opts)) {
2593 vmsvga_enabled = 1;
2594 } else if (strstart(p, "xenfb", &opts)) {
2595 xenfb_enabled = 1;
2596 } else if (!strstart(p, "none", &opts)) {
2597 invalid_vga:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07002598 PANIC("Unknown vga type: %s", p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002599 }
2600 while (*opts) {
2601 const char *nextopt;
2602
2603 if (strstart(opts, ",retrace=", &nextopt)) {
2604 opts = nextopt;
2605 if (strstart(opts, "dumb", &nextopt))
2606 vga_retrace_method = VGA_RETRACE_DUMB;
2607 else if (strstart(opts, "precise", &nextopt))
2608 vga_retrace_method = VGA_RETRACE_PRECISE;
2609 else goto invalid_vga;
2610 } else goto invalid_vga;
2611 opts = nextopt;
2612 }
2613}
2614
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002615int qemu_uuid_parse(const char *str, uint8_t *uuid)
2616{
2617 int ret;
2618
2619 if(strlen(str) != 36)
2620 return -1;
2621
2622 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
2623 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
2624 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
2625
2626 if(ret != 16)
2627 return -1;
2628
2629#ifdef TARGET_I386
2630 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
2631#endif
2632
2633 return 0;
2634}
2635
2636#define MAX_NET_CLIENTS 32
2637
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002638#ifdef _WIN32
2639/* Look for support files in the same directory as the executable. */
2640static char *find_datadir(const char *argv0)
2641{
2642 char *p;
2643 char buf[MAX_PATH];
2644 DWORD len;
2645
2646 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
2647 if (len == 0) {
2648 return NULL;
2649 }
2650
2651 buf[len] = 0;
2652 p = buf + len - 1;
2653 while (p != buf && *p != '\\')
2654 p--;
2655 *p = 0;
2656 if (access(buf, R_OK) == 0) {
2657 return qemu_strdup(buf);
2658 }
2659 return NULL;
2660}
2661#else /* !_WIN32 */
2662
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002663/* Similarly, return the location of the executable */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002664static char *find_datadir(const char *argv0)
2665{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002666 char *p = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002667 char buf[PATH_MAX];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002668
2669#if defined(__linux__)
2670 {
2671 int len;
2672 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
2673 if (len > 0) {
2674 buf[len] = 0;
2675 p = buf;
2676 }
2677 }
2678#elif defined(__FreeBSD__)
2679 {
2680 int len;
2681 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
2682 if (len > 0) {
2683 buf[len] = 0;
2684 p = buf;
2685 }
2686 }
2687#endif
2688 /* If we don't have any way of figuring out the actual executable
2689 location then try argv[0]. */
2690 if (!p) {
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002691 p = realpath(argv0, buf);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002692 if (!p) {
2693 return NULL;
2694 }
2695 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002696
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002697 return qemu_strdup(dirname(buf));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002698}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002699#endif
2700
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002701static char*
2702qemu_find_file_with_subdir(const char* data_dir, const char* subdir, const char* name)
2703{
2704 int len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
2705 char* buf = qemu_mallocz(len);
2706
2707 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
2708 VERBOSE_PRINT(init," trying to find: %s\n", buf);
2709 if (access(buf, R_OK)) {
2710 qemu_free(buf);
2711 return NULL;
2712 }
2713 return buf;
2714}
2715
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002716char *qemu_find_file(int type, const char *name)
2717{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002718 const char *subdir;
2719 char *buf;
2720
2721 /* If name contains path separators then try it as a straight path. */
2722 if ((strchr(name, '/') || strchr(name, '\\'))
2723 && access(name, R_OK) == 0) {
2724 return strdup(name);
2725 }
2726 switch (type) {
2727 case QEMU_FILE_TYPE_BIOS:
2728 subdir = "";
2729 break;
2730 case QEMU_FILE_TYPE_KEYMAP:
2731 subdir = "keymaps/";
2732 break;
2733 default:
2734 abort();
2735 }
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002736 buf = qemu_find_file_with_subdir(data_dir, subdir, name);
2737#ifdef CONFIG_ANDROID
2738 if (type == QEMU_FILE_TYPE_BIOS) {
2739 /* This case corresponds to the emulator being used as part of an
2740 * SDK installation. NOTE: data_dir is really $bindir. */
2741 if (buf == NULL)
2742 buf = qemu_find_file_with_subdir(data_dir, "lib/pc-bios/", name);
2743 /* This case corresponds to platform builds. */
2744 if (buf == NULL)
2745 buf = qemu_find_file_with_subdir(data_dir, "../usr/share/pc-bios/", name);
2746 /* Finally, try this for standalone builds under external/qemu */
2747 if (buf == NULL)
2748 buf = qemu_find_file_with_subdir(data_dir, "../../../prebuilt/common/pc-bios/", name);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002749 }
David 'Digit' Turner24d27522011-06-01 16:50:56 +02002750#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002751 return buf;
2752}
2753
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07002754static int
2755add_dns_server( const char* server_name )
2756{
2757 SockAddress addr;
2758
2759 if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
2760 fprintf(stdout,
2761 "### WARNING: can't resolve DNS server name '%s'\n",
2762 server_name );
2763 return -1;
2764 }
2765
2766 fprintf(stderr,
2767 "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
2768
2769 if ( slirp_add_dns_server( &addr ) < 0 ) {
2770 fprintf(stderr,
2771 "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
2772 return -1;
2773 }
2774 return 0;
2775}
2776
rich cannings7339b552011-02-16 13:43:44 -08002777/* Parses an integer
2778 * Pararm:
2779 * str String containing a number to be parsed.
2780 * result Passes the parsed integer in this argument
2781 * returns 0 if ok, -1 if failed
2782 */
2783int
2784parse_int(const char *str, int *result)
2785{
2786 char* r;
2787 *result = strtol(str, &r, 0);
2788 if (r == NULL || *r != '\0')
2789 return -1;
2790
2791 return 0;
2792}
2793
rich canningsd952f282011-03-01 15:40:09 -08002794#ifndef _WIN32
2795/*
2796 * Initializes the SIGUSR1 signal handler to clear Qemu logs.
2797 */
2798void init_qemu_clear_logs_sig() {
2799 struct sigaction act;
2800 sigfillset(&act.sa_mask);
2801 act.sa_flags = 0;
2802 act.sa_handler = rotate_qemu_logs_handler;
2803 if (sigaction(SIGUSR1, &act, NULL) == -1) {
2804 fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
2805 exit(-1);
2806 }
2807}
2808#endif
2809
2810
rich cannings7339b552011-02-16 13:43:44 -08002811
2812/* parses a null-terminated string specifying a network port (e.g., "80") or
2813 * port range (e.g., "[6666-7000]"). In case of a single port, lport and hport
2814 * are the same. Returns 0 on success, -1 on error. */
2815
2816int parse_port_range(const char *str, unsigned short *lport,
2817 unsigned short *hport) {
2818
2819 unsigned int low = 0, high = 0;
2820 char *p, *arg = strdup(str);
2821
2822 if ((*arg == '[') && ((p = strrchr(arg, ']')) != NULL)) {
2823 p = arg + 1; /* skip '[' */
2824 low = atoi(strtok(p, "-"));
2825 high = atoi(strtok(NULL, "-"));
2826 if ((low > 0) && (high > 0) && (low < high) && (high < 65535)) {
2827 *lport = low;
2828 *hport = high;
2829 }
2830 }
2831 else {
2832 low = atoi(arg);
2833 if ((0 < low) && (low < 65535)) {
2834 *lport = low;
2835 *hport = low;
2836 }
2837 }
2838 free(arg);
2839 if (low != 0)
2840 return 0;
2841 return -1;
2842}
2843
2844/*
2845 * Implements the generic port forwarding option
2846 */
2847void
2848net_slirp_forward(const char *optarg)
2849{
2850 /*
2851 * we expect the following format:
2852 * dst_net:dst_mask:dst_port:redirect_ip:redirect_port OR
2853 * dst_net:dst_mask:[dp_range_start-dp_range_end]:redirect_ip:redirect_port
2854 */
2855 char *argument = strdup(optarg), *p = argument;
2856 char *dst_net, *dst_mask, *dst_port;
2857 char *redirect_ip, *redirect_port;
2858 uint32_t dnet, dmask, rip;
2859 unsigned short dlport, dhport, rport;
2860
2861
2862 dst_net = strtok(p, ":");
2863 dst_mask = strtok(NULL, ":");
2864 dst_port = strtok(NULL, ":");
2865 redirect_ip = strtok(NULL, ":");
2866 redirect_port = strtok(NULL, ":");
2867
2868 if (dst_net == NULL || dst_mask == NULL || dst_port == NULL ||
2869 redirect_ip == NULL || redirect_port == NULL) {
2870 fprintf(stderr,
2871 "Invalid argument for -net-forward, we expect "
2872 "dst_net:dst_mask:dst_port:redirect_ip:redirect_port or "
2873 "dst_net:dst_mask:[dp_range_start-dp_range_end]"
2874 ":redirect_ip:redirect_port: %s\n",
2875 optarg);
2876 exit(1);
2877 }
2878
2879 /* inet_strtoip converts dotted address to host byte order */
2880 if (inet_strtoip(dst_net, &dnet) == -1) {
2881 fprintf(stderr, "Invalid destination IP net: %s\n", dst_net);
2882 exit(1);
2883 }
2884 if (inet_strtoip(dst_mask, &dmask) == -1) {
2885 fprintf(stderr, "Invalid destination IP mask: %s\n", dst_mask);
2886 exit(1);
2887 }
2888 if (inet_strtoip(redirect_ip, &rip) == -1) {
2889 fprintf(stderr, "Invalid redirect IP address: %s\n", redirect_ip);
2890 exit(1);
2891 }
2892
2893 if (parse_port_range(dst_port, &dlport, &dhport) == -1) {
2894 fprintf(stderr, "Invalid destination port or port range\n");
2895 exit(1);
2896 }
2897
2898 rport = atoi(redirect_port);
2899 if (!rport) {
2900 fprintf(stderr, "Invalid redirect port: %s\n", redirect_port);
2901 exit(1);
2902 }
2903
2904 dnet &= dmask;
2905
2906 slirp_add_net_forward(dnet, dmask, dlport, dhport,
2907 rip, rport);
2908
2909 free(argument);
2910}
2911
2912
2913/* Parses an -allow-tcp or -allow-udp argument and inserts a corresponding
2914 * entry in the allows list */
2915void
2916slirp_allow(const char *optarg, u_int8_t proto)
2917{
2918 /*
2919 * we expect the following format:
2920 * dst_ip:dst_port OR dst_ip:[dst_lport-dst_hport]
2921 */
2922 char *argument = strdup(optarg), *p = argument;
2923 char *dst_ip_str, *dst_port_str;
2924 uint32_t dst_ip;
2925 unsigned short dst_lport, dst_hport;
2926
2927 dst_ip_str = strtok(p, ":");
2928 dst_port_str = strtok(NULL, ":");
2929
2930 if (dst_ip_str == NULL || dst_port_str == NULL) {
2931 fprintf(stderr,
2932 "Invalid argument %s for -allow. We expect "
2933 "dst_ip:dst_port or dst_ip:[dst_lport-dst_hport]\n",
2934 optarg);
2935 exit(1);
2936 }
2937
2938 if (inet_strtoip(dst_ip_str, &dst_ip) == -1) {
2939 fprintf(stderr, "Invalid destination IP address: %s\n", dst_ip_str);
2940 exit(1);
2941 }
2942 if (parse_port_range(dst_port_str, &dst_lport, &dst_hport) == -1) {
2943 fprintf(stderr, "Invalid destination port or port range\n");
2944 exit(1);
2945 }
2946
2947 slirp_add_allow(dst_ip, dst_lport, dst_hport, proto);
2948
2949 free(argument);
2950}
2951
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01002952/* Add a serial device at a given location in the emulated hardware table.
2953 * On failure, this function aborts the program with an error message.
2954 */
2955static void
2956serial_hds_add_at(int index, const char* devname)
2957{
2958 char label[32];
2959
2960 if (!devname || !strcmp(devname,"none"))
2961 return;
2962
2963 if (index >= MAX_SERIAL_PORTS) {
2964 PANIC("qemu: invalid serial index for %s (%d >= %d)",
2965 devname, index, MAX_SERIAL_PORTS);
2966 }
2967 if (serial_hds[index] != NULL) {
2968 PANIC("qemu: invalid serial index for %s (%d: already taken!)",
2969 devname, index);
2970 }
2971 snprintf(label, sizeof(label), "serial%d", index);
2972 serial_hds[index] = qemu_chr_open(label, devname, NULL);
2973 if (!serial_hds[index]) {
2974 PANIC("qemu: could not open serial device '%s'", devname);
2975 }
2976}
2977
2978
2979/* Find a free slot in the emulated serial device table, and register
2980 * it. Return the allocated table index.
2981 */
2982static int
2983serial_hds_add(const char* devname)
2984{
2985 int index;
2986
2987 /* Find first free slot */
2988 for (index = 0; index < MAX_SERIAL_PORTS; index++) {
2989 if (serial_hds[index] == NULL) {
2990 serial_hds_add_at(index, devname);
2991 return index;
2992 }
2993 }
2994
2995 PANIC("qemu: too many serial devices registered (%d)", index);
2996 return -1; /* shouldn't happen */
2997}
2998
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002999int main(int argc, char **argv, char **envp)
3000{
3001 const char *gdbstub_dev = NULL;
3002 uint32_t boot_devices_bitmap = 0;
3003 int i;
3004 int snapshot, linux_boot, net_boot;
David Turner6a9ef172010-09-09 22:54:36 +02003005 const char *icount_option = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003006 const char *initrd_filename;
3007 const char *kernel_filename, *kernel_cmdline;
3008 const char *boot_devices = "";
3009 DisplayState *ds;
3010 DisplayChangeListener *dcl;
3011 int cyls, heads, secs, translation;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003012 QemuOpts *hda_opts = NULL;
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01003013 QemuOpts *hdb_opts = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003014 const char *net_clients[MAX_NET_CLIENTS];
3015 int nb_net_clients;
3016 const char *bt_opts[MAX_BT_CMDLINE];
3017 int nb_bt_opts;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003018 int optind;
3019 const char *r, *optarg;
3020 CharDriverState *monitor_hd = NULL;
3021 const char *monitor_device;
3022 const char *serial_devices[MAX_SERIAL_PORTS];
3023 int serial_device_index;
3024 const char *parallel_devices[MAX_PARALLEL_PORTS];
3025 int parallel_device_index;
3026 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
3027 int virtio_console_index;
3028 const char *loadvm = NULL;
3029 QEMUMachine *machine;
3030 const char *cpu_model;
3031 const char *usb_devices[MAX_USB_CMDLINE];
3032 int usb_devices_index;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003033 int tb_size;
3034 const char *pid_file = NULL;
3035 const char *incoming = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003036 CPUState *env;
3037 int show_vnc_port = 0;
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07003038 IniFile* hw_ini = NULL;
David 'Digit' Turner5f824112011-03-01 14:00:26 +01003039 STRALLOC_DEFINE(kernel_params);
3040 STRALLOC_DEFINE(kernel_config);
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003041 int dns_count = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003042
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003043 /* Initialize sockets before anything else, so we can properly report
3044 * initialization failures back to the UI. */
3045#ifdef _WIN32
3046 socket_init();
3047#endif
3048
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003049 init_clocks();
3050
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003051 qemu_cache_utils_init(envp);
3052
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07003053 QLIST_INIT (&vm_change_state_head);
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003054 os_setup_early_signal_handling();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003055
3056 module_call_init(MODULE_INIT_MACHINE);
3057 machine = find_default_machine();
3058 cpu_model = NULL;
3059 initrd_filename = NULL;
3060 ram_size = 0;
3061 snapshot = 0;
3062 kernel_filename = NULL;
3063 kernel_cmdline = "";
David 'Digit' Turner5f824112011-03-01 14:00:26 +01003064
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003065 cyls = heads = secs = 0;
3066 translation = BIOS_ATA_TRANSLATION_AUTO;
3067 monitor_device = "vc:80Cx24C";
3068
3069 serial_devices[0] = "vc:80Cx24C";
3070 for(i = 1; i < MAX_SERIAL_PORTS; i++)
3071 serial_devices[i] = NULL;
3072 serial_device_index = 0;
3073
3074 parallel_devices[0] = "vc:80Cx24C";
3075 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3076 parallel_devices[i] = NULL;
3077 parallel_device_index = 0;
3078
3079 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
3080 virtio_consoles[i] = NULL;
3081 virtio_console_index = 0;
3082
3083 for (i = 0; i < MAX_NODES; i++) {
3084 node_mem[i] = 0;
3085 node_cpumask[i] = 0;
3086 }
3087
3088 usb_devices_index = 0;
3089
3090 nb_net_clients = 0;
3091 nb_bt_opts = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003092#ifdef MAX_DRIVES
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003093 nb_drives = 0;
3094 nb_drives_opt = 0;
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003095#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003096 nb_numa_nodes = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003097
3098 nb_nics = 0;
3099
3100 tb_size = 0;
3101 autostart= 1;
3102
3103 register_watchdogs();
3104
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07003105 /* Initialize boot properties. */
3106 boot_property_init_service();
David 'Digit' Turnerca950592011-04-27 12:26:15 +02003107 android_hw_control_init();
David 'Digit' Turnerd4d688e2011-04-26 18:09:17 +02003108 android_net_pipes_init();
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07003109
David 'Digit' Turner36597752011-05-20 01:18:01 +02003110#ifdef CONFIG_KVM
3111 /* By default, force auto-detection for kvm */
3112 kvm_allowed = -1;
3113#endif
3114
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003115 optind = 1;
3116 for(;;) {
3117 if (optind >= argc)
3118 break;
3119 r = argv[optind];
3120 if (r[0] != '-') {
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003121 hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003122 } else {
3123 const QEMUOption *popt;
3124
3125 optind++;
3126 /* Treat --foo the same as -foo. */
3127 if (r[1] == '-')
3128 r++;
3129 popt = qemu_options;
3130 for(;;) {
3131 if (!popt->name) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003132 PANIC("%s: invalid option -- '%s'",
3133 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003134 }
3135 if (!strcmp(popt->name, r + 1))
3136 break;
3137 popt++;
3138 }
3139 if (popt->flags & HAS_ARG) {
3140 if (optind >= argc) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003141 PANIC("%s: option '%s' requires an argument",
3142 argv[0], r);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003143 }
3144 optarg = argv[optind++];
3145 } else {
3146 optarg = NULL;
3147 }
3148
3149 switch(popt->index) {
3150 case QEMU_OPTION_M:
3151 machine = find_machine(optarg);
3152 if (!machine) {
3153 QEMUMachine *m;
3154 printf("Supported machines are:\n");
3155 for(m = first_machine; m != NULL; m = m->next) {
3156 printf("%-10s %s%s\n",
3157 m->name, m->desc,
3158 m->is_default ? " (default)" : "");
3159 }
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003160 if (*optarg != '?') {
3161 PANIC("Invalid machine parameter: %s",
3162 optarg);
3163 } else {
3164 QEMU_EXIT(0);
3165 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003166 }
3167 break;
3168 case QEMU_OPTION_cpu:
3169 /* hw initialization will check this */
3170 if (*optarg == '?') {
3171/* XXX: implement xxx_cpu_list for targets that still miss it */
3172#if defined(cpu_list)
3173 cpu_list(stdout, &fprintf);
3174#endif
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003175 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003176 } else {
3177 cpu_model = optarg;
3178 }
3179 break;
3180 case QEMU_OPTION_initrd:
3181 initrd_filename = optarg;
3182 break;
3183 case QEMU_OPTION_hda:
3184 if (cyls == 0)
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003185 hda_opts = drive_add(optarg, HD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003186 else
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003187 hda_opts = drive_add(optarg, HD_ALIAS
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003188 ",cyls=%d,heads=%d,secs=%d%s",
3189 0, cyls, heads, secs,
3190 translation == BIOS_ATA_TRANSLATION_LBA ?
3191 ",trans=lba" :
3192 translation == BIOS_ATA_TRANSLATION_NONE ?
3193 ",trans=none" : "");
3194 break;
3195 case QEMU_OPTION_hdb:
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01003196 hdb_opts = drive_add(optarg, HD_ALIAS, 1);
3197 break;
3198
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003199 case QEMU_OPTION_hdc:
3200 case QEMU_OPTION_hdd:
3201 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
3202 break;
3203 case QEMU_OPTION_drive:
3204 drive_add(NULL, "%s", optarg);
3205 break;
3206 case QEMU_OPTION_mtdblock:
3207 drive_add(optarg, MTD_ALIAS);
3208 break;
3209 case QEMU_OPTION_sd:
3210 drive_add(optarg, SD_ALIAS);
3211 break;
3212 case QEMU_OPTION_pflash:
3213 drive_add(optarg, PFLASH_ALIAS);
3214 break;
3215 case QEMU_OPTION_snapshot:
3216 snapshot = 1;
3217 break;
3218 case QEMU_OPTION_hdachs:
3219 {
3220 const char *p;
3221 p = optarg;
3222 cyls = strtol(p, (char **)&p, 0);
3223 if (cyls < 1 || cyls > 16383)
3224 goto chs_fail;
3225 if (*p != ',')
3226 goto chs_fail;
3227 p++;
3228 heads = strtol(p, (char **)&p, 0);
3229 if (heads < 1 || heads > 16)
3230 goto chs_fail;
3231 if (*p != ',')
3232 goto chs_fail;
3233 p++;
3234 secs = strtol(p, (char **)&p, 0);
3235 if (secs < 1 || secs > 63)
3236 goto chs_fail;
3237 if (*p == ',') {
3238 p++;
3239 if (!strcmp(p, "none"))
3240 translation = BIOS_ATA_TRANSLATION_NONE;
3241 else if (!strcmp(p, "lba"))
3242 translation = BIOS_ATA_TRANSLATION_LBA;
3243 else if (!strcmp(p, "auto"))
3244 translation = BIOS_ATA_TRANSLATION_AUTO;
3245 else
3246 goto chs_fail;
3247 } else if (*p != '\0') {
3248 chs_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003249 PANIC("qemu: invalid physical CHS format");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003250 }
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01003251 if (hda_opts != NULL) {
3252 char num[16];
3253 snprintf(num, sizeof(num), "%d", cyls);
3254 qemu_opt_set(hda_opts, "cyls", num);
3255 snprintf(num, sizeof(num), "%d", heads);
3256 qemu_opt_set(hda_opts, "heads", num);
3257 snprintf(num, sizeof(num), "%d", secs);
3258 qemu_opt_set(hda_opts, "secs", num);
3259 if (translation == BIOS_ATA_TRANSLATION_LBA)
3260 qemu_opt_set(hda_opts, "trans", "lba");
3261 if (translation == BIOS_ATA_TRANSLATION_NONE)
3262 qemu_opt_set(hda_opts, "trans", "none");
3263 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003264 }
3265 break;
3266 case QEMU_OPTION_numa:
3267 if (nb_numa_nodes >= MAX_NODES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003268 PANIC("qemu: too many NUMA nodes");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003269 }
3270 numa_add(optarg);
3271 break;
3272 case QEMU_OPTION_nographic:
3273 display_type = DT_NOGRAPHIC;
3274 break;
3275#ifdef CONFIG_CURSES
3276 case QEMU_OPTION_curses:
3277 display_type = DT_CURSES;
3278 break;
3279#endif
3280 case QEMU_OPTION_portrait:
3281 graphic_rotate = 1;
3282 break;
3283 case QEMU_OPTION_kernel:
3284 kernel_filename = optarg;
3285 break;
3286 case QEMU_OPTION_append:
3287 kernel_cmdline = optarg;
3288 break;
3289 case QEMU_OPTION_cdrom:
3290 drive_add(optarg, CDROM_ALIAS);
3291 break;
3292 case QEMU_OPTION_boot:
3293 boot_devices = optarg;
3294 /* We just do some generic consistency checks */
3295 {
3296 /* Could easily be extended to 64 devices if needed */
3297 const char *p;
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07003298
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003299 boot_devices_bitmap = 0;
3300 for (p = boot_devices; *p != '\0'; p++) {
3301 /* Allowed boot devices are:
3302 * a b : floppy disk drives
3303 * c ... f : IDE disk drives
3304 * g ... m : machine implementation dependant drives
3305 * n ... p : network devices
3306 * It's up to each machine implementation to check
3307 * if the given boot devices match the actual hardware
3308 * implementation and firmware features.
3309 */
3310 if (*p < 'a' || *p > 'q') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003311 PANIC("Invalid boot device '%c'", *p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003312 }
3313 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003314 PANIC(
3315 "Boot device '%c' was given twice",*p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003316 }
3317 boot_devices_bitmap |= 1 << (*p - 'a');
3318 }
3319 }
3320 break;
3321 case QEMU_OPTION_fda:
3322 case QEMU_OPTION_fdb:
3323 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
3324 break;
3325#ifdef TARGET_I386
3326 case QEMU_OPTION_no_fd_bootchk:
3327 fd_bootchk = 0;
3328 break;
3329#endif
3330 case QEMU_OPTION_net:
3331 if (nb_net_clients >= MAX_NET_CLIENTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003332 PANIC("qemu: too many network clients");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003333 }
3334 net_clients[nb_net_clients] = optarg;
3335 nb_net_clients++;
3336 break;
3337#ifdef CONFIG_SLIRP
3338 case QEMU_OPTION_tftp:
3339 tftp_prefix = optarg;
3340 break;
3341 case QEMU_OPTION_bootp:
3342 bootp_filename = optarg;
3343 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003344 case QEMU_OPTION_redir:
3345 net_slirp_redir(NULL, optarg, NULL);
3346 break;
3347#endif
3348 case QEMU_OPTION_bt:
3349 if (nb_bt_opts >= MAX_BT_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003350 PANIC("qemu: too many bluetooth options");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003351 }
3352 bt_opts[nb_bt_opts++] = optarg;
3353 break;
3354#ifdef HAS_AUDIO
3355 case QEMU_OPTION_audio_help:
3356 AUD_help ();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003357 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003358 break;
3359 case QEMU_OPTION_soundhw:
3360 select_soundhw (optarg);
3361 break;
3362#endif
3363 case QEMU_OPTION_h:
3364 qemu_help(0);
3365 break;
3366 case QEMU_OPTION_version:
3367 version();
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003368 QEMU_EXIT(0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003369 break;
3370 case QEMU_OPTION_m: {
3371 uint64_t value;
3372 char *ptr;
3373
3374 value = strtoul(optarg, &ptr, 10);
3375 switch (*ptr) {
3376 case 0: case 'M': case 'm':
3377 value <<= 20;
3378 break;
3379 case 'G': case 'g':
3380 value <<= 30;
3381 break;
3382 default:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003383 PANIC("qemu: invalid ram size: %s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003384 }
3385
3386 /* On 32-bit hosts, QEMU is limited by virtual address space */
3387 if (value > (2047 << 20)
3388#ifndef CONFIG_KQEMU
3389 && HOST_LONG_BITS == 32
3390#endif
3391 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003392 PANIC("qemu: at most 2047 MB RAM can be simulated");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003393 }
3394 if (value != (uint64_t)(ram_addr_t)value) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003395 PANIC("qemu: ram size too large");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003396 }
3397 ram_size = value;
3398 break;
3399 }
3400 case QEMU_OPTION_d:
3401 {
3402 int mask;
3403 const CPULogItem *item;
3404
3405 mask = cpu_str_to_log_mask(optarg);
3406 if (!mask) {
3407 printf("Log items (comma separated):\n");
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003408 for(item = cpu_log_items; item->mask != 0; item++) {
3409 printf("%-10s %s\n", item->name, item->help);
3410 }
3411 PANIC("Invalid parameter -d=%s", optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003412 }
3413 cpu_set_log(mask);
3414 }
3415 break;
3416 case QEMU_OPTION_s:
3417 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
3418 break;
3419 case QEMU_OPTION_gdb:
3420 gdbstub_dev = optarg;
3421 break;
3422 case QEMU_OPTION_L:
3423 data_dir = optarg;
3424 break;
3425 case QEMU_OPTION_bios:
3426 bios_name = optarg;
3427 break;
3428 case QEMU_OPTION_singlestep:
3429 singlestep = 1;
3430 break;
3431 case QEMU_OPTION_S:
3432#if 0 /* ANDROID */
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003433 PANIC("Sorry, stopped launch is not supported in the Android emulator" );
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003434#endif
3435 autostart = 0;
3436 break;
3437#ifndef _WIN32
3438 case QEMU_OPTION_k:
3439 keyboard_layout = optarg;
3440 break;
3441#endif
3442 case QEMU_OPTION_localtime:
3443 rtc_utc = 0;
3444 break;
3445 case QEMU_OPTION_vga:
3446 select_vgahw (optarg);
3447 break;
3448#if defined(TARGET_PPC) || defined(TARGET_SPARC)
3449 case QEMU_OPTION_g:
3450 {
3451 const char *p;
3452 int w, h, depth;
3453 p = optarg;
3454 w = strtol(p, (char **)&p, 10);
3455 if (w <= 0) {
3456 graphic_error:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003457 PANIC("qemu: invalid resolution or depth");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003458 }
3459 if (*p != 'x')
3460 goto graphic_error;
3461 p++;
3462 h = strtol(p, (char **)&p, 10);
3463 if (h <= 0)
3464 goto graphic_error;
3465 if (*p == 'x') {
3466 p++;
3467 depth = strtol(p, (char **)&p, 10);
3468 if (depth != 8 && depth != 15 && depth != 16 &&
3469 depth != 24 && depth != 32)
3470 goto graphic_error;
3471 } else if (*p == '\0') {
3472 depth = graphic_depth;
3473 } else {
3474 goto graphic_error;
3475 }
3476
3477 graphic_width = w;
3478 graphic_height = h;
3479 graphic_depth = depth;
3480 }
3481 break;
3482#endif
3483 case QEMU_OPTION_echr:
3484 {
3485 char *r;
3486 term_escape_char = strtol(optarg, &r, 0);
3487 if (r == optarg)
3488 printf("Bad argument to echr\n");
3489 break;
3490 }
3491 case QEMU_OPTION_monitor:
3492 monitor_device = optarg;
3493 break;
3494 case QEMU_OPTION_serial:
3495 if (serial_device_index >= MAX_SERIAL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003496 PANIC("qemu: too many serial ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003497 }
3498 serial_devices[serial_device_index] = optarg;
3499 serial_device_index++;
3500 break;
3501 case QEMU_OPTION_watchdog:
3502 i = select_watchdog(optarg);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003503 if (i > 0) {
3504 if (i == 1) {
3505 PANIC("Invalid watchdog parameter: %s",
3506 optarg);
3507 } else {
3508 QEMU_EXIT(0);
3509 }
3510 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003511 break;
3512 case QEMU_OPTION_watchdog_action:
3513 if (select_watchdog_action(optarg) == -1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003514 PANIC("Unknown -watchdog-action parameter");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003515 }
3516 break;
3517 case QEMU_OPTION_virtiocon:
3518 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003519 PANIC("qemu: too many virtio consoles");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003520 }
3521 virtio_consoles[virtio_console_index] = optarg;
3522 virtio_console_index++;
3523 break;
3524 case QEMU_OPTION_parallel:
3525 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003526 PANIC("qemu: too many parallel ports");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003527 }
3528 parallel_devices[parallel_device_index] = optarg;
3529 parallel_device_index++;
3530 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003531 case QEMU_OPTION_loadvm:
3532 loadvm = optarg;
3533 break;
Tim Baverstock24204cc2010-11-25 11:37:43 +00003534 case QEMU_OPTION_savevm_on_exit:
3535 savevm_on_exit = optarg;
3536 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003537 case QEMU_OPTION_full_screen:
3538 full_screen = 1;
3539 break;
3540#ifdef CONFIG_SDL
3541 case QEMU_OPTION_no_frame:
3542 no_frame = 1;
3543 break;
3544 case QEMU_OPTION_alt_grab:
3545 alt_grab = 1;
3546 break;
3547 case QEMU_OPTION_no_quit:
3548 no_quit = 1;
3549 break;
3550 case QEMU_OPTION_sdl:
3551 display_type = DT_SDL;
3552 break;
3553#endif
3554 case QEMU_OPTION_pidfile:
3555 pid_file = optarg;
3556 break;
3557#ifdef TARGET_I386
3558 case QEMU_OPTION_win2k_hack:
3559 win2k_install_hack = 1;
3560 break;
3561 case QEMU_OPTION_rtc_td_hack:
3562 rtc_td_hack = 1;
3563 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08003564#ifndef CONFIG_ANDROID
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003565 case QEMU_OPTION_acpitable:
3566 if(acpi_table_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003567 PANIC("Wrong acpi table provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003568 }
3569 break;
Jun Nakajima334ab472011-02-02 23:49:59 -08003570#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003571 case QEMU_OPTION_smbios:
3572 if(smbios_entry_add(optarg) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003573 PANIC("Wrong smbios provided");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003574 }
3575 break;
3576#endif
3577#ifdef CONFIG_KQEMU
3578 case QEMU_OPTION_no_kqemu:
3579 kqemu_allowed = 0;
3580 break;
3581 case QEMU_OPTION_kernel_kqemu:
3582 kqemu_allowed = 2;
3583 break;
3584#endif
3585#ifdef CONFIG_KVM
3586 case QEMU_OPTION_enable_kvm:
3587 kvm_allowed = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003588 break;
David 'Digit' Turner36597752011-05-20 01:18:01 +02003589 case QEMU_OPTION_disable_kvm:
3590 kvm_allowed = 0;
3591 break;
3592#endif /* CONFIG_KVM */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003593 case QEMU_OPTION_usb:
3594 usb_enabled = 1;
3595 break;
3596 case QEMU_OPTION_usbdevice:
3597 usb_enabled = 1;
3598 if (usb_devices_index >= MAX_USB_CMDLINE) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003599 PANIC("Too many USB devices");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003600 }
3601 usb_devices[usb_devices_index] = optarg;
3602 usb_devices_index++;
3603 break;
3604 case QEMU_OPTION_smp:
3605 smp_cpus = atoi(optarg);
3606 if (smp_cpus < 1) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003607 PANIC("Invalid number of CPUs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003608 }
3609 break;
3610 case QEMU_OPTION_vnc:
3611 display_type = DT_VNC;
3612 vnc_display = optarg;
3613 break;
3614#ifdef TARGET_I386
3615 case QEMU_OPTION_no_acpi:
3616 acpi_enabled = 0;
3617 break;
3618 case QEMU_OPTION_no_hpet:
3619 no_hpet = 1;
3620 break;
3621 case QEMU_OPTION_no_virtio_balloon:
3622 no_virtio_balloon = 1;
3623 break;
3624#endif
3625 case QEMU_OPTION_no_reboot:
3626 no_reboot = 1;
3627 break;
3628 case QEMU_OPTION_no_shutdown:
3629 no_shutdown = 1;
3630 break;
3631 case QEMU_OPTION_show_cursor:
3632 cursor_hide = 0;
3633 break;
3634 case QEMU_OPTION_uuid:
3635 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003636 PANIC("Fail to parse UUID string. Wrong format.");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003637 }
3638 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003639 case QEMU_OPTION_option_rom:
3640 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003641 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003642 }
3643 option_rom[nb_option_roms] = optarg;
3644 nb_option_roms++;
3645 break;
3646#if defined(TARGET_ARM) || defined(TARGET_M68K)
3647 case QEMU_OPTION_semihosting:
3648 semihosting_enabled = 1;
3649 break;
3650#endif
3651 case QEMU_OPTION_name:
3652 qemu_name = optarg;
3653 break;
3654#if defined(TARGET_SPARC) || defined(TARGET_PPC)
3655 case QEMU_OPTION_prom_env:
3656 if (nb_prom_envs >= MAX_PROM_ENVS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003657 PANIC("Too many prom variables");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003658 }
3659 prom_envs[nb_prom_envs] = optarg;
3660 nb_prom_envs++;
3661 break;
3662#endif
3663#ifdef TARGET_ARM
3664 case QEMU_OPTION_old_param:
3665 old_param = 1;
3666 break;
3667#endif
3668 case QEMU_OPTION_clock:
3669 configure_alarms(optarg);
3670 break;
3671 case QEMU_OPTION_startdate:
3672 {
3673 struct tm tm;
David 'Digit' Turnerdc468202010-10-27 02:34:46 +02003674 time_t rtc_start_date = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003675 if (!strcmp(optarg, "now")) {
3676 rtc_date_offset = -1;
3677 } else {
3678 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
3679 &tm.tm_year,
3680 &tm.tm_mon,
3681 &tm.tm_mday,
3682 &tm.tm_hour,
3683 &tm.tm_min,
3684 &tm.tm_sec) == 6) {
3685 /* OK */
3686 } else if (sscanf(optarg, "%d-%d-%d",
3687 &tm.tm_year,
3688 &tm.tm_mon,
3689 &tm.tm_mday) == 3) {
3690 tm.tm_hour = 0;
3691 tm.tm_min = 0;
3692 tm.tm_sec = 0;
3693 } else {
3694 goto date_fail;
3695 }
3696 tm.tm_year -= 1900;
3697 tm.tm_mon--;
3698 rtc_start_date = mktimegm(&tm);
3699 if (rtc_start_date == -1) {
3700 date_fail:
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003701 PANIC("Invalid date format. Valid format are:\n"
3702 "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003703 }
3704 rtc_date_offset = time(NULL) - rtc_start_date;
3705 }
3706 }
3707 break;
rich cannings7339b552011-02-16 13:43:44 -08003708
3709 /* -------------------------------------------------------*/
3710 /* User mode network stack restrictions */
3711 case QEMU_OPTION_drop_udp:
3712 slirp_drop_udp();
3713 break;
3714 case QEMU_OPTION_drop_tcp:
3715 slirp_drop_tcp();
3716 break;
3717 case QEMU_OPTION_allow_tcp:
3718 slirp_allow(optarg, IPPROTO_TCP);
3719 break;
3720 case QEMU_OPTION_allow_udp:
3721 slirp_allow(optarg, IPPROTO_UDP);
3722 break;
3723 case QEMU_OPTION_drop_log:
3724 {
3725 FILE* drop_log_fd;
rich canningsd952f282011-03-01 15:40:09 -08003726 drop_log_filename = optarg;
3727 drop_log_fd = fopen(optarg, "w+");
rich cannings7339b552011-02-16 13:43:44 -08003728
3729 if (!drop_log_fd) {
3730 fprintf(stderr, "Cannot open drop log: %s\n", optarg);
3731 exit(1);
3732 }
3733
3734 slirp_drop_log_fd(drop_log_fd);
3735 }
3736 break;
3737
3738 case QEMU_OPTION_dns_log:
3739 {
3740 FILE* dns_log_fd;
rich canningsd952f282011-03-01 15:40:09 -08003741 dns_log_filename = optarg;
3742 dns_log_fd = fopen(optarg, "wb+");
rich cannings7339b552011-02-16 13:43:44 -08003743
3744 if (dns_log_fd == NULL) {
3745 fprintf(stderr, "Cannot open dns log: %s\n", optarg);
3746 exit(1);
3747 }
3748
3749 slirp_dns_log_fd(dns_log_fd);
3750 }
3751 break;
3752
3753
3754 case QEMU_OPTION_max_dns_conns:
3755 {
3756 int max_dns_conns = 0;
3757 if (parse_int(optarg, &max_dns_conns)) {
3758 fprintf(stderr,
3759 "qemu: syntax: -max-dns-conns max_connections\n");
3760 exit(1);
3761 }
3762 if (max_dns_conns <= 0 || max_dns_conns == LONG_MAX) {
3763 fprintf(stderr,
3764 "Invalid arg for max dns connections: %s\n",
3765 optarg);
3766 exit(1);
3767 }
3768 slirp_set_max_dns_conns(max_dns_conns);
3769 }
3770 break;
3771
3772 case QEMU_OPTION_net_forward:
3773 net_slirp_forward(optarg);
3774 break;
3775 case QEMU_OPTION_net_forward_tcp2sink:
3776 {
3777 SockAddress saddr;
3778
3779 if (parse_host_port(&saddr, optarg)) {
3780 fprintf(stderr,
3781 "Invalid ip/port %s for "
3782 "-forward-dropped-tcp2sink. "
3783 "We expect 'sink_ip:sink_port'\n",
3784 optarg);
3785 exit(1);
3786 }
3787 slirp_forward_dropped_tcp2sink(saddr.u.inet.address,
3788 saddr.u.inet.port);
3789 }
3790 break;
3791 /* -------------------------------------------------------*/
3792
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003793 case QEMU_OPTION_tb_size:
3794 tb_size = strtol(optarg, NULL, 0);
3795 if (tb_size < 0)
3796 tb_size = 0;
3797 break;
3798 case QEMU_OPTION_icount:
David Turner6a9ef172010-09-09 22:54:36 +02003799 icount_option = optarg;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003800 break;
3801 case QEMU_OPTION_incoming:
3802 incoming = optarg;
3803 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003804#ifdef CONFIG_XEN
3805 case QEMU_OPTION_xen_domid:
3806 xen_domid = atoi(optarg);
3807 break;
3808 case QEMU_OPTION_xen_create:
3809 xen_mode = XEN_CREATE;
3810 break;
3811 case QEMU_OPTION_xen_attach:
3812 xen_mode = XEN_ATTACH;
3813 break;
3814#endif
3815
3816
3817 case QEMU_OPTION_mic:
3818 audio_input_source = (char*)optarg;
3819 break;
3820#ifdef CONFIG_TRACE
David 'Digit' Turnera577fca2009-10-15 18:18:09 -07003821 case QEMU_OPTION_trace:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003822 trace_filename = optarg;
3823 tracing = 1;
3824 break;
3825#if 0
3826 case QEMU_OPTION_trace_miss:
3827 trace_cache_miss = 1;
3828 break;
3829 case QEMU_OPTION_trace_addr:
3830 trace_all_addr = 1;
3831 break;
3832#endif
3833 case QEMU_OPTION_tracing:
3834 if (strcmp(optarg, "off") == 0)
3835 tracing = 0;
3836 else if (strcmp(optarg, "on") == 0 && trace_filename)
3837 tracing = 1;
3838 else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003839 PANIC("Unexpected option to -tracing ('%s')",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003840 optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003841 }
3842 break;
3843#if 0
3844 case QEMU_OPTION_dcache_load_miss:
3845 dcache_load_miss_penalty = atoi(optarg);
3846 break;
3847 case QEMU_OPTION_dcache_store_miss:
3848 dcache_store_miss_penalty = atoi(optarg);
3849 break;
3850#endif
3851#endif
3852#ifdef CONFIG_NAND
3853 case QEMU_OPTION_nand:
3854 nand_add_dev(optarg);
3855 break;
3856#endif
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07003857 case QEMU_OPTION_android_ports:
3858 android_op_ports = (char*)optarg;
3859 break;
3860
3861 case QEMU_OPTION_android_port:
3862 android_op_port = (char*)optarg;
3863 break;
3864
3865 case QEMU_OPTION_android_report_console:
3866 android_op_report_console = (char*)optarg;
3867 break;
3868
3869 case QEMU_OPTION_http_proxy:
3870 op_http_proxy = (char*)optarg;
3871 break;
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07003872
3873 case QEMU_OPTION_charmap:
3874 op_charmap_file = (char*)optarg;
3875 break;
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07003876
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07003877 case QEMU_OPTION_android_hw:
3878 android_op_hwini = (char*)optarg;
3879 break;
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07003880
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003881 case QEMU_OPTION_dns_server:
3882 android_op_dns_server = (char*)optarg;
3883 break;
3884
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07003885 case QEMU_OPTION_radio:
3886 android_op_radio = (char*)optarg;
3887 break;
3888
3889 case QEMU_OPTION_gps:
3890 android_op_gps = (char*)optarg;
3891 break;
3892
3893 case QEMU_OPTION_audio:
3894 android_op_audio = (char*)optarg;
3895 break;
3896
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07003897 case QEMU_OPTION_cpu_delay:
3898 android_op_cpu_delay = (char*)optarg;
3899 break;
3900
Vladimir Chtchetkine13f3b6c2010-08-25 09:49:25 -07003901 case QEMU_OPTION_show_kernel:
3902 android_kmsg_init(ANDROID_KMSG_PRINT_MESSAGES);
3903 break;
3904
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07003905#ifdef CONFIG_NAND_LIMITS
3906 case QEMU_OPTION_nand_limits:
3907 android_op_nand_limits = (char*)optarg;
3908 break;
3909#endif // CONFIG_NAND_LIMITS
3910
3911 case QEMU_OPTION_netspeed:
3912 android_op_netspeed = (char*)optarg;
3913 break;
3914
3915 case QEMU_OPTION_netdelay:
3916 android_op_netdelay = (char*)optarg;
3917 break;
3918
3919 case QEMU_OPTION_netfast:
3920 android_op_netfast = 1;
3921 break;
3922
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07003923 case QEMU_OPTION_tcpdump:
3924 android_op_tcpdump = (char*)optarg;
3925 break;
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07003926
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07003927 case QEMU_OPTION_boot_property:
3928 boot_property_parse_option((char*)optarg);
3929 break;
3930
3931 case QEMU_OPTION_lcd_density:
3932 android_op_lcd_density = (char*)optarg;
3933 break;
3934
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003935 case QEMU_OPTION_ui_port:
3936 android_op_ui_port = (char*)optarg;
3937 break;
3938
3939 case QEMU_OPTION_ui_settings:
3940 android_op_ui_settings = (char*)optarg;
3941 break;
3942
David 'Digit' Turnerca29fbb2011-01-02 13:17:22 +01003943 case QEMU_OPTION_audio_test_out:
3944 android_audio_test_start_out();
3945 break;
3946
Vladimir Chtchetkine90c62352011-01-13 11:24:07 -08003947 case QEMU_OPTION_android_avdname:
3948 android_op_avd_name = (char*)optarg;
3949 break;
3950
3951 case QEMU_OPTION_timezone:
3952 if (timezone_set((char*)optarg)) {
3953 fprintf(stderr, "emulator: it seems the timezone '%s' is not in zoneinfo format\n",
3954 (char*)optarg);
3955 }
3956 break;
3957
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07003958#ifdef CONFIG_MEMCHECK
3959 case QEMU_OPTION_android_memcheck:
3960 android_op_memcheck = (char*)optarg;
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07003961 /* This will set ro.kernel.memcheck system property
3962 * to memcheck's tracing flags. */
David 'Digit' Turner5f824112011-03-01 14:00:26 +01003963 stralloc_add_format(kernel_config, " memcheck=%s", android_op_memcheck);
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07003964 break;
3965#endif // CONFIG_MEMCHECK
David 'Digit' Turnerbdb6f2d2011-02-23 15:57:25 +01003966
3967 case QEMU_OPTION_snapshot_no_time_update:
3968 android_snapshot_update_time = 0;
3969 break;
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003970 default:
3971 os_parse_cmd_args(popt->index, optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003972 }
3973 }
3974 }
3975
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07003976 /* Initialize character map. */
3977 if (android_charmap_setup(op_charmap_file)) {
3978 if (op_charmap_file) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003979 PANIC(
3980 "Unable to initialize character map from file %s.",
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07003981 op_charmap_file);
3982 } else {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07003983 PANIC(
3984 "Unable to initialize default character map.");
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07003985 }
Vladimir Chtchetkine43552dc2010-07-22 11:23:19 -07003986 }
3987
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003988 /* If no data_dir is specified then try to find it relative to the
3989 executable path. */
3990 if (!data_dir) {
3991 data_dir = find_datadir(argv[0]);
3992 }
3993 /* If all else fails use the install patch specified when building. */
3994 if (!data_dir) {
3995 data_dir = CONFIG_QEMU_SHAREDIR;
3996 }
3997
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01003998 if (!android_op_hwini) {
3999 PANIC("Missing -android-hw <file> option!");
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004000 }
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004001 hw_ini = iniFile_newFromFile(android_op_hwini);
4002 if (hw_ini == NULL) {
4003 PANIC("Could not find %s file.", android_op_hwini);
4004 }
David 'Digit' Turnerb64325d2011-03-22 16:07:01 +01004005
4006 androidHwConfig_init(android_hw, 0);
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004007 androidHwConfig_read(android_hw, hw_ini);
David 'Digit' Turnerb64325d2011-03-22 16:07:01 +01004008
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004009 iniFile_free(hw_ini);
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004010
4011 {
4012 int width = android_hw->hw_lcd_width;
4013 int height = android_hw->hw_lcd_height;
4014 int depth = android_hw->hw_lcd_depth;
4015
4016 /* A bit of sanity checking */
4017 if (width <= 0 || height <= 0 ||
4018 (depth != 16 && depth != 32) ||
4019 (((width|height) & 3) != 0) )
4020 {
4021 PANIC("Invalid display configuration (%d,%d,%d)",
4022 width, height, depth);
4023 }
4024 android_display_width = width;
4025 android_display_height = height;
4026 android_display_bpp = depth;
4027 }
Vladimir Chtchetkine074d1f92010-08-06 09:29:50 -07004028
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004029#ifdef CONFIG_NAND_LIMITS
4030 /* Init nand stuff. */
4031 if (android_op_nand_limits) {
4032 parse_nand_limits(android_op_nand_limits);
4033 }
4034#endif // CONFIG_NAND_LIMITS
4035
David 'Digit' Turner53eb66d2011-03-01 14:58:23 +01004036 /* Initialize AVD name from hardware configuration if needed */
4037 if (!android_op_avd_name) {
4038 if (android_hw->avd_name && *android_hw->avd_name) {
4039 android_op_avd_name = android_hw->avd_name;
4040 VERBOSE_PRINT(init,"AVD Name: %s", android_op_avd_name);
4041 }
4042 }
4043
David 'Digit' Turner40841b22011-03-01 14:04:00 +01004044 /* Initialize system partition image */
4045 {
4046 char tmp[PATH_MAX+32];
4047 const char* sysImage = android_hw->disk_systemPartition_path;
4048 const char* initImage = android_hw->disk_systemPartition_initPath;
4049 uint64_t sysBytes = android_hw->disk_systemPartition_size;
4050
4051 if (sysBytes == 0) {
4052 PANIC("Invalid system partition size: %" PRUd64, sysBytes);
4053 }
4054
4055 snprintf(tmp,sizeof(tmp),"system,size=0x%" PRUx64, sysBytes);
4056
4057 if (sysImage && *sysImage) {
4058 if (filelock_create(sysImage) == NULL) {
4059 fprintf(stderr,"WARNING: System image already in use, changes will not persist!\n");
4060 /* If there is no file= parameters, nand_add_dev will create
4061 * a temporary file to back the partition image. */
4062 } else {
4063 pstrcat(tmp,sizeof(tmp),",file=");
4064 pstrcat(tmp,sizeof(tmp),sysImage);
4065 }
4066 }
4067 if (initImage && *initImage) {
4068 if (!path_exists(initImage)) {
4069 PANIC("Invalid initial system image path: %s", initImage);
4070 }
4071 pstrcat(tmp,sizeof(tmp),",initfile=");
4072 pstrcat(tmp,sizeof(tmp),initImage);
4073 } else {
4074 PANIC("Missing initial system image path!");
4075 }
4076 nand_add_dev(tmp);
4077 }
4078
David 'Digit' Turnerfd59c332011-03-01 00:48:52 +01004079 /* Initialize data partition image */
4080 {
4081 char tmp[PATH_MAX+32];
4082 const char* dataImage = android_hw->disk_dataPartition_path;
4083 const char* initImage = android_hw->disk_dataPartition_initPath;
4084 uint64_t dataBytes = android_hw->disk_dataPartition_size;
4085
4086 if (dataBytes == 0) {
4087 PANIC("Invalid data partition size: %" PRUd64, dataBytes);
4088 }
4089
4090 snprintf(tmp,sizeof(tmp),"userdata,size=0x%" PRUx64, dataBytes);
4091
4092 if (dataImage && *dataImage) {
4093 if (filelock_create(dataImage) == NULL) {
4094 fprintf(stderr, "WARNING: Data partition already in use. Changes will not persist!\n");
4095 /* Note: if there is no file= parameters, nand_add_dev() will
4096 * create a temporary file to back the partition image. */
4097 } else {
4098 /* Create the file if needed */
4099 if (!path_exists(dataImage)) {
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01004100 if (path_empty_file(dataImage) < 0) {
4101 PANIC("Could not create data image file %s: %s", dataImage, strerror(errno));
4102 }
David 'Digit' Turnerfd59c332011-03-01 00:48:52 +01004103 }
4104 pstrcat(tmp, sizeof(tmp), ",file=");
4105 pstrcat(tmp, sizeof(tmp), dataImage);
4106 }
4107 }
4108 if (initImage && *initImage) {
4109 pstrcat(tmp, sizeof(tmp), ",initfile=");
4110 pstrcat(tmp, sizeof(tmp), initImage);
4111 }
4112 nand_add_dev(tmp);
4113 }
4114
David 'Digit' Turner48a3c662011-03-01 14:03:20 +01004115 /* Init SD-Card stuff. For Android, it is always hda */
4116 /* If the -hda option was used, ignore the Android-provided one */
4117 if (hda_opts == NULL) {
4118 const char* sdPath = android_hw->hw_sdCard_path;
4119 if (sdPath && *sdPath) {
4120 if (!path_exists(sdPath)) {
4121 fprintf(stderr, "WARNING: SD Card image is missing: %s\n", sdPath);
4122 } else if (filelock_create(sdPath) == NULL) {
4123 fprintf(stderr, "WARNING: SD Card image already in use: %s\n", sdPath);
4124 } else {
4125 /* Successful locking */
4126 hda_opts = drive_add(sdPath, HD_ALIAS, 0);
David 'Digit' Turner8fc3e6e2011-05-09 10:17:20 +02004127 /* Set this property of any operation involving the SD Card
4128 * will be x100 slower, due to the corresponding file being
4129 * mounted as O_DIRECT. Note that this is only 'unsafe' in
4130 * the context of an emulator crash. The data is already
4131 * synced properly when the emulator exits (either normally or through ^C).
4132 */
4133 qemu_opt_set(hda_opts, "cache", "unsafe");
David 'Digit' Turner48a3c662011-03-01 14:03:20 +01004134 }
4135 }
4136 }
4137
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01004138 if (hdb_opts == NULL) {
4139 const char* spath = android_hw->disk_snapStorage_path;
4140 if (spath && *spath) {
4141 if (!path_exists(spath)) {
4142 PANIC("Snapshot storage file does not exist: %s", spath);
4143 }
4144 if (filelock_create(spath) == NULL) {
David 'Digit' Turner4297b822011-05-04 19:18:15 +02004145 PANIC("Snapshot storage already in use: %s", spath);
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01004146 }
4147 hdb_opts = drive_add(spath, HD_ALIAS, 1);
David 'Digit' Turner8fc3e6e2011-05-09 10:17:20 +02004148 /* See comment above to understand why this is needed. */
David 'Digit' Turner9fb360e2011-05-04 22:01:28 +02004149 qemu_opt_set(hdb_opts, "cache", "unsafe");
David 'Digit' Turner5f64b872011-02-28 23:23:05 +01004150 }
4151 }
4152
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004153 /* Set the VM's max heap size, passed as a boot property */
4154 if (android_hw->vm_heapSize > 0) {
4155 char tmp[64];
4156 snprintf(tmp, sizeof(tmp), "%dm", android_hw->vm_heapSize);
4157 boot_property_add("dalvik.vm.heapsize",tmp);
4158 }
4159
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004160 /* Initialize net speed and delays stuff. */
4161 if (android_parse_network_speed(android_op_netspeed) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004162 PANIC("invalid -netspeed parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004163 android_op_netspeed);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004164 }
4165
4166 if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004167 PANIC("invalid -netdelay parameter '%s'",
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004168 android_op_netdelay);
Vladimir Chtchetkinee1316862010-08-26 09:03:54 -07004169 }
4170
4171 if (android_op_netfast) {
4172 qemu_net_download_speed = 0;
4173 qemu_net_upload_speed = 0;
4174 qemu_net_min_latency = 0;
4175 qemu_net_max_latency = 0;
4176 }
4177
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004178 /* Initialize LCD density */
David 'Digit' Turner5377c5b2011-02-10 16:52:19 +01004179 if (android_hw->hw_lcd_density) {
4180 long density = android_hw->hw_lcd_density;
4181 if (density <= 0) {
4182 PANIC("Invalid hw.lcd.density value: %ld", density);
Vladimir Chtchetkineb25bf2a2010-09-08 11:09:23 -07004183 }
4184 hwLcd_setBootProperty(density);
4185 }
4186
Vladimir Chtchetkine318f17a2010-08-27 09:09:45 -07004187 /* Initialize TCP dump */
4188 if (android_op_tcpdump) {
4189 if (qemu_tcpdump_start(android_op_tcpdump) < 0) {
4190 fprintf(stdout, "could not start packet capture: %s\n", strerror(errno));
4191 }
4192 }
4193
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004194 /* Initialize modem */
4195 if (android_op_radio) {
4196 CharDriverState* cs = qemu_chr_open("radio", android_op_radio, NULL);
4197 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004198 PANIC("unsupported character device specification: %s\n"
4199 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004200 android_op_radio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004201 }
4202 android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
4203 } else if (android_hw->hw_gsmModem != 0 ) {
4204 if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004205 PANIC("could not initialize qemud 'gsm' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004206 }
4207 }
4208
4209 /* Initialize GPS */
4210 if (android_op_gps) {
4211 CharDriverState* cs = qemu_chr_open("gps", android_op_gps, NULL);
4212 if (cs == NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004213 PANIC("unsupported character device specification: %s\n"
4214 "used -help-char-devices for list of available formats",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004215 android_op_gps);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004216 }
4217 android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
4218 } else if (android_hw->hw_gps != 0) {
4219 if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004220 PANIC("could not initialize qemud 'gps' channel");
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004221 }
4222 }
4223
4224 /* Initialize audio. */
4225 if (android_op_audio) {
David 'Digit' Turnercc3b2192011-05-21 00:42:27 +02004226 char temp[128];
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004227 if ( !audio_check_backend_name( 0, android_op_audio ) ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004228 PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004229 android_op_audio);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004230 }
David 'Digit' Turnercc3b2192011-05-21 00:42:27 +02004231 snprintf(temp, sizeof temp, "QEMU_AUDIO_DRV=%s", android_op_audio);
4232 putenv(temp);
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004233 }
4234
David 'Digit' Turner5b481492011-04-11 17:37:32 +02004235 /* Initialize OpenGLES emulation */
David 'Digit' Turnerd4d688e2011-04-26 18:09:17 +02004236 //android_hw_opengles_init();
David 'Digit' Turner5b481492011-04-11 17:37:32 +02004237
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004238 if (android_op_cpu_delay) {
4239 char* end;
4240 long delay = strtol(android_op_cpu_delay, &end, 0);
4241 if (end == NULL || *end || delay < 0 || delay > 1000 ) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004242 PANIC("option -cpu-delay must be an integer between 0 and 1000" );
Vladimir Chtchetkineb2438402010-08-24 08:55:33 -07004243 }
4244 if (delay > 0)
4245 delay = (1000-delay);
4246
4247 qemu_cpu_delay = (int) delay;
4248 }
4249
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004250 if (android_op_dns_server) {
4251 char* x = strchr(android_op_dns_server, ',');
4252 dns_count = 0;
4253 if (x == NULL)
4254 {
4255 if ( add_dns_server( android_op_dns_server ) == 0 )
4256 dns_count = 1;
4257 }
4258 else
4259 {
4260 x = android_op_dns_server;
4261 while (*x) {
4262 char* y = strchr(x, ',');
4263
4264 if (y != NULL) {
4265 *y = 0;
4266 y++;
4267 } else {
4268 y = x + strlen(x);
4269 }
4270
4271 if (y > x && add_dns_server( x ) == 0) {
4272 dns_count += 1;
4273 }
4274 x = y;
4275 }
4276 }
4277 if (dns_count == 0)
4278 fprintf( stdout, "### WARNING: will use system default DNS server\n" );
4279 }
4280
4281 if (dns_count == 0)
4282 dns_count = slirp_get_system_dns_servers();
4283 if (dns_count) {
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004284 stralloc_add_format(kernel_config, " ndns=%d", dns_count);
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004285 }
4286
Vladimir Chtchetkineb5365f32010-08-09 13:33:57 -07004287#ifdef CONFIG_MEMCHECK
4288 if (android_op_memcheck) {
4289 memcheck_init(android_op_memcheck);
4290 }
4291#endif // CONFIG_MEMCHECK
4292
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01004293 /* Initialize cache partition, if any */
4294 if (android_hw->disk_cachePartition != 0) {
4295 char tmp[PATH_MAX+32];
4296 const char* partPath = android_hw->disk_cachePartition_path;
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01004297 uint64_t partSize = android_hw->disk_cachePartition_size;
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01004298
David 'Digit' Turnere8ab08c2011-03-15 23:08:50 +01004299 snprintf(tmp,sizeof(tmp),"cache,size=0x%" PRUx64, partSize);
4300
4301 if (partPath && *partPath && strcmp(partPath, "<temp>") != 0) {
4302 if (filelock_create(partPath) == NULL) {
4303 fprintf(stderr, "WARNING: Cache partition already in use. Changes will not persist!\n");
4304 /* Note: if there is no file= parameters, nand_add_dev() will
4305 * create a temporary file to back the partition image. */
4306 } else {
4307 /* Create the file if needed */
4308 if (!path_exists(partPath)) {
4309 if (path_empty_file(partPath) < 0) {
4310 PANIC("Could not create cache image file %s: %s", partPath, strerror(errno));
4311 }
4312 }
4313 pstrcat(tmp, sizeof(tmp), ",file=");
4314 pstrcat(tmp, sizeof(tmp), partPath);
4315 }
David 'Digit' Turnerc480cca2011-02-25 16:43:34 +01004316 }
4317 nand_add_dev(tmp);
4318 }
4319
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01004320 /* We always force qemu=1 when running inside QEMU */
4321 stralloc_add_str(kernel_params, " qemu=1");
4322
4323 /* We always initialize the first serial port for the android-kmsg
4324 * character device (used to send kernel messages) */
4325 serial_hds_add_at(0, "android-kmsg");
4326 stralloc_add_str(kernel_params, " console=ttyS0");
4327
4328 /* We always initialize the second serial port for the android-qemud
4329 * character device as well */
4330 serial_hds_add_at(1, "android-qemud");
4331 stralloc_add_str(kernel_params, " android.qemud=ttyS1");
4332
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004333 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
4334 os_pidfile_error();
4335 exit(1);
4336 }
4337
David 'Digit' Turner36597752011-05-20 01:18:01 +02004338#if defined(CONFIG_KVM)
4339 if (kvm_allowed < 0) {
4340 kvm_allowed = kvm_check_allowed();
4341 }
4342#endif
4343
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004344#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
4345 if (kvm_allowed && kqemu_allowed) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004346 PANIC(
4347 "You can not enable both KVM and kqemu at the same time");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004348 }
4349#endif
4350
4351 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
4352 if (smp_cpus > machine->max_cpus) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004353 PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
4354 "supported by machine `%s' (%d)", smp_cpus, machine->name,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004355 machine->max_cpus);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004356 }
4357
4358 if (display_type == DT_NOGRAPHIC) {
4359 if (serial_device_index == 0)
4360 serial_devices[0] = "stdio";
4361 if (parallel_device_index == 0)
4362 parallel_devices[0] = "null";
4363 if (strncmp(monitor_device, "vc", 2) == 0)
4364 monitor_device = "stdio";
4365 }
4366
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004367#ifdef CONFIG_KQEMU
4368 if (smp_cpus > 1)
4369 kqemu_allowed = 0;
4370#endif
4371 if (qemu_init_main_loop()) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004372 PANIC("qemu_init_main_loop failed");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004373 }
David 'Digit' Turner0b019492011-03-01 14:02:42 +01004374
4375 if (kernel_filename == NULL) {
4376 kernel_filename = android_hw->kernel_path;
4377 }
4378 if (initrd_filename == NULL) {
4379 initrd_filename = android_hw->disk_ramdisk_path;
4380 }
4381
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004382 linux_boot = (kernel_filename != NULL);
4383 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
4384
4385 if (!linux_boot && *kernel_cmdline != '\0') {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004386 PANIC("-append only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004387 }
4388
4389 if (!linux_boot && initrd_filename != NULL) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004390 PANIC("-initrd only allowed with -kernel option");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004391 }
4392
4393 /* boot to floppy or the default cd if no hard disk defined yet */
4394 if (!boot_devices[0]) {
4395 boot_devices = "cad";
4396 }
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004397 os_set_line_buffering();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004398
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004399 if (init_timer_alarm() < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004400 PANIC("could not initialize alarm timer");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004401 }
David Turner6a9ef172010-09-09 22:54:36 +02004402 configure_icount(icount_option);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004403
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004404 /* init network clients */
4405 if (nb_net_clients == 0) {
4406 /* if no clients, we use a default config */
4407 net_clients[nb_net_clients++] = "nic";
4408#ifdef CONFIG_SLIRP
4409 net_clients[nb_net_clients++] = "user";
4410#endif
4411 }
4412
4413 for(i = 0;i < nb_net_clients; i++) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004414 if (net_client_parse(net_clients[i]) < 0) {
4415 PANIC("Unable to parse net clients");
4416 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004417 }
4418 net_client_check();
4419
4420#ifdef TARGET_I386
4421 /* XXX: this should be moved in the PC machine instantiation code */
4422 if (net_boot != 0) {
4423 int netroms = 0;
4424 for (i = 0; i < nb_nics && i < 4; i++) {
4425 const char *model = nd_table[i].model;
4426 char buf[1024];
4427 char *filename;
4428 if (net_boot & (1 << i)) {
4429 if (model == NULL)
4430 model = "ne2k_pci";
4431 snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
4432 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
4433 if (filename && get_image_size(filename) > 0) {
4434 if (nb_option_roms >= MAX_OPTION_ROMS) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004435 PANIC("Too many option ROMs");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004436 }
4437 option_rom[nb_option_roms] = qemu_strdup(buf);
4438 nb_option_roms++;
4439 netroms++;
4440 }
4441 if (filename) {
4442 qemu_free(filename);
4443 }
4444 }
4445 }
4446 if (netroms == 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004447 PANIC("No valid PXE rom found for network device");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004448 }
4449 }
4450#endif
4451
4452 /* init the bluetooth world */
4453 for (i = 0; i < nb_bt_opts; i++)
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004454 if (bt_parse(bt_opts[i])) {
4455 PANIC("Unable to parse bluetooth options");
4456 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004457
4458 /* init the memory */
David 'Digit' Turner5377c5b2011-02-10 16:52:19 +01004459 if (ram_size == 0) {
4460 ram_size = android_hw->hw_ramSize * 1024LL * 1024;
4461 if (ram_size == 0) {
4462 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
4463 }
4464 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004465
4466#ifdef CONFIG_KQEMU
4467 /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
4468 guest ram allocation. It needs to go away. */
4469 if (kqemu_allowed) {
4470 kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
4471 kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
4472 if (!kqemu_phys_ram_base) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004473 PANIC("Could not allocate physical memory");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004474 }
4475 }
4476#endif
4477
rich canningsd952f282011-03-01 15:40:09 -08004478#ifndef _WIN32
4479 init_qemu_clear_logs_sig();
4480#endif
4481
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004482 /* init the dynamic translator */
4483 cpu_exec_init_all(tb_size * 1024 * 1024);
4484
4485 bdrv_init();
4486
4487 /* we always create the cdrom drive, even if no disk is there */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004488#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004489 if (nb_drives_opt < MAX_DRIVES)
4490 drive_add(NULL, CDROM_ALIAS);
4491
4492 /* we always create at least one floppy */
4493
4494 if (nb_drives_opt < MAX_DRIVES)
4495 drive_add(NULL, FD_ALIAS, 0);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004496 /* we always create one sd slot, even if no card is in it */
4497
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004498 if (1) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004499 drive_add(NULL, SD_ALIAS);
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004500 }
4501#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004502
4503 /* open the virtual block devices */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004504 if (snapshot)
4505 qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
4506 if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
4507 exit(1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004508
David Turner6a9ef172010-09-09 22:54:36 +02004509 //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004510 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
4511
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004512 /* must be after terminal init, SDL library changes signal handlers */
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004513 os_setup_signal_handling();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004514
4515 /* Maintain compatibility with multiple stdio monitors */
4516 if (!strcmp(monitor_device,"stdio")) {
4517 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
4518 const char *devname = serial_devices[i];
4519 if (devname && !strcmp(devname,"mon:stdio")) {
4520 monitor_device = NULL;
4521 break;
4522 } else if (devname && !strcmp(devname,"stdio")) {
4523 monitor_device = NULL;
4524 serial_devices[i] = "mon:stdio";
4525 break;
4526 }
4527 }
4528 }
4529
4530 if (nb_numa_nodes > 0) {
4531 int i;
4532
4533 if (nb_numa_nodes > smp_cpus) {
4534 nb_numa_nodes = smp_cpus;
4535 }
4536
4537 /* If no memory size if given for any node, assume the default case
4538 * and distribute the available memory equally across all nodes
4539 */
4540 for (i = 0; i < nb_numa_nodes; i++) {
4541 if (node_mem[i] != 0)
4542 break;
4543 }
4544 if (i == nb_numa_nodes) {
4545 uint64_t usedmem = 0;
4546
4547 /* On Linux, the each node's border has to be 8MB aligned,
4548 * the final node gets the rest.
4549 */
4550 for (i = 0; i < nb_numa_nodes - 1; i++) {
4551 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
4552 usedmem += node_mem[i];
4553 }
4554 node_mem[i] = ram_size - usedmem;
4555 }
4556
4557 for (i = 0; i < nb_numa_nodes; i++) {
4558 if (node_cpumask[i] != 0)
4559 break;
4560 }
4561 /* assigning the VCPUs round-robin is easier to implement, guest OSes
4562 * must cope with this anyway, because there are BIOSes out there in
4563 * real machines which also use this scheme.
4564 */
4565 if (i == nb_numa_nodes) {
4566 for (i = 0; i < smp_cpus; i++) {
4567 node_cpumask[i % nb_numa_nodes] |= 1 << i;
4568 }
4569 }
4570 }
4571
4572 if (kvm_enabled()) {
4573 int ret;
4574
4575 ret = kvm_init(smp_cpus);
4576 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004577 PANIC("failed to initialize KVM");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004578 }
4579 }
4580
4581 if (monitor_device) {
4582 monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
4583 if (!monitor_hd) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004584 PANIC("qemu: could not open monitor device '%s'",
4585 monitor_device);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004586 }
4587 }
4588
4589 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01004590 serial_hds_add(serial_devices[i]);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004591 }
4592
4593 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
4594 const char *devname = parallel_devices[i];
4595 if (devname && strcmp(devname, "none")) {
4596 char label[32];
4597 snprintf(label, sizeof(label), "parallel%d", i);
4598 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
4599 if (!parallel_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004600 PANIC("qemu: could not open parallel device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004601 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004602 }
4603 }
4604 }
4605
4606 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
4607 const char *devname = virtio_consoles[i];
4608 if (devname && strcmp(devname, "none")) {
4609 char label[32];
4610 snprintf(label, sizeof(label), "virtcon%d", i);
4611 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
4612 if (!virtcon_hds[i]) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004613 PANIC("qemu: could not open virtio console '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004614 devname);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004615 }
4616 }
4617 }
4618
4619 module_call_init(MODULE_INIT_DEVICE);
4620
4621
4622#ifdef CONFIG_TRACE
4623 if (trace_filename) {
4624 trace_init(trace_filename);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004625 fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
4626 }
4627#endif
4628
David 'Digit' Turner2d238fd2011-03-25 10:34:47 +01004629 /* Check the CPU Architecture value */
4630#if defined(TARGET_ARM)
4631 if (strcmp(android_hw->hw_cpu_arch,"arm") != 0) {
4632 fprintf(stderr, "-- Invalid CPU architecture: %s, expected 'arm'\n",
4633 android_hw->hw_cpu_arch);
4634 exit(1);
4635 }
4636#elif defined(TARGET_X86)
4637 if (strcmp(android_hw->hw_cpu_arch,"x86") != 0) {
4638 fprintf(stderr, "-- Invalid CPU architecture: %s, expected 'x86'\n",
4639 android_hw->hw_cpu_arch);
4640 exit(1);
4641 }
4642#endif
4643
4644 /* Grab CPU model if provided in hardware.ini */
4645 if ( !cpu_model
4646 && android_hw->hw_cpu_model
4647 && android_hw->hw_cpu_model[0] != '\0')
4648 {
4649 cpu_model = android_hw->hw_cpu_model;
4650 }
4651
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004652 /* Combine kernel command line passed from the UI with parameters
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004653 * collected during initialization.
4654 *
4655 * The order is the following:
4656 * - parameters from the hw configuration (kernel.parameters)
4657 * - additionnal parameters from options (e.g. -memcheck)
4658 * - the -append parameters.
4659 */
4660 {
4661 const char* kernel_parameters;
Vladimir Chtchetkine7fbf4972010-08-11 15:30:32 -07004662
David 'Digit' Turner0b019492011-03-01 14:02:42 +01004663 if (android_hw->kernel_parameters) {
David 'Digit' Turner62c7ae52011-03-08 15:46:53 +01004664 stralloc_add_c(kernel_params, ' ');
David 'Digit' Turner0b019492011-03-01 14:02:42 +01004665 stralloc_add_str(kernel_params, android_hw->kernel_parameters);
4666 }
4667
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004668 /* If not empty, kernel_config always contains a leading space */
4669 stralloc_append(kernel_params, kernel_config);
4670
4671 if (*kernel_cmdline) {
4672 stralloc_add_c(kernel_params, ' ');
4673 stralloc_add_str(kernel_params, kernel_cmdline);
4674 }
4675
David 'Digit' Turner062dd6a2011-03-01 14:50:07 +01004676 /* Remove any leading/trailing spaces */
4677 stralloc_strip(kernel_params);
4678
David 'Digit' Turner5f824112011-03-01 14:00:26 +01004679 kernel_parameters = stralloc_cstr(kernel_params);
4680 VERBOSE_PRINT(init, "Kernel parameters: %s", kernel_parameters);
4681
4682 machine->init(ram_size,
4683 boot_devices,
4684 kernel_filename,
4685 kernel_parameters,
4686 initrd_filename,
4687 cpu_model);
4688
4689 stralloc_reset(kernel_params);
4690 stralloc_reset(kernel_config);
4691 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004692
4693
4694 for (env = first_cpu; env != NULL; env = env->next_cpu) {
4695 for (i = 0; i < nb_numa_nodes; i++) {
4696 if (node_cpumask[i] & (1 << env->cpu_index)) {
4697 env->numa_node = i;
4698 }
4699 }
4700 }
4701
4702 current_machine = machine;
4703
4704 /* Set KVM's vcpu state to qemu's initial CPUState. */
4705 if (kvm_enabled()) {
4706 int ret;
4707
4708 ret = kvm_sync_vcpus();
4709 if (ret < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004710 PANIC("failed to initialize vcpus");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004711 }
4712 }
4713
4714 /* init USB devices */
4715 if (usb_enabled) {
4716 for(i = 0; i < usb_devices_index; i++) {
4717 if (usb_device_add(usb_devices[i], 0) < 0) {
4718 fprintf(stderr, "Warning: could not add USB device %s\n",
4719 usb_devices[i]);
4720 }
4721 }
4722 }
4723
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08004724 /* just use the first displaystate for the moment */
David 'Digit' Turner94702b02011-01-20 02:46:33 +01004725 ds = get_displaystate();
Vladimir Chtchetkinecf755ea2011-01-12 14:38:19 -08004726
David 'Digit' Turner2507cab2011-02-10 16:29:17 +01004727 /* Initialize display from the command line parameters. */
4728 android_display_reset(ds,
4729 android_display_width,
4730 android_display_height,
4731 android_display_bpp);
Vladimir Chtchetkinedd50f7d2010-07-30 09:16:41 -07004732
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004733 if (display_type == DT_DEFAULT) {
4734#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
4735 display_type = DT_SDL;
4736#else
4737 display_type = DT_VNC;
4738 vnc_display = "localhost:0,to=99";
4739 show_vnc_port = 1;
4740#endif
4741 }
Vladimir Chtchetkined81e6d12010-06-15 16:46:32 -07004742
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004743
4744 switch (display_type) {
4745 case DT_NOGRAPHIC:
4746 break;
4747#if defined(CONFIG_CURSES)
4748 case DT_CURSES:
4749 curses_display_init(ds, full_screen);
4750 break;
4751#endif
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07004752#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004753 case DT_SDL:
4754 sdl_display_init(ds, full_screen, no_frame);
4755 break;
4756#elif defined(CONFIG_COCOA)
4757 case DT_SDL:
4758 cocoa_display_init(ds, full_screen);
4759 break;
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08004760#elif defined(CONFIG_STANDALONE_CORE)
4761 case DT_SDL:
Vladimir Chtchetkinee95660a2010-12-20 08:28:03 -08004762 coredisplay_init(ds);
Vladimir Chtchetkine72d83df2010-12-14 09:24:02 -08004763 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004764#endif
4765 case DT_VNC:
4766 vnc_display_init(ds);
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004767 if (vnc_display_open(ds, vnc_display) < 0) {
4768 PANIC("Unable to initialize VNC display");
4769 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004770
4771 if (show_vnc_port) {
4772 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
4773 }
4774 break;
4775 default:
4776 break;
4777 }
4778 dpy_resize(ds);
4779
4780 dcl = ds->listeners;
4781 while (dcl != NULL) {
4782 if (dcl->dpy_refresh != NULL) {
David 'Digit' Turner5973c772011-05-10 07:06:00 +02004783 ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
4784 qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004785 }
4786 dcl = dcl->next;
4787 }
4788
4789 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
David 'Digit' Turner5973c772011-05-10 07:06:00 +02004790 nographic_timer = qemu_new_timer_ms(rt_clock, nographic_update, NULL);
4791 qemu_mod_timer(nographic_timer, qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004792 }
4793
David 'Digit' Turner94702b02011-01-20 02:46:33 +01004794 text_consoles_set_display(ds);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004795 qemu_chr_initial_reset();
4796
4797 if (monitor_device && monitor_hd)
4798 monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
4799
4800 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
4801 const char *devname = serial_devices[i];
4802 if (devname && strcmp(devname, "none")) {
4803 if (strstart(devname, "vc", 0))
4804 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
4805 }
4806 }
4807
4808 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
4809 const char *devname = parallel_devices[i];
4810 if (devname && strcmp(devname, "none")) {
4811 if (strstart(devname, "vc", 0))
4812 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
4813 }
4814 }
4815
4816 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
4817 const char *devname = virtio_consoles[i];
4818 if (virtcon_hds[i] && devname) {
4819 if (strstart(devname, "vc", 0))
4820 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
4821 }
4822 }
4823
4824 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004825 PANIC("qemu: could not open gdbserver on device '%s'",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004826 gdbstub_dev);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004827 }
4828
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004829 /* call android-specific setup function */
4830 android_emulation_setup();
4831
Vladimir Chtchetkine57584042011-01-20 16:15:30 -08004832#if !defined(CONFIG_STANDALONE_CORE)
4833 // For the standalone emulator (UI+core in one executable) we need to
4834 // set the window title here.
4835 android_emulator_set_base_port(android_base_port);
4836#endif
4837
Ot ten Thije871da2a2010-09-20 10:29:22 +01004838 if (loadvm)
4839 do_loadvm(cur_mon, loadvm);
4840
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004841 if (incoming) {
4842 autostart = 0; /* fixme how to deal with -daemonize */
4843 qemu_start_incoming_migration(incoming);
4844 }
4845
4846 if (autostart)
4847 vm_start();
4848
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004849 os_setup_post();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004850
Vladimir Chtchetkine7746af02010-10-07 05:40:39 -07004851#ifdef CONFIG_ANDROID
4852 // This will notify the UI that the core is successfuly initialized
4853 android_core_init_completed();
4854#endif // CONFIG_ANDROID
4855
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004856 main_loop();
4857 quit_timers();
4858 net_cleanup();
4859 android_emulation_teardown();
4860 return 0;
4861}
Vladimir Chtchetkineeb838252010-07-15 12:27:56 -07004862
4863void
4864android_emulation_teardown(void)
4865{
4866 android_charmap_done();
4867}