blob: feb8831324aaba9bc6d8a80b370fe4fbc1412ea4 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/*
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 */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080024#include <unistd.h>
25#include <fcntl.h>
26#include <signal.h>
27#include <time.h>
28#include <errno.h>
29#include <sys/time.h>
30#include <zlib.h>
31
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070032/* Needed early for CONFIG_BSD etc. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070033#include "config-host.h"
34
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080035#ifndef _WIN32
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070036#include <libgen.h>
37#include <pwd.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080038#include <sys/times.h>
39#include <sys/wait.h>
40#include <termios.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080041#include <sys/mman.h>
42#include <sys/ioctl.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070043#include <sys/resource.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080044#include <sys/socket.h>
45#include <netinet/in.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070046#include <net/if.h>
47#if defined(__NetBSD__)
48#include <net/if_tap.h>
49#endif
50#ifdef __linux__
51#include <linux/if_tun.h>
52#endif
53#include <arpa/inet.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080054#include <dirent.h>
55#include <netdb.h>
56#include <sys/select.h>
David 'Digit' Turner2c538c82010-05-10 16:48:20 -070057#ifdef CONFIG_BSD
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080058#include <sys/stat.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070059#if defined(__FreeBSD__) || defined(__DragonFly__)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080060#include <libutil.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070061#else
62#include <util.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080063#endif
64#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
65#include <freebsd/stdlib.h>
66#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070067#ifdef __linux__
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080068#include <pty.h>
69#include <malloc.h>
70#include <linux/rtc.h>
71
72/* For the benefit of older linux systems which don't supply it,
73 we use a local copy of hpet.h. */
74/* #include <linux/hpet.h> */
75#include "hpet.h"
76
77#include <linux/ppdev.h>
78#include <linux/parport.h>
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070079#endif
80#ifdef __sun__
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080081#include <sys/stat.h>
82#include <sys/ethernet.h>
83#include <sys/sockio.h>
84#include <netinet/arp.h>
85#include <netinet/in.h>
86#include <netinet/in_systm.h>
87#include <netinet/ip.h>
88#include <netinet/ip_icmp.h> // must come after ip.h
89#include <netinet/udp.h>
90#include <netinet/tcp.h>
91#include <net/if.h>
92#include <syslog.h>
93#include <stropts.h>
94#endif
95#endif
96#endif
97
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080098#if defined(__OpenBSD__)
99#include <util.h>
100#endif
101
102#if defined(CONFIG_VDE)
103#include <libvdeplug.h>
104#endif
105
106#ifdef _WIN32
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700107#include <windows.h>
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800108#include <malloc.h>
109#include <sys/timeb.h>
110#include <mmsystem.h>
111#define getopt_long_only getopt_long
112#define memalign(align, size) malloc(size)
113#endif
114
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700115#ifdef CONFIG_SDL
116#ifdef __APPLE__
117#include <SDL.h>
118int qemu_main(int argc, char **argv, char **envp);
119int main(int argc, char **argv)
120{
121 qemu_main(argc, argv, NULL);
122}
123#undef main
124#define main qemu_main
125#endif
126#endif /* CONFIG_SDL */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800127
128#ifdef CONFIG_COCOA
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +0200129int qemu_main(int argc, char **argv, char **envp);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800130#undef main
131#define main qemu_main
132#endif /* CONFIG_COCOA */
133
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700134#include "hw/hw.h"
135#include "hw/boards.h"
136#include "hw/usb.h"
137#include "hw/pcmcia.h"
138#include "hw/pc.h"
139#include "hw/audiodev.h"
140#include "hw/isa.h"
141#include "hw/baum.h"
142#include "hw/bt.h"
143#include "hw/watchdog.h"
144#include "hw/smbios.h"
145#include "hw/xen.h"
146#include "bt-host.h"
147#include "net.h"
148#include "monitor.h"
149#include "console.h"
150#include "sysemu.h"
151#include "gdbstub.h"
152#include "qemu-timer.h"
153#include "qemu-char.h"
154#include "cache-utils.h"
155#include "block.h"
156#include "dma.h"
157#include "audio/audio.h"
158#include "migration.h"
159#include "kvm.h"
160#include "balloon.h"
161#include "qemu-option.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800162
163#include "disas.h"
164
165#include "exec-all.h"
166
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700167#include "qemu_socket.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800168
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700169#if defined(CONFIG_SLIRP)
170#include "libslirp.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800171#endif
172
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800173
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700174
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700175#define DEFAULT_RAM_SIZE 128
176
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800177/* Max number of USB devices that can be specified on the commandline. */
178#define MAX_USB_CMDLINE 8
179
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700180/* Max number of bluetooth switches on the commandline. */
181#define MAX_BT_CMDLINE 10
182
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800183/* XXX: use a two level table to limit memory usage */
184#define MAX_IOPORTS 65536
185
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700186static const char *data_dir;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800187const char *bios_name = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700188static void *ioport_opaque[MAX_IOPORTS];
189static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
190static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800191/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
192 to store the VM snapshots */
193DriveInfo drives_table[MAX_DRIVES+1];
194int nb_drives;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700195enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700196DisplayType display_type = DT_DEFAULT;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800197const char* keyboard_layout = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800198ram_addr_t ram_size;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800199int nb_nics;
200NICInfo nd_table[MAX_NICS];
201int vm_running;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700202static int autostart;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800203static int rtc_utc = 1;
204static int rtc_date_offset = -1; /* -1 means no change */
205int cirrus_vga_enabled = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700206int std_vga_enabled = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800207int vmsvga_enabled = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700208int xenfb_enabled = 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700209QEMUClock *rtc_clock;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800210#ifdef TARGET_SPARC
211int graphic_width = 1024;
212int graphic_height = 768;
213int graphic_depth = 8;
214#else
215int graphic_width = 800;
216int graphic_height = 600;
217int graphic_depth = 15;
218#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700219static int full_screen = 0;
220#ifdef CONFIG_SDL
221static int no_frame = 0;
222#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800223int no_quit = 0;
224CharDriverState *serial_hds[MAX_SERIAL_PORTS];
225CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700226CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800227#ifdef TARGET_I386
228int win2k_install_hack = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700229int rtc_td_hack = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800230#endif
231int usb_enabled = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700232int singlestep = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800233int smp_cpus = 1;
234const char *vnc_display;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800235int acpi_enabled = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700236int no_hpet = 0;
237int no_virtio_balloon = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800238int fd_bootchk = 1;
239int no_reboot = 0;
240int no_shutdown = 0;
241int cursor_hide = 1;
242int graphic_rotate = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700243WatchdogTimerModel *watchdog = NULL;
244int watchdog_action = WDT_RESET;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800245const char *option_rom[MAX_OPTION_ROMS];
246int nb_option_roms;
247int semihosting_enabled = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800248#ifdef TARGET_ARM
249int old_param = 0;
250#endif
251const char *qemu_name;
252int alt_grab = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700253#if defined(TARGET_SPARC) || defined(TARGET_PPC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800254unsigned int nb_prom_envs = 0;
255const char *prom_envs[MAX_PROM_ENVS];
256#endif
257int nb_drives_opt;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700258struct drive_opt drives_opt[MAX_DRIVES];
259
260int nb_numa_nodes;
261uint64_t node_mem[MAX_NODES];
262uint64_t node_cpumask[MAX_NODES];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800263
264static CPUState *cur_cpu;
265static CPUState *next_cpu;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700266static int timer_alarm_pending = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700267static QEMUTimer *nographic_timer;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800268
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700269uint8_t qemu_uuid[16];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800270
271/***********************************************************/
272/* x86 ISA bus support */
273
274target_phys_addr_t isa_mem_base = 0;
275PicState2 *isa_pic;
276
277static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
278static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
279
280static uint32_t ioport_read(int index, uint32_t address)
281{
282 static IOPortReadFunc *default_func[3] = {
283 default_ioport_readb,
284 default_ioport_readw,
285 default_ioport_readl
286 };
287 IOPortReadFunc *func = ioport_read_table[index][address];
288 if (!func)
289 func = default_func[index];
290 return func(ioport_opaque[address], address);
291}
292
293static void ioport_write(int index, uint32_t address, uint32_t data)
294{
295 static IOPortWriteFunc *default_func[3] = {
296 default_ioport_writeb,
297 default_ioport_writew,
298 default_ioport_writel
299 };
300 IOPortWriteFunc *func = ioport_write_table[index][address];
301 if (!func)
302 func = default_func[index];
303 func(ioport_opaque[address], address, data);
304}
305
306static uint32_t default_ioport_readb(void *opaque, uint32_t address)
307{
308#ifdef DEBUG_UNUSED_IOPORT
309 fprintf(stderr, "unused inb: port=0x%04x\n", address);
310#endif
311 return 0xff;
312}
313
314static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
315{
316#ifdef DEBUG_UNUSED_IOPORT
317 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
318#endif
319}
320
321/* default is to make two byte accesses */
322static uint32_t default_ioport_readw(void *opaque, uint32_t address)
323{
324 uint32_t data;
325 data = ioport_read(0, address);
326 address = (address + 1) & (MAX_IOPORTS - 1);
327 data |= ioport_read(0, address) << 8;
328 return data;
329}
330
331static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
332{
333 ioport_write(0, address, data & 0xff);
334 address = (address + 1) & (MAX_IOPORTS - 1);
335 ioport_write(0, address, (data >> 8) & 0xff);
336}
337
338static uint32_t default_ioport_readl(void *opaque, uint32_t address)
339{
340#ifdef DEBUG_UNUSED_IOPORT
341 fprintf(stderr, "unused inl: port=0x%04x\n", address);
342#endif
343 return 0xffffffff;
344}
345
346static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
347{
348#ifdef DEBUG_UNUSED_IOPORT
349 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
350#endif
351}
352
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800353
354/***********************************************************/
355void hw_error(const char *fmt, ...)
356{
357 va_list ap;
358 CPUState *env;
359
360 va_start(ap, fmt);
361 fprintf(stderr, "qemu: hardware error: ");
362 vfprintf(stderr, fmt, ap);
363 fprintf(stderr, "\n");
364 for(env = first_cpu; env != NULL; env = env->next_cpu) {
365 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
366#ifdef TARGET_I386
367 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
368#else
369 cpu_dump_state(env, stderr, fprintf, 0);
370#endif
371 }
372 va_end(ap);
373 abort();
374}
David 'Digit' Turner707c8a82010-12-22 22:35:58 +0100375
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700376/***************/
377/* ballooning */
378
379static QEMUBalloonEvent *qemu_balloon_event;
380void *qemu_balloon_event_opaque;
381
382void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
383{
384 qemu_balloon_event = func;
385 qemu_balloon_event_opaque = opaque;
386}
387
388void qemu_balloon(ram_addr_t target)
389{
390 if (qemu_balloon_event)
391 qemu_balloon_event(qemu_balloon_event_opaque, target);
392}
393
394ram_addr_t qemu_balloon_status(void)
395{
396 if (qemu_balloon_event)
397 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
398 return 0;
399}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800400
401/***********************************************************/
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800402/* host time/date access */
403void qemu_get_timedate(struct tm *tm, int offset)
404{
405 time_t ti;
406 struct tm *ret;
407
408 time(&ti);
409 ti += offset;
410 if (rtc_date_offset == -1) {
411 if (rtc_utc)
412 ret = gmtime(&ti);
413 else
414 ret = localtime(&ti);
415 } else {
416 ti -= rtc_date_offset;
417 ret = gmtime(&ti);
418 }
419
420 memcpy(tm, ret, sizeof(struct tm));
421}
422
423int qemu_timedate_diff(struct tm *tm)
424{
425 time_t seconds;
426
427 if (rtc_date_offset == -1)
428 if (rtc_utc)
429 seconds = mktimegm(tm);
430 else
431 seconds = mktime(tm);
432 else
433 seconds = mktimegm(tm) + rtc_date_offset;
434
435 return seconds - time(NULL);
436}
437
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800438#ifdef _WIN32
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700439static void socket_cleanup(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800440{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700441 WSACleanup();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800442}
443
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700444static int socket_init(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800445{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700446 WSADATA Data;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800447 int ret, err;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800448
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700449 ret = WSAStartup(MAKEWORD(2,2), &Data);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800450 if (ret != 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700451 err = WSAGetLastError();
452 fprintf(stderr, "WSAStartup: %d\n", err);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800453 return -1;
454 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700455 atexit(socket_cleanup);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800456 return 0;
457}
458#endif
459
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700460int get_param_value(char *buf, int buf_size,
461 const char *tag, const char *str)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800462{
463 const char *p;
464 char option[128];
465
466 p = str;
467 for(;;) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700468 p = get_opt_name(option, sizeof(option), p, '=');
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800469 if (*p != '=')
470 break;
471 p++;
472 if (!strcmp(tag, option)) {
473 (void)get_opt_value(buf, buf_size, p);
474 return strlen(buf);
475 } else {
476 p = get_opt_value(NULL, 0, p);
477 }
478 if (*p != ',')
479 break;
480 p++;
481 }
482 return 0;
483}
484
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700485int check_params(char *buf, int buf_size,
486 const char * const *params, const char *str)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800487{
488 const char *p;
489 int i;
490
491 p = str;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700492 while (*p != '\0') {
493 p = get_opt_name(buf, buf_size, p, '=');
494 if (*p != '=') {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800495 return -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700496 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800497 p++;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700498 for (i = 0; params[i] != NULL; i++) {
499 if (!strcmp(params[i], buf)) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800500 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700501 }
502 }
503 if (params[i] == NULL) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800504 return -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700505 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800506 p = get_opt_value(NULL, 0, p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700507 if (*p != ',') {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800508 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700509 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800510 p++;
511 }
512 return 0;
513}
514
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700515/***********************************************************/
516/* Bluetooth support */
517static int nb_hcis;
518static int cur_hci;
519static struct HCIInfo *hci_table[MAX_NICS];
520
521static struct bt_vlan_s {
522 struct bt_scatternet_s net;
523 int id;
524 struct bt_vlan_s *next;
525} *first_bt_vlan;
526
527/* find or alloc a new bluetooth "VLAN" */
528static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800529{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700530 struct bt_vlan_s **pvlan, *vlan;
531 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
532 if (vlan->id == id)
533 return &vlan->net;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800534 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700535 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
536 vlan->id = id;
537 pvlan = &first_bt_vlan;
538 while (*pvlan != NULL)
539 pvlan = &(*pvlan)->next;
540 *pvlan = vlan;
541 return &vlan->net;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800542}
543
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700544static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800545{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800546}
547
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700548static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800549{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700550 return -ENOTSUP;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800551}
552
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700553static struct HCIInfo null_hci = {
554 .cmd_send = null_hci_send,
555 .sco_send = null_hci_send,
556 .acl_send = null_hci_send,
557 .bdaddr_set = null_hci_addr_set,
558};
559
560struct HCIInfo *qemu_next_hci(void)
561{
562 if (cur_hci == nb_hcis)
563 return &null_hci;
564
565 return hci_table[cur_hci++];
566}
567
568static struct HCIInfo *hci_init(const char *str)
569{
570 char *endp;
571 struct bt_scatternet_s *vlan = 0;
572
573 if (!strcmp(str, "null"))
574 /* null */
575 return &null_hci;
576 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
577 /* host[:hciN] */
578 return bt_host_hci(str[4] ? str + 5 : "hci0");
579 else if (!strncmp(str, "hci", 3)) {
580 /* hci[,vlan=n] */
581 if (str[3]) {
582 if (!strncmp(str + 3, ",vlan=", 6)) {
583 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
584 if (*endp)
585 vlan = 0;
586 }
587 } else
588 vlan = qemu_find_bt_vlan(0);
589 if (vlan)
590 return bt_new_hci(vlan);
591 }
592
593 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
594
595 return 0;
596}
597
598static int bt_hci_parse(const char *str)
599{
600 struct HCIInfo *hci;
601 bdaddr_t bdaddr;
602
603 if (nb_hcis >= MAX_NICS) {
604 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
605 return -1;
606 }
607
608 hci = hci_init(str);
609 if (!hci)
610 return -1;
611
612 bdaddr.b[0] = 0x52;
613 bdaddr.b[1] = 0x54;
614 bdaddr.b[2] = 0x00;
615 bdaddr.b[3] = 0x12;
616 bdaddr.b[4] = 0x34;
617 bdaddr.b[5] = 0x56 + nb_hcis;
618 hci->bdaddr_set(hci, bdaddr.b);
619
620 hci_table[nb_hcis++] = hci;
621
622 return 0;
623}
624
625static void bt_vhci_add(int vlan_id)
626{
627 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
628
629 if (!vlan->slave)
630 fprintf(stderr, "qemu: warning: adding a VHCI to "
631 "an empty scatternet %i\n", vlan_id);
632
633 bt_vhci_init(bt_new_hci(vlan));
634}
635
636static struct bt_device_s *bt_device_add(const char *opt)
637{
638 struct bt_scatternet_s *vlan;
639 int vlan_id = 0;
640 char *endp = strstr(opt, ",vlan=");
641 int len = (endp ? endp - opt : strlen(opt)) + 1;
642 char devname[10];
643
644 pstrcpy(devname, MIN(sizeof(devname), len), opt);
645
646 if (endp) {
647 vlan_id = strtol(endp + 6, &endp, 0);
648 if (*endp) {
649 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
650 return 0;
651 }
652 }
653
654 vlan = qemu_find_bt_vlan(vlan_id);
655
656 if (!vlan->slave)
657 fprintf(stderr, "qemu: warning: adding a slave device to "
658 "an empty scatternet %i\n", vlan_id);
659
660 if (!strcmp(devname, "keyboard"))
661 return bt_keyboard_init(vlan);
662
663 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
664 return 0;
665}
666
667static int bt_parse(const char *opt)
668{
669 const char *endp, *p;
670 int vlan;
671
672 if (strstart(opt, "hci", &endp)) {
673 if (!*endp || *endp == ',') {
674 if (*endp)
675 if (!strstart(endp, ",vlan=", 0))
676 opt = endp + 1;
677
678 return bt_hci_parse(opt);
679 }
680 } else if (strstart(opt, "vhci", &endp)) {
681 if (!*endp || *endp == ',') {
682 if (*endp) {
683 if (strstart(endp, ",vlan=", &p)) {
684 vlan = strtol(p, (char **) &endp, 0);
685 if (*endp) {
686 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
687 return 1;
688 }
689 } else {
690 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
691 return 1;
692 }
693 } else
694 vlan = 0;
695
696 bt_vhci_add(vlan);
697 return 0;
698 }
699 } else if (strstart(opt, "device:", &endp))
700 return !bt_device_add(endp);
701
702 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
703 return 1;
704}
705
706/***********************************************************/
707/* QEMU Block devices */
708
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800709#define HD_ALIAS "index=%d,media=disk"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800710#define CDROM_ALIAS "index=2,media=cdrom"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800711#define FD_ALIAS "index=%d,if=floppy"
712#define PFLASH_ALIAS "if=pflash"
713#define MTD_ALIAS "if=mtd"
714#define SD_ALIAS "index=0,if=sd"
715
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +0100716static int drive_init_func(QemuOpts *opts, void *opaque)
717{
718 int *use_scsi = opaque;
719 int fatal_error = 0;
720
721 if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
722 if (fatal_error)
723 return 1;
724 }
725 return 0;
726}
727
728static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
729{
730 if (NULL == qemu_opt_get(opts, "snapshot")) {
731 qemu_opt_set(opts, "snapshot", "on");
732 }
733 return 0;
734}
735
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700736static int drive_opt_get_free_idx(void)
737{
738 int index;
739
740 for (index = 0; index < MAX_DRIVES; index++)
741 if (!drives_opt[index].used) {
742 drives_opt[index].used = 1;
743 return index;
744 }
745
746 return -1;
747}
748
749static int drive_get_free_idx(void)
750{
751 int index;
752
753 for (index = 0; index < MAX_DRIVES; index++)
754 if (!drives_table[index].used) {
755 drives_table[index].used = 1;
756 return index;
757 }
758
759 return -1;
760}
761
762int drive_add(const char *file, const char *fmt, ...)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800763{
764 va_list ap;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700765 int index = drive_opt_get_free_idx();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800766
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700767 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800768 fprintf(stderr, "qemu: too many drives\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700769 return -1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800770 }
771
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700772 drives_opt[index].file = file;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800773 va_start(ap, fmt);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700774 vsnprintf(drives_opt[index].opt,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800775 sizeof(drives_opt[0].opt), fmt, ap);
776 va_end(ap);
777
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700778 nb_drives_opt++;
779 return index;
780}
781
782void drive_remove(int index)
783{
784 drives_opt[index].used = 0;
785 nb_drives_opt--;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800786}
787
788int drive_get_index(BlockInterfaceType type, int bus, int unit)
789{
790 int index;
791
792 /* seek interface, bus and unit */
793
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700794 for (index = 0; index < MAX_DRIVES; index++)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800795 if (drives_table[index].type == type &&
796 drives_table[index].bus == bus &&
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700797 drives_table[index].unit == unit &&
798 drives_table[index].used)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800799 return index;
800
801 return -1;
802}
803
804int drive_get_max_bus(BlockInterfaceType type)
805{
806 int max_bus;
807 int index;
808
809 max_bus = -1;
810 for (index = 0; index < nb_drives; index++) {
811 if(drives_table[index].type == type &&
812 drives_table[index].bus > max_bus)
813 max_bus = drives_table[index].bus;
814 }
815 return max_bus;
816}
817
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700818const char *drive_get_serial(BlockDriverState *bdrv)
819{
820 int index;
821
822 for (index = 0; index < nb_drives; index++)
823 if (drives_table[index].bdrv == bdrv)
824 return drives_table[index].serial;
825
826 return "\0";
827}
828
829BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
830{
831 int index;
832
833 for (index = 0; index < nb_drives; index++)
834 if (drives_table[index].bdrv == bdrv)
835 return drives_table[index].onerror;
836
837 return BLOCK_ERR_STOP_ENOSPC;
838}
839
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800840static void bdrv_format_print(void *opaque, const char *name)
841{
842 fprintf(stderr, " %s", name);
843}
844
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700845void drive_uninit(BlockDriverState *bdrv)
846{
847 int i;
848
849 for (i = 0; i < MAX_DRIVES; i++)
850 if (drives_table[i].bdrv == bdrv) {
851 drives_table[i].bdrv = NULL;
852 drives_table[i].used = 0;
853 drive_remove(drives_table[i].drive_opt_idx);
854 nb_drives--;
855 break;
856 }
857}
858
859int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800860{
861 char buf[128];
862 char file[1024];
863 char devname[128];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700864 char serial[21];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800865 const char *mediastr = "";
866 BlockInterfaceType type;
867 enum { MEDIA_DISK, MEDIA_CDROM } media;
868 int bus_id, unit_id;
869 int cyls, heads, secs, translation;
870 BlockDriverState *bdrv;
871 BlockDriver *drv = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700872 QEMUMachine *machine = opaque;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800873 int max_devs;
874 int index;
875 int cache;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700876 int bdrv_flags, onerror;
877 int drives_table_idx;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800878 char *str = arg->opt;
879 static const char * const params[] = { "bus", "unit", "if", "index",
880 "cyls", "heads", "secs", "trans",
881 "media", "snapshot", "file",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700882 "cache", "format", "serial", "werror",
883 NULL };
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800884
885 if (check_params(buf, sizeof(buf), params, str) < 0) {
886 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
887 buf, str);
888 return -1;
889 }
890
891 file[0] = 0;
892 cyls = heads = secs = 0;
893 bus_id = 0;
894 unit_id = -1;
895 translation = BIOS_ATA_TRANSLATION_AUTO;
896 index = -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700897 cache = 3;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800898
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700899 if (machine->use_scsi) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800900 type = IF_SCSI;
901 max_devs = MAX_SCSI_DEVS;
902 pstrcpy(devname, sizeof(devname), "scsi");
903 } else {
904 type = IF_IDE;
905 max_devs = MAX_IDE_DEVS;
906 pstrcpy(devname, sizeof(devname), "ide");
907 }
908 media = MEDIA_DISK;
909
910 /* extract parameters */
911
912 if (get_param_value(buf, sizeof(buf), "bus", str)) {
913 bus_id = strtol(buf, NULL, 0);
914 if (bus_id < 0) {
915 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
916 return -1;
917 }
918 }
919
920 if (get_param_value(buf, sizeof(buf), "unit", str)) {
921 unit_id = strtol(buf, NULL, 0);
922 if (unit_id < 0) {
923 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
924 return -1;
925 }
926 }
927
928 if (get_param_value(buf, sizeof(buf), "if", str)) {
929 pstrcpy(devname, sizeof(devname), buf);
930 if (!strcmp(buf, "ide")) {
931 type = IF_IDE;
932 max_devs = MAX_IDE_DEVS;
933 } else if (!strcmp(buf, "scsi")) {
934 type = IF_SCSI;
935 max_devs = MAX_SCSI_DEVS;
936 } else if (!strcmp(buf, "floppy")) {
937 type = IF_FLOPPY;
938 max_devs = 0;
939 } else if (!strcmp(buf, "pflash")) {
940 type = IF_PFLASH;
941 max_devs = 0;
942 } else if (!strcmp(buf, "mtd")) {
943 type = IF_MTD;
944 max_devs = 0;
945 } else if (!strcmp(buf, "sd")) {
946 type = IF_SD;
947 max_devs = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700948 } else if (!strcmp(buf, "virtio")) {
949 type = IF_VIRTIO;
950 max_devs = 0;
951 } else if (!strcmp(buf, "xen")) {
952 type = IF_XEN;
953 max_devs = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800954 } else {
955 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
956 return -1;
957 }
958 }
959
960 if (get_param_value(buf, sizeof(buf), "index", str)) {
961 index = strtol(buf, NULL, 0);
962 if (index < 0) {
963 fprintf(stderr, "qemu: '%s' invalid index\n", str);
964 return -1;
965 }
966 }
967
968 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
969 cyls = strtol(buf, NULL, 0);
970 }
971
972 if (get_param_value(buf, sizeof(buf), "heads", str)) {
973 heads = strtol(buf, NULL, 0);
974 }
975
976 if (get_param_value(buf, sizeof(buf), "secs", str)) {
977 secs = strtol(buf, NULL, 0);
978 }
979
980 if (cyls || heads || secs) {
981 if (cyls < 1 || cyls > 16383) {
982 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
983 return -1;
984 }
985 if (heads < 1 || heads > 16) {
986 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
987 return -1;
988 }
989 if (secs < 1 || secs > 63) {
990 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
991 return -1;
992 }
993 }
994
995 if (get_param_value(buf, sizeof(buf), "trans", str)) {
996 if (!cyls) {
997 fprintf(stderr,
998 "qemu: '%s' trans must be used with cyls,heads and secs\n",
999 str);
1000 return -1;
1001 }
1002 if (!strcmp(buf, "none"))
1003 translation = BIOS_ATA_TRANSLATION_NONE;
1004 else if (!strcmp(buf, "lba"))
1005 translation = BIOS_ATA_TRANSLATION_LBA;
1006 else if (!strcmp(buf, "auto"))
1007 translation = BIOS_ATA_TRANSLATION_AUTO;
1008 else {
1009 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
1010 return -1;
1011 }
1012 }
1013
1014 if (get_param_value(buf, sizeof(buf), "media", str)) {
1015 if (!strcmp(buf, "disk")) {
1016 media = MEDIA_DISK;
1017 } else if (!strcmp(buf, "cdrom")) {
1018 if (cyls || secs || heads) {
1019 fprintf(stderr,
1020 "qemu: '%s' invalid physical CHS format\n", str);
1021 return -1;
1022 }
1023 media = MEDIA_CDROM;
1024 } else {
1025 fprintf(stderr, "qemu: '%s' invalid media\n", str);
1026 return -1;
1027 }
1028 }
1029
1030 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
1031 if (!strcmp(buf, "on"))
1032 snapshot = 1;
1033 else if (!strcmp(buf, "off"))
1034 snapshot = 0;
1035 else {
1036 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
1037 return -1;
1038 }
1039 }
1040
1041 if (get_param_value(buf, sizeof(buf), "cache", str)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001042 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001043 cache = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001044 else if (!strcmp(buf, "writethrough"))
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001045 cache = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001046 else if (!strcmp(buf, "writeback"))
1047 cache = 2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001048 else {
1049 fprintf(stderr, "qemu: invalid cache option\n");
1050 return -1;
1051 }
1052 }
1053
1054 if (get_param_value(buf, sizeof(buf), "format", str)) {
1055 if (strcmp(buf, "?") == 0) {
1056 fprintf(stderr, "qemu: Supported formats:");
1057 bdrv_iterate_format(bdrv_format_print, NULL);
1058 fprintf(stderr, "\n");
1059 return -1;
1060 }
1061 drv = bdrv_find_format(buf);
1062 if (!drv) {
1063 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
1064 return -1;
1065 }
1066 }
1067
1068 if (arg->file == NULL)
1069 get_param_value(file, sizeof(file), "file", str);
1070 else
1071 pstrcpy(file, sizeof(file), arg->file);
1072
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001073 if (!get_param_value(serial, sizeof(serial), "serial", str))
1074 memset(serial, 0, sizeof(serial));
1075
1076 onerror = BLOCK_ERR_STOP_ENOSPC;
1077 if (get_param_value(buf, sizeof(serial), "werror", str)) {
1078 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
1079 fprintf(stderr, "werror is no supported by this format\n");
1080 return -1;
1081 }
1082 if (!strcmp(buf, "ignore"))
1083 onerror = BLOCK_ERR_IGNORE;
1084 else if (!strcmp(buf, "enospc"))
1085 onerror = BLOCK_ERR_STOP_ENOSPC;
1086 else if (!strcmp(buf, "stop"))
1087 onerror = BLOCK_ERR_STOP_ANY;
1088 else if (!strcmp(buf, "report"))
1089 onerror = BLOCK_ERR_REPORT;
1090 else {
1091 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
1092 return -1;
1093 }
1094 }
1095
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001096 /* compute bus and unit according index */
1097
1098 if (index != -1) {
1099 if (bus_id != 0 || unit_id != -1) {
1100 fprintf(stderr,
1101 "qemu: '%s' index cannot be used with bus and unit\n", str);
1102 return -1;
1103 }
1104 if (max_devs == 0)
1105 {
1106 unit_id = index;
1107 bus_id = 0;
1108 } else {
1109 unit_id = index % max_devs;
1110 bus_id = index / max_devs;
1111 }
1112 }
1113
1114 /* if user doesn't specify a unit_id,
1115 * try to find the first free
1116 */
1117
1118 if (unit_id == -1) {
1119 unit_id = 0;
1120 while (drive_get_index(type, bus_id, unit_id) != -1) {
1121 unit_id++;
1122 if (max_devs && unit_id >= max_devs) {
1123 unit_id -= max_devs;
1124 bus_id++;
1125 }
1126 }
1127 }
1128
1129 /* check unit id */
1130
1131 if (max_devs && unit_id >= max_devs) {
1132 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
1133 str, unit_id, max_devs - 1);
1134 return -1;
1135 }
1136
1137 /*
1138 * ignore multiple definitions
1139 */
1140
1141 if (drive_get_index(type, bus_id, unit_id) != -1)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001142 return -2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001143
1144 /* init */
1145
1146 if (type == IF_IDE || type == IF_SCSI)
1147 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
1148 if (max_devs)
1149 snprintf(buf, sizeof(buf), "%s%i%s%i",
1150 devname, bus_id, mediastr, unit_id);
1151 else
1152 snprintf(buf, sizeof(buf), "%s%s%i",
1153 devname, mediastr, unit_id);
1154 bdrv = bdrv_new(buf);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001155 drives_table_idx = drive_get_free_idx();
1156 drives_table[drives_table_idx].bdrv = bdrv;
1157 drives_table[drives_table_idx].type = type;
1158 drives_table[drives_table_idx].bus = bus_id;
1159 drives_table[drives_table_idx].unit = unit_id;
1160 drives_table[drives_table_idx].onerror = onerror;
1161 drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
1162 strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001163 nb_drives++;
1164
1165 switch(type) {
1166 case IF_IDE:
1167 case IF_SCSI:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001168 case IF_XEN:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001169 switch(media) {
1170 case MEDIA_DISK:
1171 if (cyls != 0) {
1172 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
1173 bdrv_set_translation_hint(bdrv, translation);
1174 }
1175 break;
1176 case MEDIA_CDROM:
1177 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
1178 break;
1179 }
1180 break;
1181 case IF_SD:
1182 /* FIXME: This isn't really a floppy, but it's a reasonable
1183 approximation. */
1184 case IF_FLOPPY:
1185 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
1186 break;
1187 case IF_PFLASH:
1188 case IF_MTD:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001189 case IF_VIRTIO:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001190 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001191 case IF_COUNT:
1192 abort();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001193 }
1194 if (!file[0])
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001195 return -2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001196 bdrv_flags = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001197 if (snapshot) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001198 bdrv_flags |= BDRV_O_SNAPSHOT;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001199 cache = 2; /* always use write-back with snapshot */
1200 }
1201 if (cache == 0) /* no caching */
1202 bdrv_flags |= BDRV_O_NOCACHE;
1203 else if (cache == 2) /* write-back */
1204 bdrv_flags |= BDRV_O_CACHE_WB;
1205 else if (cache == 3) /* not specified */
1206 bdrv_flags |= BDRV_O_CACHE_DEF;
1207 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001208 fprintf(stderr, "qemu: could not open disk image %s\n",
1209 file);
1210 return -1;
1211 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001212 if (bdrv_key_required(bdrv))
1213 autostart = 0;
1214 return drives_table_idx;
1215}
1216
1217static void numa_add(const char *optarg)
1218{
1219 char option[128];
1220 char *endptr;
1221 unsigned long long value, endvalue;
1222 int nodenr;
1223
1224 optarg = get_opt_name(option, 128, optarg, ',') + 1;
1225 if (!strcmp(option, "node")) {
1226 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
1227 nodenr = nb_numa_nodes;
1228 } else {
1229 nodenr = strtoull(option, NULL, 10);
1230 }
1231
1232 if (get_param_value(option, 128, "mem", optarg) == 0) {
1233 node_mem[nodenr] = 0;
1234 } else {
1235 value = strtoull(option, &endptr, 0);
1236 switch (*endptr) {
1237 case 0: case 'M': case 'm':
1238 value <<= 20;
1239 break;
1240 case 'G': case 'g':
1241 value <<= 30;
1242 break;
1243 }
1244 node_mem[nodenr] = value;
1245 }
1246 if (get_param_value(option, 128, "cpus", optarg) == 0) {
1247 node_cpumask[nodenr] = 0;
1248 } else {
1249 value = strtoull(option, &endptr, 10);
1250 if (value >= 64) {
1251 value = 63;
1252 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
1253 } else {
1254 if (*endptr == '-') {
1255 endvalue = strtoull(endptr+1, &endptr, 10);
1256 if (endvalue >= 63) {
1257 endvalue = 62;
1258 fprintf(stderr,
1259 "only 63 CPUs in NUMA mode supported.\n");
1260 }
1261 value = (1 << (endvalue + 1)) - (1 << value);
1262 } else {
1263 value = 1 << value;
1264 }
1265 }
1266 node_cpumask[nodenr] = value;
1267 }
1268 nb_numa_nodes++;
1269 }
1270 return;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001271}
1272
1273/***********************************************************/
1274/* USB devices */
1275
1276static USBPort *used_usb_ports;
1277static USBPort *free_usb_ports;
1278
1279/* ??? Maybe change this to register a hub to keep track of the topology. */
1280void qemu_register_usb_port(USBPort *port, void *opaque, int index,
1281 usb_attachfn attach)
1282{
1283 port->opaque = opaque;
1284 port->index = index;
1285 port->attach = attach;
1286 port->next = free_usb_ports;
1287 free_usb_ports = port;
1288}
1289
1290int usb_device_add_dev(USBDevice *dev)
1291{
1292 USBPort *port;
1293
1294 /* Find a USB port to add the device to. */
1295 port = free_usb_ports;
1296 if (!port->next) {
1297 USBDevice *hub;
1298
1299 /* Create a new hub and chain it on. */
1300 free_usb_ports = NULL;
1301 port->next = used_usb_ports;
1302 used_usb_ports = port;
1303
1304 hub = usb_hub_init(VM_USB_HUB_SIZE);
1305 usb_attach(port, hub);
1306 port = free_usb_ports;
1307 }
1308
1309 free_usb_ports = port->next;
1310 port->next = used_usb_ports;
1311 used_usb_ports = port;
1312 usb_attach(port, dev);
1313 return 0;
1314}
1315
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001316static void usb_msd_password_cb(void *opaque, int err)
1317{
1318 USBDevice *dev = opaque;
1319
1320 if (!err)
1321 usb_device_add_dev(dev);
1322 else
1323 dev->handle_destroy(dev);
1324}
1325
1326static int usb_device_add(const char *devname, int is_hotplug)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001327{
1328 const char *p;
1329 USBDevice *dev;
1330
1331 if (!free_usb_ports)
1332 return -1;
1333
1334 if (strstart(devname, "host:", &p)) {
1335 dev = usb_host_device_open(p);
1336 } else if (!strcmp(devname, "mouse")) {
1337 dev = usb_mouse_init();
1338 } else if (!strcmp(devname, "tablet")) {
1339 dev = usb_tablet_init();
1340 } else if (!strcmp(devname, "keyboard")) {
1341 dev = usb_keyboard_init();
1342 } else if (strstart(devname, "disk:", &p)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001343 BlockDriverState *bs;
1344
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001345 dev = usb_msd_init(p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001346 if (!dev)
1347 return -1;
1348 bs = usb_msd_get_bdrv(dev);
1349 if (bdrv_key_required(bs)) {
1350 autostart = 0;
1351 if (is_hotplug) {
1352 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
1353 dev);
1354 return 0;
1355 }
1356 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001357 } else if (!strcmp(devname, "wacom-tablet")) {
1358 dev = usb_wacom_init();
1359 } else if (strstart(devname, "serial:", &p)) {
1360 dev = usb_serial_init(p);
1361#ifdef CONFIG_BRLAPI
1362 } else if (!strcmp(devname, "braille")) {
1363 dev = usb_baum_init();
1364#endif
1365 } else if (strstart(devname, "net:", &p)) {
1366 int nic = nb_nics;
1367
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001368 if (net_client_init(NULL, "nic", p) < 0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001369 return -1;
1370 nd_table[nic].model = "usb";
1371 dev = usb_net_init(&nd_table[nic]);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001372 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
1373 dev = usb_bt_init(devname[2] ? hci_init(p) :
1374 bt_new_hci(qemu_find_bt_vlan(0)));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001375 } else {
1376 return -1;
1377 }
1378 if (!dev)
1379 return -1;
1380
1381 return usb_device_add_dev(dev);
1382}
1383
1384int usb_device_del_addr(int bus_num, int addr)
1385{
1386 USBPort *port;
1387 USBPort **lastp;
1388 USBDevice *dev;
1389
1390 if (!used_usb_ports)
1391 return -1;
1392
1393 if (bus_num != 0)
1394 return -1;
1395
1396 lastp = &used_usb_ports;
1397 port = used_usb_ports;
1398 while (port && port->dev->addr != addr) {
1399 lastp = &port->next;
1400 port = port->next;
1401 }
1402
1403 if (!port)
1404 return -1;
1405
1406 dev = port->dev;
1407 *lastp = port->next;
1408 usb_attach(port, NULL);
1409 dev->handle_destroy(dev);
1410 port->next = free_usb_ports;
1411 free_usb_ports = port;
1412 return 0;
1413}
1414
1415static int usb_device_del(const char *devname)
1416{
1417 int bus_num, addr;
1418 const char *p;
1419
1420 if (strstart(devname, "host:", &p))
1421 return usb_host_device_close(p);
1422
1423 if (!used_usb_ports)
1424 return -1;
1425
1426 p = strchr(devname, '.');
1427 if (!p)
1428 return -1;
1429 bus_num = strtoul(devname, NULL, 0);
1430 addr = strtoul(p + 1, NULL, 0);
1431
1432 return usb_device_del_addr(bus_num, addr);
1433}
1434
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001435void do_usb_add(Monitor *mon, const char *devname)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001436{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001437 usb_device_add(devname, 1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001438}
1439
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001440void do_usb_del(Monitor *mon, const char *devname)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001441{
1442 usb_device_del(devname);
1443}
1444
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001445void usb_info(Monitor *mon)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001446{
1447 USBDevice *dev;
1448 USBPort *port;
1449 const char *speed_str;
1450
1451 if (!usb_enabled) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001452 monitor_printf(mon, "USB support not enabled\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001453 return;
1454 }
1455
1456 for (port = used_usb_ports; port; port = port->next) {
1457 dev = port->dev;
1458 if (!dev)
1459 continue;
1460 switch(dev->speed) {
1461 case USB_SPEED_LOW:
1462 speed_str = "1.5";
1463 break;
1464 case USB_SPEED_FULL:
1465 speed_str = "12";
1466 break;
1467 case USB_SPEED_HIGH:
1468 speed_str = "480";
1469 break;
1470 default:
1471 speed_str = "?";
1472 break;
1473 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001474 monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
1475 0, dev->addr, speed_str, dev->devname);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001476 }
1477}
1478
1479/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001480/* PCMCIA/Cardbus */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001481
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001482static struct pcmcia_socket_entry_s {
1483 PCMCIASocket *socket;
1484 struct pcmcia_socket_entry_s *next;
1485} *pcmcia_sockets = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001486
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001487void pcmcia_socket_register(PCMCIASocket *socket)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001488{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001489 struct pcmcia_socket_entry_s *entry;
1490
1491 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
1492 entry->socket = socket;
1493 entry->next = pcmcia_sockets;
1494 pcmcia_sockets = entry;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001495}
1496
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001497void pcmcia_socket_unregister(PCMCIASocket *socket)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001498{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001499 struct pcmcia_socket_entry_s *entry, **ptr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001500
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001501 ptr = &pcmcia_sockets;
1502 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
1503 if (entry->socket == socket) {
1504 *ptr = entry->next;
1505 qemu_free(entry);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001506 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001507}
1508
1509void pcmcia_info(Monitor *mon)
1510{
1511 struct pcmcia_socket_entry_s *iter;
1512
1513 if (!pcmcia_sockets)
1514 monitor_printf(mon, "No PCMCIA sockets\n");
1515
1516 for (iter = pcmcia_sockets; iter; iter = iter->next)
1517 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
1518 iter->socket->attached ? iter->socket->card_string :
1519 "Empty");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001520}
1521
1522/***********************************************************/
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001523/* ram save/restore */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001524
1525static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
1526{
1527 int v;
1528
1529 v = qemu_get_byte(f);
1530 switch(v) {
1531 case 0:
1532 if (qemu_get_buffer(f, buf, len) != len)
1533 return -EIO;
1534 break;
1535 case 1:
1536 v = qemu_get_byte(f);
1537 memset(buf, v, len);
1538 break;
1539 default:
1540 return -EINVAL;
1541 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001542
1543 if (qemu_file_has_error(f))
1544 return -EIO;
1545
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001546 return 0;
1547}
1548
1549static int ram_load_v1(QEMUFile *f, void *opaque)
1550{
1551 int ret;
1552 ram_addr_t i;
1553
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001554 if (qemu_get_be32(f) != last_ram_offset)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001555 return -EINVAL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001556 for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
1557 ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001558 if (ret)
1559 return ret;
1560 }
1561 return 0;
1562}
1563
1564#define BDRV_HASH_BLOCK_SIZE 1024
1565#define IOBUF_SIZE 4096
1566#define RAM_CBLOCK_MAGIC 0xfabe
1567
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001568typedef struct RamDecompressState {
1569 z_stream zstream;
1570 QEMUFile *f;
1571 uint8_t buf[IOBUF_SIZE];
1572} RamDecompressState;
1573
1574static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
1575{
1576 int ret;
1577 memset(s, 0, sizeof(*s));
1578 s->f = f;
1579 ret = inflateInit(&s->zstream);
1580 if (ret != Z_OK)
1581 return -1;
1582 return 0;
1583}
1584
1585static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
1586{
1587 int ret, clen;
1588
1589 s->zstream.avail_out = len;
1590 s->zstream.next_out = buf;
1591 while (s->zstream.avail_out > 0) {
1592 if (s->zstream.avail_in == 0) {
1593 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
1594 return -1;
1595 clen = qemu_get_be16(s->f);
1596 if (clen > IOBUF_SIZE)
1597 return -1;
1598 qemu_get_buffer(s->f, s->buf, clen);
1599 s->zstream.avail_in = clen;
1600 s->zstream.next_in = s->buf;
1601 }
1602 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
1603 if (ret != Z_OK && ret != Z_STREAM_END) {
1604 return -1;
1605 }
1606 }
1607 return 0;
1608}
1609
1610static void ram_decompress_close(RamDecompressState *s)
1611{
1612 inflateEnd(&s->zstream);
1613}
1614
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001615#define RAM_SAVE_FLAG_FULL 0x01
1616#define RAM_SAVE_FLAG_COMPRESS 0x02
1617#define RAM_SAVE_FLAG_MEM_SIZE 0x04
1618#define RAM_SAVE_FLAG_PAGE 0x08
1619#define RAM_SAVE_FLAG_EOS 0x10
1620
1621static int is_dup_page(uint8_t *page, uint8_t ch)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001622{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001623 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
1624 uint32_t *array = (uint32_t *)page;
1625 int i;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001626
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001627 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
1628 if (array[i] != val)
1629 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001630 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001631
1632 return 1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001633}
1634
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001635static int ram_save_block(QEMUFile *f)
1636{
1637 static ram_addr_t current_addr = 0;
1638 ram_addr_t saved_addr = current_addr;
1639 ram_addr_t addr = 0;
1640 int found = 0;
1641
1642 while (addr < last_ram_offset) {
1643 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
1644 uint8_t *p;
1645
1646 cpu_physical_memory_reset_dirty(current_addr,
1647 current_addr + TARGET_PAGE_SIZE,
1648 MIGRATION_DIRTY_FLAG);
1649
1650 p = qemu_get_ram_ptr(current_addr);
1651
1652 if (is_dup_page(p, *p)) {
1653 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
1654 qemu_put_byte(f, *p);
1655 } else {
1656 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
1657 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
1658 }
1659
1660 found = 1;
1661 break;
1662 }
1663 addr += TARGET_PAGE_SIZE;
1664 current_addr = (saved_addr + addr) % last_ram_offset;
1665 }
1666
1667 return found;
1668}
1669
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02001670static uint64_t bytes_transferred = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001671
1672static ram_addr_t ram_save_remaining(void)
1673{
1674 ram_addr_t addr;
1675 ram_addr_t count = 0;
1676
1677 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
1678 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
1679 count++;
1680 }
1681
1682 return count;
1683}
1684
1685uint64_t ram_bytes_remaining(void)
1686{
1687 return ram_save_remaining() * TARGET_PAGE_SIZE;
1688}
1689
1690uint64_t ram_bytes_transferred(void)
1691{
1692 return bytes_transferred;
1693}
1694
1695uint64_t ram_bytes_total(void)
1696{
1697 return last_ram_offset;
1698}
1699
1700static int ram_save_live(QEMUFile *f, int stage, void *opaque)
1701{
1702 ram_addr_t addr;
1703 uint64_t bytes_transferred_last;
1704 double bwidth = 0;
1705 uint64_t expected_time = 0;
1706
1707 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
1708 qemu_file_set_error(f);
1709 return 0;
1710 }
1711
1712 if (stage == 1) {
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07001713 bytes_transferred = 0;
1714
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001715 /* Make sure all dirty bits are set */
1716 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
1717 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
1718 cpu_physical_memory_set_dirty(addr);
1719 }
1720
1721 /* Enable dirty memory tracking */
1722 cpu_physical_memory_set_dirty_tracking(1);
1723
1724 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
1725 }
1726
1727 bytes_transferred_last = bytes_transferred;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07001728 bwidth = qemu_get_clock_ns(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001729
1730 while (!qemu_file_rate_limit(f)) {
1731 int ret;
1732
1733 ret = ram_save_block(f);
1734 bytes_transferred += ret * TARGET_PAGE_SIZE;
1735 if (ret == 0) /* no more blocks */
1736 break;
1737 }
1738
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07001739 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001740 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
1741
1742 /* if we haven't transferred anything this round, force expected_time to a
1743 * a very high value, but without crashing */
1744 if (bwidth == 0)
1745 bwidth = 0.000001;
1746
1747 /* try transferring iterative blocks of memory */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001748 if (stage == 3) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001749 /* flush all remaining blocks regardless of rate limiting */
1750 while (ram_save_block(f) != 0) {
1751 bytes_transferred += TARGET_PAGE_SIZE;
1752 }
1753 cpu_physical_memory_set_dirty_tracking(0);
1754 }
1755
1756 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
1757
1758 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
1759
1760 return (stage == 2) && (expected_time <= migrate_max_downtime());
1761}
1762
1763static int ram_load_dead(QEMUFile *f, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001764{
1765 RamDecompressState s1, *s = &s1;
1766 uint8_t buf[10];
1767 ram_addr_t i;
1768
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001769 if (ram_decompress_open(s, f) < 0)
1770 return -EINVAL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001771 for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001772 if (ram_decompress_buf(s, buf, 1) < 0) {
1773 fprintf(stderr, "Error while reading ram block header\n");
1774 goto error;
1775 }
1776 if (buf[0] == 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001777 if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
1778 BDRV_HASH_BLOCK_SIZE) < 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001779 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
1780 goto error;
1781 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001782 } else {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001783 error:
1784 printf("Error block header\n");
1785 return -EINVAL;
1786 }
1787 }
1788 ram_decompress_close(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001789
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001790 return 0;
1791}
1792
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001793static int ram_load(QEMUFile *f, void *opaque, int version_id)
1794{
1795 ram_addr_t addr;
1796 int flags;
1797
1798 if (version_id == 1)
1799 return ram_load_v1(f, opaque);
1800
1801 if (version_id == 2) {
1802 if (qemu_get_be32(f) != last_ram_offset)
1803 return -EINVAL;
1804 return ram_load_dead(f, opaque);
1805 }
1806
1807 if (version_id != 3)
1808 return -EINVAL;
1809
1810 do {
1811 addr = qemu_get_be64(f);
1812
1813 flags = addr & ~TARGET_PAGE_MASK;
1814 addr &= TARGET_PAGE_MASK;
1815
1816 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
1817 if (addr != last_ram_offset)
1818 return -EINVAL;
1819 }
1820
1821 if (flags & RAM_SAVE_FLAG_FULL) {
1822 if (ram_load_dead(f, opaque) < 0)
1823 return -EINVAL;
1824 }
David 'Digit' Turner707c8a82010-12-22 22:35:58 +01001825
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001826 if (flags & RAM_SAVE_FLAG_COMPRESS) {
1827 uint8_t ch = qemu_get_byte(f);
1828 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
1829 } else if (flags & RAM_SAVE_FLAG_PAGE)
1830 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
1831 } while (!(flags & RAM_SAVE_FLAG_EOS));
1832
1833 return 0;
1834}
1835
1836void qemu_service_io(void)
1837{
1838 qemu_notify_event();
1839}
1840
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001841/***********************************************************/
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001842/* machine registration */
1843
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001844static QEMUMachine *first_machine = NULL;
1845QEMUMachine *current_machine = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001846
1847int qemu_register_machine(QEMUMachine *m)
1848{
1849 QEMUMachine **pm;
1850 pm = &first_machine;
1851 while (*pm != NULL)
1852 pm = &(*pm)->next;
1853 m->next = NULL;
1854 *pm = m;
1855 return 0;
1856}
1857
1858static QEMUMachine *find_machine(const char *name)
1859{
1860 QEMUMachine *m;
1861
1862 for(m = first_machine; m != NULL; m = m->next) {
1863 if (!strcmp(m->name, name))
1864 return m;
1865 }
1866 return NULL;
1867}
1868
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001869static QEMUMachine *find_default_machine(void)
1870{
1871 QEMUMachine *m;
1872
1873 for(m = first_machine; m != NULL; m = m->next) {
1874 if (m->is_default) {
1875 return m;
1876 }
1877 }
1878 return NULL;
1879}
1880
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001881/***********************************************************/
1882/* main execution loop */
1883
1884static void gui_update(void *opaque)
1885{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001886 uint64_t interval = GUI_REFRESH_INTERVAL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001887 DisplayState *ds = opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001888 DisplayChangeListener *dcl = ds->listeners;
1889
1890 dpy_refresh(ds);
1891
1892 while (dcl != NULL) {
1893 if (dcl->gui_timer_interval &&
1894 dcl->gui_timer_interval < interval)
1895 interval = dcl->gui_timer_interval;
1896 dcl = dcl->next;
1897 }
David 'Digit' Turner5973c772011-05-10 07:06:00 +02001898 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001899}
1900
1901static void nographic_update(void *opaque)
1902{
1903 uint64_t interval = GUI_REFRESH_INTERVAL;
1904
David 'Digit' Turner5973c772011-05-10 07:06:00 +02001905 qemu_mod_timer(nographic_timer, interval + qemu_get_clock_ms(rt_clock));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001906}
1907
1908struct vm_change_state_entry {
1909 VMChangeStateHandler *cb;
1910 void *opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07001911 QLIST_ENTRY (vm_change_state_entry) entries;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001912};
1913
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07001914static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001915
1916VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
1917 void *opaque)
1918{
1919 VMChangeStateEntry *e;
1920
1921 e = qemu_mallocz(sizeof (*e));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001922
1923 e->cb = cb;
1924 e->opaque = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07001925 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001926 return e;
1927}
1928
1929void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
1930{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07001931 QLIST_REMOVE (e, entries);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001932 qemu_free (e);
1933}
1934
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001935static void vm_state_notify(int running, int reason)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001936{
1937 VMChangeStateEntry *e;
1938
1939 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001940 e->cb(e->opaque, running, reason);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001941 }
1942}
1943
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001944static void resume_all_vcpus(void);
1945static void pause_all_vcpus(void);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001946
1947void vm_start(void)
1948{
1949 if (!vm_running) {
1950 cpu_enable_ticks();
1951 vm_running = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001952 vm_state_notify(1, 0);
David Turner6a9ef172010-09-09 22:54:36 +02001953 //qemu_rearm_alarm_timer(alarm_timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001954 resume_all_vcpus();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001955 }
1956}
1957
1958/* reset/shutdown handler */
1959
1960typedef struct QEMUResetEntry {
David Turner025c32f2010-09-10 14:52:42 +02001961 QTAILQ_ENTRY(QEMUResetEntry) entry;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001962 QEMUResetHandler *func;
1963 void *opaque;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001964} QEMUResetEntry;
1965
David Turner025c32f2010-09-10 14:52:42 +02001966static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
1967 QTAILQ_HEAD_INITIALIZER(reset_handlers);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001968static int reset_requested;
David 'Digit' Turner088edf82011-05-09 15:59:28 +02001969static int shutdown_requested, shutdown_signal = -1;
1970static pid_t shutdown_pid;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001971static int powerdown_requested;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001972static int debug_requested;
1973static int vmstop_requested;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001974
1975int qemu_shutdown_requested(void)
1976{
1977 int r = shutdown_requested;
1978 shutdown_requested = 0;
1979 return r;
1980}
1981
1982int qemu_reset_requested(void)
1983{
1984 int r = reset_requested;
1985 reset_requested = 0;
1986 return r;
1987}
1988
1989int qemu_powerdown_requested(void)
1990{
1991 int r = powerdown_requested;
1992 powerdown_requested = 0;
1993 return r;
1994}
1995
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001996static int qemu_debug_requested(void)
1997{
1998 int r = debug_requested;
1999 debug_requested = 0;
2000 return r;
2001}
2002
2003static int qemu_vmstop_requested(void)
2004{
2005 int r = vmstop_requested;
2006 vmstop_requested = 0;
2007 return r;
2008}
2009
David Turner025c32f2010-09-10 14:52:42 +02002010void qemu_register_reset(QEMUResetHandler *func, void *opaque)
2011{
2012 QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
2013
2014 re->func = func;
2015 re->opaque = opaque;
2016 QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
2017}
2018
2019void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
2020{
2021 QEMUResetEntry *re;
2022
2023 QTAILQ_FOREACH(re, &reset_handlers, entry) {
2024 if (re->func == func && re->opaque == opaque) {
2025 QTAILQ_REMOVE(&reset_handlers, re, entry);
2026 qemu_free(re);
2027 return;
2028 }
2029 }
2030}
2031
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002032static void do_vm_stop(int reason)
2033{
2034 if (vm_running) {
2035 cpu_disable_ticks();
2036 vm_running = 0;
2037 pause_all_vcpus();
2038 vm_state_notify(0, reason);
2039 }
2040}
2041
2042void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002043{
2044 QEMUResetEntry **pre, *re;
2045
2046 pre = &first_reset_entry;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002047 while (*pre != NULL && (*pre)->order >= order) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002048 pre = &(*pre)->next;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002049 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002050 re = qemu_mallocz(sizeof(QEMUResetEntry));
2051 re->func = func;
2052 re->opaque = opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002053 re->order = order;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002054 re->next = NULL;
2055 *pre = re;
2056}
2057
2058void qemu_system_reset(void)
2059{
2060 QEMUResetEntry *re;
2061
2062 /* reset all devices */
David Turner025c32f2010-09-10 14:52:42 +02002063 QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002064 re->func(re->opaque);
2065 }
2066}
2067
2068void qemu_system_reset_request(void)
2069{
2070 if (no_reboot) {
2071 shutdown_requested = 1;
2072 } else {
2073 reset_requested = 1;
2074 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002075 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002076}
2077
David 'Digit' Turner088edf82011-05-09 15:59:28 +02002078void qemu_system_killed(int signal, pid_t pid)
2079{
2080 shutdown_signal = signal;
2081 shutdown_pid = pid;
2082 qemu_system_shutdown_request();
2083}
2084
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002085void qemu_system_shutdown_request(void)
2086{
2087 shutdown_requested = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002088 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002089}
2090
2091void qemu_system_powerdown_request(void)
2092{
2093 powerdown_requested = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002094 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002095}
2096
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002097#ifdef CONFIG_IOTHREAD
2098static void qemu_system_vmstop_request(int reason)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002099{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002100 vmstop_requested = reason;
2101 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002102}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002103#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002104
2105#ifndef _WIN32
2106static int io_thread_fd = -1;
2107
2108static void qemu_event_increment(void)
2109{
2110 static const char byte = 0;
2111
2112 if (io_thread_fd == -1)
2113 return;
2114
2115 write(io_thread_fd, &byte, sizeof(byte));
2116}
2117
2118static void qemu_event_read(void *opaque)
2119{
2120 int fd = (unsigned long)opaque;
2121 ssize_t len;
2122
2123 /* Drain the notify pipe */
2124 do {
2125 char buffer[512];
2126 len = read(fd, buffer, sizeof(buffer));
2127 } while ((len == -1 && errno == EINTR) || len > 0);
2128}
2129
2130static int qemu_event_init(void)
2131{
2132 int err;
2133 int fds[2];
2134
2135 err = pipe(fds);
2136 if (err == -1)
2137 return -errno;
2138
2139 err = fcntl_setfl(fds[0], O_NONBLOCK);
2140 if (err < 0)
2141 goto fail;
2142
2143 err = fcntl_setfl(fds[1], O_NONBLOCK);
2144 if (err < 0)
2145 goto fail;
2146
2147 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
2148 (void *)(unsigned long)fds[0]);
2149
2150 io_thread_fd = fds[1];
2151 return 0;
2152
2153fail:
2154 close(fds[0]);
2155 close(fds[1]);
2156 return err;
2157}
2158#else
2159HANDLE qemu_event_handle;
2160
2161static void dummy_event_handler(void *opaque)
2162{
2163}
2164
2165static int qemu_event_init(void)
2166{
2167 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
2168 if (!qemu_event_handle) {
2169 perror("Failed CreateEvent");
2170 return -1;
2171 }
2172 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
2173 return 0;
2174}
2175
2176static void qemu_event_increment(void)
2177{
2178 SetEvent(qemu_event_handle);
2179}
2180#endif
2181
2182static int cpu_can_run(CPUState *env)
2183{
2184 if (env->stop)
2185 return 0;
2186 if (env->stopped)
2187 return 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002188 if (!vm_running)
2189 return 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002190 return 1;
2191}
2192
2193#ifndef CONFIG_IOTHREAD
2194static int qemu_init_main_loop(void)
2195{
2196 return qemu_event_init();
2197}
2198
2199void qemu_init_vcpu(void *_env)
2200{
2201 CPUState *env = _env;
2202
2203 if (kvm_enabled())
2204 kvm_init_vcpu(env);
2205 return;
2206}
2207
2208int qemu_cpu_self(void *env)
2209{
2210 return 1;
2211}
2212
2213static void resume_all_vcpus(void)
2214{
2215}
2216
2217static void pause_all_vcpus(void)
2218{
2219}
2220
2221void qemu_cpu_kick(void *env)
2222{
2223 return;
2224}
2225
2226void qemu_notify_event(void)
2227{
2228 CPUState *env = cpu_single_env;
2229
2230 if (env) {
2231 cpu_exit(env);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002232 }
2233}
2234
2235#define qemu_mutex_lock_iothread() do { } while (0)
2236#define qemu_mutex_unlock_iothread() do { } while (0)
2237
2238void vm_stop(int reason)
2239{
2240 do_vm_stop(reason);
2241}
2242
2243#else /* CONFIG_IOTHREAD */
2244
2245#include "qemu-thread.h"
2246
2247QemuMutex qemu_global_mutex;
2248static QemuMutex qemu_fair_mutex;
2249
2250static QemuThread io_thread;
2251
2252static QemuThread *tcg_cpu_thread;
2253static QemuCond *tcg_halt_cond;
2254
2255static int qemu_system_ready;
2256/* cpu creation */
2257static QemuCond qemu_cpu_cond;
2258/* system init */
2259static QemuCond qemu_system_cond;
2260static QemuCond qemu_pause_cond;
2261
2262static void block_io_signals(void);
2263static void unblock_io_signals(void);
2264static int tcg_has_work(void);
2265
2266static int qemu_init_main_loop(void)
2267{
2268 int ret;
2269
2270 ret = qemu_event_init();
2271 if (ret)
2272 return ret;
2273
2274 qemu_cond_init(&qemu_pause_cond);
2275 qemu_mutex_init(&qemu_fair_mutex);
2276 qemu_mutex_init(&qemu_global_mutex);
2277 qemu_mutex_lock(&qemu_global_mutex);
2278
2279 unblock_io_signals();
2280 qemu_thread_self(&io_thread);
2281
2282 return 0;
2283}
2284
2285static void qemu_wait_io_event(CPUState *env)
2286{
2287 while (!tcg_has_work())
2288 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
2289
2290 qemu_mutex_unlock(&qemu_global_mutex);
2291
2292 /*
2293 * Users of qemu_global_mutex can be starved, having no chance
2294 * to acquire it since this path will get to it first.
2295 * So use another lock to provide fairness.
2296 */
2297 qemu_mutex_lock(&qemu_fair_mutex);
2298 qemu_mutex_unlock(&qemu_fair_mutex);
2299
2300 qemu_mutex_lock(&qemu_global_mutex);
2301 if (env->stop) {
2302 env->stop = 0;
2303 env->stopped = 1;
2304 qemu_cond_signal(&qemu_pause_cond);
2305 }
2306}
2307
2308static int qemu_cpu_exec(CPUState *env);
2309
2310static void *kvm_cpu_thread_fn(void *arg)
2311{
2312 CPUState *env = arg;
2313
2314 block_io_signals();
2315 qemu_thread_self(env->thread);
2316
2317 /* signal CPU creation */
2318 qemu_mutex_lock(&qemu_global_mutex);
2319 env->created = 1;
2320 qemu_cond_signal(&qemu_cpu_cond);
2321
2322 /* and wait for machine initialization */
2323 while (!qemu_system_ready)
2324 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2325
2326 while (1) {
2327 if (cpu_can_run(env))
2328 qemu_cpu_exec(env);
2329 qemu_wait_io_event(env);
2330 }
2331
2332 return NULL;
2333}
2334
2335static void tcg_cpu_exec(void);
2336
2337static void *tcg_cpu_thread_fn(void *arg)
2338{
2339 CPUState *env = arg;
2340
2341 block_io_signals();
2342 qemu_thread_self(env->thread);
2343
2344 /* signal CPU creation */
2345 qemu_mutex_lock(&qemu_global_mutex);
2346 for (env = first_cpu; env != NULL; env = env->next_cpu)
2347 env->created = 1;
2348 qemu_cond_signal(&qemu_cpu_cond);
2349
2350 /* and wait for machine initialization */
2351 while (!qemu_system_ready)
2352 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2353
2354 while (1) {
2355 tcg_cpu_exec();
2356 qemu_wait_io_event(cur_cpu);
2357 }
2358
2359 return NULL;
2360}
2361
2362void qemu_cpu_kick(void *_env)
2363{
2364 CPUState *env = _env;
2365 qemu_cond_broadcast(env->halt_cond);
2366 if (kvm_enabled())
2367 qemu_thread_signal(env->thread, SIGUSR1);
2368}
2369
2370int qemu_cpu_self(void *env)
2371{
2372 return (cpu_single_env != NULL);
2373}
2374
2375static void cpu_signal(int sig)
2376{
2377 if (cpu_single_env)
2378 cpu_exit(cpu_single_env);
2379}
2380
2381static void block_io_signals(void)
2382{
2383 sigset_t set;
2384 struct sigaction sigact;
2385
2386 sigemptyset(&set);
2387 sigaddset(&set, SIGUSR2);
2388 sigaddset(&set, SIGIO);
2389 sigaddset(&set, SIGALRM);
2390 pthread_sigmask(SIG_BLOCK, &set, NULL);
2391
2392 sigemptyset(&set);
2393 sigaddset(&set, SIGUSR1);
2394 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2395
2396 memset(&sigact, 0, sizeof(sigact));
2397 sigact.sa_handler = cpu_signal;
2398 sigaction(SIGUSR1, &sigact, NULL);
2399}
2400
2401static void unblock_io_signals(void)
2402{
2403 sigset_t set;
2404
2405 sigemptyset(&set);
2406 sigaddset(&set, SIGUSR2);
2407 sigaddset(&set, SIGIO);
2408 sigaddset(&set, SIGALRM);
2409 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2410
2411 sigemptyset(&set);
2412 sigaddset(&set, SIGUSR1);
2413 pthread_sigmask(SIG_BLOCK, &set, NULL);
2414}
2415
2416static void qemu_signal_lock(unsigned int msecs)
2417{
2418 qemu_mutex_lock(&qemu_fair_mutex);
2419
2420 while (qemu_mutex_trylock(&qemu_global_mutex)) {
2421 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
2422 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
2423 break;
2424 }
2425 qemu_mutex_unlock(&qemu_fair_mutex);
2426}
2427
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002428void qemu_mutex_lock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002429{
2430 if (kvm_enabled()) {
2431 qemu_mutex_lock(&qemu_fair_mutex);
2432 qemu_mutex_lock(&qemu_global_mutex);
2433 qemu_mutex_unlock(&qemu_fair_mutex);
2434 } else
2435 qemu_signal_lock(100);
2436}
2437
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002438void qemu_mutex_unlock_iothread(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002439{
2440 qemu_mutex_unlock(&qemu_global_mutex);
2441}
2442
2443static int all_vcpus_paused(void)
2444{
2445 CPUState *penv = first_cpu;
2446
2447 while (penv) {
2448 if (!penv->stopped)
2449 return 0;
2450 penv = (CPUState *)penv->next_cpu;
2451 }
2452
2453 return 1;
2454}
2455
2456static void pause_all_vcpus(void)
2457{
2458 CPUState *penv = first_cpu;
2459
2460 while (penv) {
2461 penv->stop = 1;
2462 qemu_thread_signal(penv->thread, SIGUSR1);
2463 qemu_cpu_kick(penv);
2464 penv = (CPUState *)penv->next_cpu;
2465 }
2466
2467 while (!all_vcpus_paused()) {
2468 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
2469 penv = first_cpu;
2470 while (penv) {
2471 qemu_thread_signal(penv->thread, SIGUSR1);
2472 penv = (CPUState *)penv->next_cpu;
2473 }
2474 }
2475}
2476
2477static void resume_all_vcpus(void)
2478{
2479 CPUState *penv = first_cpu;
2480
2481 while (penv) {
2482 penv->stop = 0;
2483 penv->stopped = 0;
2484 qemu_thread_signal(penv->thread, SIGUSR1);
2485 qemu_cpu_kick(penv);
2486 penv = (CPUState *)penv->next_cpu;
2487 }
2488}
2489
2490static void tcg_init_vcpu(void *_env)
2491{
2492 CPUState *env = _env;
2493 /* share a single thread for all cpus with TCG */
2494 if (!tcg_cpu_thread) {
2495 env->thread = qemu_mallocz(sizeof(QemuThread));
2496 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
2497 qemu_cond_init(env->halt_cond);
2498 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
2499 while (env->created == 0)
2500 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2501 tcg_cpu_thread = env->thread;
2502 tcg_halt_cond = env->halt_cond;
2503 } else {
2504 env->thread = tcg_cpu_thread;
2505 env->halt_cond = tcg_halt_cond;
2506 }
2507}
2508
2509static void kvm_start_vcpu(CPUState *env)
2510{
2511 kvm_init_vcpu(env);
2512 env->thread = qemu_mallocz(sizeof(QemuThread));
2513 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
2514 qemu_cond_init(env->halt_cond);
2515 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
2516 while (env->created == 0)
2517 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
2518}
2519
2520void qemu_init_vcpu(void *_env)
2521{
2522 CPUState *env = _env;
2523
2524 if (kvm_enabled())
2525 kvm_start_vcpu(env);
2526 else
2527 tcg_init_vcpu(env);
2528}
2529
2530void qemu_notify_event(void)
2531{
2532 qemu_event_increment();
2533}
2534
2535void vm_stop(int reason)
2536{
2537 QemuThread me;
2538 qemu_thread_self(&me);
2539
2540 if (!qemu_thread_equal(&me, &io_thread)) {
2541 qemu_system_vmstop_request(reason);
2542 /*
2543 * FIXME: should not return to device code in case
2544 * vm_stop() has been requested.
2545 */
2546 if (cpu_single_env) {
2547 cpu_exit(cpu_single_env);
2548 cpu_single_env->stop = 1;
2549 }
2550 return;
2551 }
2552 do_vm_stop(reason);
2553}
2554
2555#endif
2556
2557
2558#ifdef _WIN32
2559static void host_main_loop_wait(int *timeout)
2560{
2561 int ret, ret2, i;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002562 PollingEntry *pe;
2563
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002564
2565 /* XXX: need to suppress polling by better using win32 events */
2566 ret = 0;
2567 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
2568 ret |= pe->func(pe->opaque);
2569 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002570 if (ret == 0) {
2571 int err;
2572 WaitObjects *w = &wait_objects;
2573
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002574 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002575 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
2576 if (w->func[ret - WAIT_OBJECT_0])
2577 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
2578
2579 /* Check for additional signaled events */
2580 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
2581
2582 /* Check if event is signaled */
2583 ret2 = WaitForSingleObject(w->events[i], 0);
2584 if(ret2 == WAIT_OBJECT_0) {
2585 if (w->func[i])
2586 w->func[i](w->opaque[i]);
2587 } else if (ret2 == WAIT_TIMEOUT) {
2588 } else {
2589 err = GetLastError();
2590 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
2591 }
2592 }
2593 } else if (ret == WAIT_TIMEOUT) {
2594 } else {
2595 err = GetLastError();
2596 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
2597 }
2598 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002599
2600 *timeout = 0;
2601}
2602#else
2603static void host_main_loop_wait(int *timeout)
2604{
2605}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002606#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002607
2608void main_loop_wait(int timeout)
2609{
2610 IOHandlerRecord *ioh;
2611 fd_set rfds, wfds, xfds;
2612 int ret, nfds;
2613 struct timeval tv;
2614
2615 qemu_bh_update_timeout(&timeout);
2616
2617 host_main_loop_wait(&timeout);
2618
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002619
2620 tv.tv_sec = timeout / 1000;
2621 tv.tv_usec = (timeout % 1000) * 1000;
2622
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002623 /* poll any events */
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002624
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002625 /* XXX: separate device handlers from system ones */
2626 nfds = -1;
2627 FD_ZERO(&rfds);
2628 FD_ZERO(&wfds);
2629 FD_ZERO(&xfds);
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002630 qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002631 if (slirp_is_inited()) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002632 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
2633 }
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002634
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002635 qemu_mutex_unlock_iothread();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002636 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002637 qemu_mutex_lock_iothread();
David 'Digit' Turner8354d2d2011-05-11 00:19:06 +02002638 qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002639 if (slirp_is_inited()) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002640 if (ret < 0) {
2641 FD_ZERO(&rfds);
2642 FD_ZERO(&wfds);
2643 FD_ZERO(&xfds);
2644 }
2645 slirp_select_poll(&rfds, &wfds, &xfds);
2646 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002647
David Turner6a9ef172010-09-09 22:54:36 +02002648 qemu_run_all_timers();
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002649
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002650 /* Check bottom-halves last in case any of the earlier events triggered
2651 them. */
2652 qemu_bh_poll();
2653
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002654}
2655
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002656static int qemu_cpu_exec(CPUState *env)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002657{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002658 int ret;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002659#ifdef CONFIG_PROFILER
2660 int64_t ti;
2661#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002662
2663#ifdef CONFIG_PROFILER
2664 ti = profile_getclock();
2665#endif
2666 if (use_icount) {
2667 int64_t count;
2668 int decr;
2669 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
2670 env->icount_decr.u16.low = 0;
2671 env->icount_extra = 0;
2672 count = qemu_next_deadline();
2673 count = (count + (1 << icount_time_shift) - 1)
2674 >> icount_time_shift;
2675 qemu_icount += count;
2676 decr = (count > 0xffff) ? 0xffff : count;
2677 count -= decr;
2678 env->icount_decr.u16.low = decr;
2679 env->icount_extra = count;
2680 }
2681 ret = cpu_exec(env);
2682#ifdef CONFIG_PROFILER
2683 qemu_time += profile_getclock() - ti;
2684#endif
2685 if (use_icount) {
2686 /* Fold pending instructions back into the
2687 instruction counter, and clear the interrupt flag. */
2688 qemu_icount -= (env->icount_decr.u16.low
2689 + env->icount_extra);
2690 env->icount_decr.u32 = 0;
2691 env->icount_extra = 0;
2692 }
2693 return ret;
2694}
2695
2696static void tcg_cpu_exec(void)
2697{
2698 int ret = 0;
2699
2700 if (next_cpu == NULL)
2701 next_cpu = first_cpu;
2702 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
2703 CPUState *env = cur_cpu = next_cpu;
2704
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002705 if (timer_alarm_pending) {
2706 timer_alarm_pending = 0;
2707 break;
2708 }
2709 if (cpu_can_run(env))
2710 ret = qemu_cpu_exec(env);
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002711 else if (env->stop)
2712 break;
2713
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002714 if (ret == EXCP_DEBUG) {
2715 gdb_set_stop_cpu(env);
2716 debug_requested = 1;
2717 break;
2718 }
2719 }
2720}
2721
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002722#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002723static int cpu_has_work(CPUState *env)
2724{
2725 if (env->stop)
2726 return 1;
2727 if (env->stopped)
2728 return 0;
2729 if (!env->halted)
2730 return 1;
2731 if (qemu_cpu_has_work(env))
2732 return 1;
2733 return 0;
2734}
2735
2736static int tcg_has_work(void)
2737{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002738 CPUState *env;
2739
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002740 for (env = first_cpu; env != NULL; env = env->next_cpu)
2741 if (cpu_has_work(env))
2742 return 1;
2743 return 0;
2744}
David 'Digit' Turnerc34e8dc2010-09-13 02:47:01 -07002745#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002746
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002747static int vm_can_run(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002748{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002749 if (powerdown_requested)
2750 return 0;
2751 if (reset_requested)
2752 return 0;
2753 if (shutdown_requested)
2754 return 0;
2755 if (debug_requested)
2756 return 0;
2757 return 1;
2758}
2759
2760static void main_loop(void)
2761{
2762 int r;
2763
2764#ifdef CONFIG_IOTHREAD
2765 qemu_system_ready = 1;
2766 qemu_cond_broadcast(&qemu_system_cond);
2767#endif
2768
2769 for (;;) {
2770 do {
2771#ifdef CONFIG_PROFILER
2772 int64_t ti;
2773#endif
2774#ifndef CONFIG_IOTHREAD
2775 tcg_cpu_exec();
2776#endif
2777#ifdef CONFIG_PROFILER
2778 ti = profile_getclock();
2779#endif
2780 main_loop_wait(qemu_calculate_timeout());
2781#ifdef CONFIG_PROFILER
2782 dev_time += profile_getclock() - ti;
2783#endif
2784 } while (vm_can_run());
2785
2786 if (qemu_debug_requested())
2787 vm_stop(EXCP_DEBUG);
2788 if (qemu_shutdown_requested()) {
2789 if (no_shutdown) {
2790 vm_stop(0);
2791 no_shutdown = 0;
2792 } else
2793 break;
2794 }
2795 if (qemu_reset_requested()) {
2796 pause_all_vcpus();
2797 qemu_system_reset();
2798 resume_all_vcpus();
2799 }
2800 if (qemu_powerdown_requested())
2801 qemu_system_powerdown();
2802 if ((r = qemu_vmstop_requested()))
2803 vm_stop(r);
2804 }
2805 pause_all_vcpus();
2806}
2807
2808static void version(void)
2809{
2810 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
2811}
2812
2813static void help(int exitcode)
2814{
2815 version();
2816 printf("usage: %s [options] [disk_image]\n"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002817 "\n"
2818 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
2819 "\n"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002820#define DEF(option, opt_arg, opt_enum, opt_help) \
2821 opt_help
2822#define DEFHEADING(text) stringify(text) "\n"
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02002823#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002824#undef DEF
2825#undef DEFHEADING
2826#undef GEN_DOCS
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002827 "\n"
2828 "During emulation, the following keys are useful:\n"
2829 "ctrl-alt-f toggle full screen\n"
2830 "ctrl-alt-n switch to virtual console 'n'\n"
2831 "ctrl-alt toggle mouse and keyboard grab\n"
2832 "\n"
2833 "When using -nographic, press 'ctrl-a h' to get some help.\n"
2834 ,
2835 "qemu",
2836 DEFAULT_RAM_SIZE,
2837#ifndef _WIN32
2838 DEFAULT_NETWORK_SCRIPT,
2839 DEFAULT_NETWORK_DOWN_SCRIPT,
2840#endif
2841 DEFAULT_GDBSTUB_PORT,
2842 "/tmp/qemu.log");
2843 exit(exitcode);
2844}
2845
2846#define HAS_ARG 0x0001
2847
2848enum {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002849#define DEF(option, opt_arg, opt_enum, opt_help) \
2850 opt_enum,
2851#define DEFHEADING(text)
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02002852#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002853#undef DEF
2854#undef DEFHEADING
2855#undef GEN_DOCS
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002856};
2857
2858typedef struct QEMUOption {
2859 const char *name;
2860 int flags;
2861 int index;
2862} QEMUOption;
2863
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002864static const QEMUOption qemu_options[] = {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002865 { "h", 0, QEMU_OPTION_h },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002866#define DEF(option, opt_arg, opt_enum, opt_help) \
2867 { option, opt_arg, opt_enum },
2868#define DEFHEADING(text)
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02002869#include "qemu-options.def"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002870#undef DEF
2871#undef DEFHEADING
2872#undef GEN_DOCS
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02002873 { NULL, 0, 0 },
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002874};
2875
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002876#ifdef HAS_AUDIO
2877struct soundhw soundhw[] = {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002878#ifdef HAS_AUDIO_CHOICE
2879#if defined(TARGET_I386) || defined(TARGET_MIPS)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002880 {
2881 "pcspk",
2882 "PC speaker",
2883 0,
2884 1,
2885 { .init_isa = pcspk_audio_init }
2886 },
2887#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002888
2889#ifdef CONFIG_SB16
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002890 {
2891 "sb16",
2892 "Creative Sound Blaster 16",
2893 0,
2894 1,
2895 { .init_isa = SB16_init }
2896 },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002897#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002898
2899#ifdef CONFIG_CS4231A
2900 {
2901 "cs4231a",
2902 "CS4231A",
2903 0,
2904 1,
2905 { .init_isa = cs4231a_init }
2906 },
2907#endif
2908
2909#ifdef CONFIG_ADLIB
2910 {
2911 "adlib",
2912#ifdef HAS_YMF262
2913 "Yamaha YMF262 (OPL3)",
2914#else
2915 "Yamaha YM3812 (OPL2)",
2916#endif
2917 0,
2918 1,
2919 { .init_isa = Adlib_init }
2920 },
2921#endif
2922
2923#ifdef CONFIG_GUS
2924 {
2925 "gus",
2926 "Gravis Ultrasound GF1",
2927 0,
2928 1,
2929 { .init_isa = GUS_init }
2930 },
2931#endif
2932
2933#ifdef CONFIG_AC97
2934 {
2935 "ac97",
2936 "Intel 82801AA AC97 Audio",
2937 0,
2938 0,
2939 { .init_pci = ac97_init }
2940 },
2941#endif
2942
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002943#ifdef CONFIG_ES1370
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002944 {
2945 "es1370",
2946 "ENSONIQ AudioPCI ES1370",
2947 0,
2948 0,
2949 { .init_pci = es1370_init }
2950 },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002951#endif
2952
2953#endif /* HAS_AUDIO_CHOICE */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002954
2955 { NULL, NULL, 0, 0, { NULL } }
2956};
2957
2958static void select_soundhw (const char *optarg)
2959{
2960 struct soundhw *c;
2961
2962 if (*optarg == '?') {
2963 show_valid_cards:
2964
2965 printf ("Valid sound card names (comma separated):\n");
2966 for (c = soundhw; c->name; ++c) {
2967 printf ("%-11s %s\n", c->name, c->descr);
2968 }
2969 printf ("\n-soundhw all will enable all of the above\n");
2970 exit (*optarg != '?');
2971 }
2972 else {
2973 size_t l;
2974 const char *p;
2975 char *e;
2976 int bad_card = 0;
2977
2978 if (!strcmp (optarg, "all")) {
2979 for (c = soundhw; c->name; ++c) {
2980 c->enabled = 1;
2981 }
2982 return;
2983 }
2984
2985 p = optarg;
2986 while (*p) {
2987 e = strchr (p, ',');
2988 l = !e ? strlen (p) : (size_t) (e - p);
2989
2990 for (c = soundhw; c->name; ++c) {
2991 if (!strncmp (c->name, p, l)) {
2992 c->enabled = 1;
2993 break;
2994 }
2995 }
2996
2997 if (!c->name) {
2998 if (l > 80) {
2999 fprintf (stderr,
3000 "Unknown sound card name (too big to show)\n");
3001 }
3002 else {
3003 fprintf (stderr, "Unknown sound card name `%.*s'\n",
3004 (int) l, p);
3005 }
3006 bad_card = 1;
3007 }
3008 p += l + (e != NULL);
3009 }
3010
3011 if (bad_card)
3012 goto show_valid_cards;
3013 }
3014}
3015#endif
3016
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003017static void select_vgahw (const char *p)
3018{
3019 const char *opts;
3020
3021 cirrus_vga_enabled = 0;
3022 std_vga_enabled = 0;
3023 vmsvga_enabled = 0;
3024 xenfb_enabled = 0;
3025 if (strstart(p, "std", &opts)) {
3026 std_vga_enabled = 1;
3027 } else if (strstart(p, "cirrus", &opts)) {
3028 cirrus_vga_enabled = 1;
3029 } else if (strstart(p, "vmware", &opts)) {
3030 vmsvga_enabled = 1;
3031 } else if (strstart(p, "xenfb", &opts)) {
3032 xenfb_enabled = 1;
3033 } else if (!strstart(p, "none", &opts)) {
3034 invalid_vga:
3035 fprintf(stderr, "Unknown vga type: %s\n", p);
3036 exit(1);
3037 }
3038 while (*opts) {
3039 const char *nextopt;
3040
3041 if (strstart(opts, ",retrace=", &nextopt)) {
3042 opts = nextopt;
3043 if (strstart(opts, "dumb", &nextopt))
3044 vga_retrace_method = VGA_RETRACE_DUMB;
3045 else if (strstart(opts, "precise", &nextopt))
3046 vga_retrace_method = VGA_RETRACE_PRECISE;
3047 else goto invalid_vga;
3048 } else goto invalid_vga;
3049 opts = nextopt;
3050 }
3051}
3052
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003053int qemu_uuid_parse(const char *str, uint8_t *uuid)
3054{
3055 int ret;
3056
3057 if(strlen(str) != 36)
3058 return -1;
3059
3060 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
3061 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
3062 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
3063
3064 if(ret != 16)
3065 return -1;
3066
3067#ifdef TARGET_I386
3068 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
3069#endif
3070
3071 return 0;
3072}
3073
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003074#define MAX_NET_CLIENTS 32
3075
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003076#ifdef _WIN32
3077/* Look for support files in the same directory as the executable. */
3078static char *find_datadir(const char *argv0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003079{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003080 char *p;
3081 char buf[MAX_PATH];
3082 DWORD len;
3083
3084 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
3085 if (len == 0) {
3086 return NULL;
3087 }
3088
3089 buf[len] = 0;
3090 p = buf + len - 1;
3091 while (p != buf && *p != '\\')
3092 p--;
3093 *p = 0;
3094 if (access(buf, R_OK) == 0) {
3095 return qemu_strdup(buf);
3096 }
3097 return NULL;
3098}
3099#else /* !_WIN32 */
3100
3101/* Find a likely location for support files using the location of the binary.
3102 For installed binaries this will be "$bindir/../share/qemu". When
3103 running from the build tree this will be "$bindir/../pc-bios". */
3104#define SHARE_SUFFIX "/share/qemu"
3105#define BUILD_SUFFIX "/pc-bios"
3106static char *find_datadir(const char *argv0)
3107{
3108 char *dir;
3109 char *p = NULL;
3110 char *res;
3111#ifdef PATH_MAX
3112 char buf[PATH_MAX];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003113#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003114 size_t max_len;
3115
3116#if defined(__linux__)
3117 {
3118 int len;
3119 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
3120 if (len > 0) {
3121 buf[len] = 0;
3122 p = buf;
3123 }
3124 }
3125#elif defined(__FreeBSD__)
3126 {
3127 int len;
3128 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
3129 if (len > 0) {
3130 buf[len] = 0;
3131 p = buf;
3132 }
3133 }
3134#endif
3135 /* If we don't have any way of figuring out the actual executable
3136 location then try argv[0]. */
3137 if (!p) {
3138#ifdef PATH_MAX
3139 p = buf;
3140#endif
3141 p = realpath(argv0, p);
3142 if (!p) {
3143 return NULL;
3144 }
3145 }
3146 dir = dirname(p);
3147 dir = dirname(dir);
3148
3149 max_len = strlen(dir) +
3150 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
3151 res = qemu_mallocz(max_len);
3152 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
3153 if (access(res, R_OK)) {
3154 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
3155 if (access(res, R_OK)) {
3156 qemu_free(res);
3157 res = NULL;
3158 }
3159 }
3160#ifndef PATH_MAX
3161 free(p);
3162#endif
3163 return res;
3164}
3165#undef SHARE_SUFFIX
3166#undef BUILD_SUFFIX
3167#endif
3168
3169char *qemu_find_file(int type, const char *name)
3170{
3171 int len;
3172 const char *subdir;
3173 char *buf;
3174
3175 /* If name contains path separators then try it as a straight path. */
3176 if ((strchr(name, '/') || strchr(name, '\\'))
3177 && access(name, R_OK) == 0) {
David Turner025c32f2010-09-10 14:52:42 +02003178 return qemu_strdup(name);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003179 }
3180 switch (type) {
3181 case QEMU_FILE_TYPE_BIOS:
3182 subdir = "";
3183 break;
3184 case QEMU_FILE_TYPE_KEYMAP:
3185 subdir = "keymaps/";
3186 break;
3187 default:
3188 abort();
3189 }
3190 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
3191 buf = qemu_mallocz(len);
3192 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
3193 if (access(buf, R_OK)) {
3194 qemu_free(buf);
3195 return NULL;
3196 }
3197 return buf;
3198}
3199
3200int main(int argc, char **argv, char **envp)
3201{
3202 const char *gdbstub_dev = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003203 uint32_t boot_devices_bitmap = 0;
3204 int i;
3205 int snapshot, linux_boot, net_boot;
David Turner6a9ef172010-09-09 22:54:36 +02003206 const char *icount_option = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003207 const char *initrd_filename;
3208 const char *kernel_filename, *kernel_cmdline;
3209 const char *boot_devices = "";
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003210 DisplayState *ds;
3211 DisplayChangeListener *dcl;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003212 int cyls, heads, secs, translation;
3213 const char *net_clients[MAX_NET_CLIENTS];
3214 int nb_net_clients;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003215 const char *bt_opts[MAX_BT_CMDLINE];
3216 int nb_bt_opts;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003217 int hda_index;
3218 int optind;
3219 const char *r, *optarg;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003220 CharDriverState *monitor_hd = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003221 const char *monitor_device;
3222 const char *serial_devices[MAX_SERIAL_PORTS];
3223 int serial_device_index;
3224 const char *parallel_devices[MAX_PARALLEL_PORTS];
3225 int parallel_device_index;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003226 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
3227 int virtio_console_index;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003228 const char *loadvm = NULL;
3229 QEMUMachine *machine;
3230 const char *cpu_model;
3231 const char *usb_devices[MAX_USB_CMDLINE];
3232 int usb_devices_index;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003233 int tb_size;
3234 const char *pid_file = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003235 const char *incoming = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003236 CPUState *env;
3237 int show_vnc_port = 0;
3238
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003239 init_clocks();
3240
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003241 qemu_cache_utils_init(envp);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003242
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07003243 QLIST_INIT (&vm_change_state_head);
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003244 os_setup_early_signal_handling();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003245
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003246 module_call_init(MODULE_INIT_MACHINE);
3247 machine = find_default_machine();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003248 cpu_model = NULL;
3249 initrd_filename = NULL;
3250 ram_size = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003251 snapshot = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003252 kernel_filename = NULL;
3253 kernel_cmdline = "";
3254 cyls = heads = secs = 0;
3255 translation = BIOS_ATA_TRANSLATION_AUTO;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003256 monitor_device = "vc:80Cx24C";
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003257
3258 serial_devices[0] = "vc:80Cx24C";
3259 for(i = 1; i < MAX_SERIAL_PORTS; i++)
3260 serial_devices[i] = NULL;
3261 serial_device_index = 0;
3262
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003263 parallel_devices[0] = "vc:80Cx24C";
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003264 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3265 parallel_devices[i] = NULL;
3266 parallel_device_index = 0;
3267
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003268 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
3269 virtio_consoles[i] = NULL;
3270 virtio_console_index = 0;
3271
3272 for (i = 0; i < MAX_NODES; i++) {
3273 node_mem[i] = 0;
3274 node_cpumask[i] = 0;
3275 }
3276
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003277 usb_devices_index = 0;
3278
3279 nb_net_clients = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003280 nb_bt_opts = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003281 nb_drives = 0;
3282 nb_drives_opt = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003283 nb_numa_nodes = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003284 hda_index = -1;
3285
3286 nb_nics = 0;
3287
3288 tb_size = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003289 autostart= 1;
3290
3291 register_watchdogs();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003292
3293 optind = 1;
3294 for(;;) {
3295 if (optind >= argc)
3296 break;
3297 r = argv[optind];
3298 if (r[0] != '-') {
3299 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
3300 } else {
3301 const QEMUOption *popt;
3302
3303 optind++;
3304 /* Treat --foo the same as -foo. */
3305 if (r[1] == '-')
3306 r++;
3307 popt = qemu_options;
3308 for(;;) {
3309 if (!popt->name) {
3310 fprintf(stderr, "%s: invalid option -- '%s'\n",
3311 argv[0], r);
3312 exit(1);
3313 }
3314 if (!strcmp(popt->name, r + 1))
3315 break;
3316 popt++;
3317 }
3318 if (popt->flags & HAS_ARG) {
3319 if (optind >= argc) {
3320 fprintf(stderr, "%s: option '%s' requires an argument\n",
3321 argv[0], r);
3322 exit(1);
3323 }
3324 optarg = argv[optind++];
3325 } else {
3326 optarg = NULL;
3327 }
3328
3329 switch(popt->index) {
3330 case QEMU_OPTION_M:
3331 machine = find_machine(optarg);
3332 if (!machine) {
3333 QEMUMachine *m;
3334 printf("Supported machines are:\n");
3335 for(m = first_machine; m != NULL; m = m->next) {
3336 printf("%-10s %s%s\n",
3337 m->name, m->desc,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003338 m->is_default ? " (default)" : "");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003339 }
3340 exit(*optarg != '?');
3341 }
3342 break;
3343 case QEMU_OPTION_cpu:
3344 /* hw initialization will check this */
3345 if (*optarg == '?') {
3346/* XXX: implement xxx_cpu_list for targets that still miss it */
3347#if defined(cpu_list)
3348 cpu_list(stdout, &fprintf);
3349#endif
3350 exit(0);
3351 } else {
3352 cpu_model = optarg;
3353 }
3354 break;
3355 case QEMU_OPTION_initrd:
3356 initrd_filename = optarg;
3357 break;
3358 case QEMU_OPTION_hda:
3359 if (cyls == 0)
3360 hda_index = drive_add(optarg, HD_ALIAS, 0);
3361 else
3362 hda_index = drive_add(optarg, HD_ALIAS
3363 ",cyls=%d,heads=%d,secs=%d%s",
3364 0, cyls, heads, secs,
3365 translation == BIOS_ATA_TRANSLATION_LBA ?
3366 ",trans=lba" :
3367 translation == BIOS_ATA_TRANSLATION_NONE ?
3368 ",trans=none" : "");
3369 break;
3370 case QEMU_OPTION_hdb:
3371 case QEMU_OPTION_hdc:
3372 case QEMU_OPTION_hdd:
3373 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
3374 break;
3375 case QEMU_OPTION_drive:
3376 drive_add(NULL, "%s", optarg);
3377 break;
3378 case QEMU_OPTION_mtdblock:
3379 drive_add(optarg, MTD_ALIAS);
3380 break;
3381 case QEMU_OPTION_sd:
3382 drive_add(optarg, SD_ALIAS);
3383 break;
3384 case QEMU_OPTION_pflash:
3385 drive_add(optarg, PFLASH_ALIAS);
3386 break;
3387 case QEMU_OPTION_snapshot:
3388 snapshot = 1;
3389 break;
3390 case QEMU_OPTION_hdachs:
3391 {
3392 const char *p;
3393 p = optarg;
3394 cyls = strtol(p, (char **)&p, 0);
3395 if (cyls < 1 || cyls > 16383)
3396 goto chs_fail;
3397 if (*p != ',')
3398 goto chs_fail;
3399 p++;
3400 heads = strtol(p, (char **)&p, 0);
3401 if (heads < 1 || heads > 16)
3402 goto chs_fail;
3403 if (*p != ',')
3404 goto chs_fail;
3405 p++;
3406 secs = strtol(p, (char **)&p, 0);
3407 if (secs < 1 || secs > 63)
3408 goto chs_fail;
3409 if (*p == ',') {
3410 p++;
3411 if (!strcmp(p, "none"))
3412 translation = BIOS_ATA_TRANSLATION_NONE;
3413 else if (!strcmp(p, "lba"))
3414 translation = BIOS_ATA_TRANSLATION_LBA;
3415 else if (!strcmp(p, "auto"))
3416 translation = BIOS_ATA_TRANSLATION_AUTO;
3417 else
3418 goto chs_fail;
3419 } else if (*p != '\0') {
3420 chs_fail:
3421 fprintf(stderr, "qemu: invalid physical CHS format\n");
3422 exit(1);
3423 }
3424 if (hda_index != -1)
3425 snprintf(drives_opt[hda_index].opt,
3426 sizeof(drives_opt[hda_index].opt),
3427 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
3428 0, cyls, heads, secs,
3429 translation == BIOS_ATA_TRANSLATION_LBA ?
3430 ",trans=lba" :
3431 translation == BIOS_ATA_TRANSLATION_NONE ?
3432 ",trans=none" : "");
3433 }
3434 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003435 case QEMU_OPTION_numa:
3436 if (nb_numa_nodes >= MAX_NODES) {
3437 fprintf(stderr, "qemu: too many NUMA nodes\n");
3438 exit(1);
3439 }
3440 numa_add(optarg);
3441 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003442 case QEMU_OPTION_nographic:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003443 display_type = DT_NOGRAPHIC;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003444 break;
3445#ifdef CONFIG_CURSES
3446 case QEMU_OPTION_curses:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003447 display_type = DT_CURSES;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003448 break;
3449#endif
3450 case QEMU_OPTION_portrait:
3451 graphic_rotate = 1;
3452 break;
3453 case QEMU_OPTION_kernel:
3454 kernel_filename = optarg;
3455 break;
3456 case QEMU_OPTION_append:
3457 kernel_cmdline = optarg;
3458 break;
3459 case QEMU_OPTION_cdrom:
3460 drive_add(optarg, CDROM_ALIAS);
3461 break;
3462 case QEMU_OPTION_boot:
3463 boot_devices = optarg;
3464 /* We just do some generic consistency checks */
3465 {
3466 /* Could easily be extended to 64 devices if needed */
3467 const char *p;
David 'Digit' Turner707c8a82010-12-22 22:35:58 +01003468
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003469 boot_devices_bitmap = 0;
3470 for (p = boot_devices; *p != '\0'; p++) {
3471 /* Allowed boot devices are:
3472 * a b : floppy disk drives
3473 * c ... f : IDE disk drives
3474 * g ... m : machine implementation dependant drives
3475 * n ... p : network devices
3476 * It's up to each machine implementation to check
3477 * if the given boot devices match the actual hardware
3478 * implementation and firmware features.
3479 */
3480 if (*p < 'a' || *p > 'q') {
3481 fprintf(stderr, "Invalid boot device '%c'\n", *p);
3482 exit(1);
3483 }
3484 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
3485 fprintf(stderr,
3486 "Boot device '%c' was given twice\n",*p);
3487 exit(1);
3488 }
3489 boot_devices_bitmap |= 1 << (*p - 'a');
3490 }
3491 }
3492 break;
3493 case QEMU_OPTION_fda:
3494 case QEMU_OPTION_fdb:
3495 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
3496 break;
3497#ifdef TARGET_I386
3498 case QEMU_OPTION_no_fd_bootchk:
3499 fd_bootchk = 0;
3500 break;
3501#endif
3502 case QEMU_OPTION_net:
3503 if (nb_net_clients >= MAX_NET_CLIENTS) {
3504 fprintf(stderr, "qemu: too many network clients\n");
3505 exit(1);
3506 }
3507 net_clients[nb_net_clients] = optarg;
3508 nb_net_clients++;
3509 break;
3510#ifdef CONFIG_SLIRP
3511 case QEMU_OPTION_tftp:
3512 tftp_prefix = optarg;
3513 break;
3514 case QEMU_OPTION_bootp:
3515 bootp_filename = optarg;
3516 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003517 case QEMU_OPTION_redir:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003518 net_slirp_redir(NULL, optarg, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003519 break;
3520#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003521 case QEMU_OPTION_bt:
3522 if (nb_bt_opts >= MAX_BT_CMDLINE) {
3523 fprintf(stderr, "qemu: too many bluetooth options\n");
3524 exit(1);
3525 }
3526 bt_opts[nb_bt_opts++] = optarg;
3527 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003528#ifdef HAS_AUDIO
3529 case QEMU_OPTION_audio_help:
3530 AUD_help ();
3531 exit (0);
3532 break;
3533 case QEMU_OPTION_soundhw:
3534 select_soundhw (optarg);
3535 break;
3536#endif
3537 case QEMU_OPTION_h:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003538 help(0);
3539 break;
3540 case QEMU_OPTION_version:
3541 version();
3542 exit(0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003543 break;
3544 case QEMU_OPTION_m: {
3545 uint64_t value;
3546 char *ptr;
3547
3548 value = strtoul(optarg, &ptr, 10);
3549 switch (*ptr) {
3550 case 0: case 'M': case 'm':
3551 value <<= 20;
3552 break;
3553 case 'G': case 'g':
3554 value <<= 30;
3555 break;
3556 default:
3557 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
3558 exit(1);
3559 }
3560
3561 /* On 32-bit hosts, QEMU is limited by virtual address space */
David Turner025c32f2010-09-10 14:52:42 +02003562 if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003563 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
3564 exit(1);
3565 }
3566 if (value != (uint64_t)(ram_addr_t)value) {
3567 fprintf(stderr, "qemu: ram size too large\n");
3568 exit(1);
3569 }
3570 ram_size = value;
3571 break;
3572 }
3573 case QEMU_OPTION_d:
3574 {
3575 int mask;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003576 const CPULogItem *item;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003577
3578 mask = cpu_str_to_log_mask(optarg);
3579 if (!mask) {
3580 printf("Log items (comma separated):\n");
3581 for(item = cpu_log_items; item->mask != 0; item++) {
3582 printf("%-10s %s\n", item->name, item->help);
3583 }
3584 exit(1);
3585 }
3586 cpu_set_log(mask);
3587 }
3588 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003589 case QEMU_OPTION_s:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003590 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003591 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003592 case QEMU_OPTION_gdb:
3593 gdbstub_dev = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003594 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003595 case QEMU_OPTION_L:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003596 data_dir = optarg;
3597 break;
3598 case QEMU_OPTION_bios:
3599 bios_name = optarg;
3600 break;
3601 case QEMU_OPTION_singlestep:
3602 singlestep = 1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003603 break;
3604 case QEMU_OPTION_S:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003605 autostart = 0;
3606 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003607#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003608 case QEMU_OPTION_k:
3609 keyboard_layout = optarg;
3610 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003611#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003612 case QEMU_OPTION_localtime:
3613 rtc_utc = 0;
3614 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003615 case QEMU_OPTION_vga:
3616 select_vgahw (optarg);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003617 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003618#if defined(TARGET_PPC) || defined(TARGET_SPARC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003619 case QEMU_OPTION_g:
3620 {
3621 const char *p;
3622 int w, h, depth;
3623 p = optarg;
3624 w = strtol(p, (char **)&p, 10);
3625 if (w <= 0) {
3626 graphic_error:
3627 fprintf(stderr, "qemu: invalid resolution or depth\n");
3628 exit(1);
3629 }
3630 if (*p != 'x')
3631 goto graphic_error;
3632 p++;
3633 h = strtol(p, (char **)&p, 10);
3634 if (h <= 0)
3635 goto graphic_error;
3636 if (*p == 'x') {
3637 p++;
3638 depth = strtol(p, (char **)&p, 10);
3639 if (depth != 8 && depth != 15 && depth != 16 &&
3640 depth != 24 && depth != 32)
3641 goto graphic_error;
3642 } else if (*p == '\0') {
3643 depth = graphic_depth;
3644 } else {
3645 goto graphic_error;
3646 }
3647
3648 graphic_width = w;
3649 graphic_height = h;
3650 graphic_depth = depth;
3651 }
3652 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003653#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003654 case QEMU_OPTION_echr:
3655 {
3656 char *r;
3657 term_escape_char = strtol(optarg, &r, 0);
3658 if (r == optarg)
3659 printf("Bad argument to echr\n");
3660 break;
3661 }
3662 case QEMU_OPTION_monitor:
3663 monitor_device = optarg;
3664 break;
3665 case QEMU_OPTION_serial:
3666 if (serial_device_index >= MAX_SERIAL_PORTS) {
3667 fprintf(stderr, "qemu: too many serial ports\n");
3668 exit(1);
3669 }
3670 serial_devices[serial_device_index] = optarg;
3671 serial_device_index++;
3672 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003673 case QEMU_OPTION_watchdog:
3674 i = select_watchdog(optarg);
3675 if (i > 0)
3676 exit (i == 1 ? 1 : 0);
3677 break;
3678 case QEMU_OPTION_watchdog_action:
3679 if (select_watchdog_action(optarg) == -1) {
3680 fprintf(stderr, "Unknown -watchdog-action parameter\n");
3681 exit(1);
3682 }
3683 break;
3684 case QEMU_OPTION_virtiocon:
3685 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
3686 fprintf(stderr, "qemu: too many virtio consoles\n");
3687 exit(1);
3688 }
3689 virtio_consoles[virtio_console_index] = optarg;
3690 virtio_console_index++;
3691 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003692 case QEMU_OPTION_parallel:
3693 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
3694 fprintf(stderr, "qemu: too many parallel ports\n");
3695 exit(1);
3696 }
3697 parallel_devices[parallel_device_index] = optarg;
3698 parallel_device_index++;
3699 break;
3700 case QEMU_OPTION_loadvm:
3701 loadvm = optarg;
3702 break;
3703 case QEMU_OPTION_full_screen:
3704 full_screen = 1;
3705 break;
3706#ifdef CONFIG_SDL
3707 case QEMU_OPTION_no_frame:
3708 no_frame = 1;
3709 break;
3710 case QEMU_OPTION_alt_grab:
3711 alt_grab = 1;
3712 break;
3713 case QEMU_OPTION_no_quit:
3714 no_quit = 1;
3715 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003716 case QEMU_OPTION_sdl:
3717 display_type = DT_SDL;
3718 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003719#endif
3720 case QEMU_OPTION_pidfile:
3721 pid_file = optarg;
3722 break;
3723#ifdef TARGET_I386
3724 case QEMU_OPTION_win2k_hack:
3725 win2k_install_hack = 1;
3726 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003727 case QEMU_OPTION_rtc_td_hack:
3728 rtc_td_hack = 1;
3729 break;
3730 case QEMU_OPTION_acpitable:
3731 if(acpi_table_add(optarg) < 0) {
3732 fprintf(stderr, "Wrong acpi table provided\n");
3733 exit(1);
3734 }
3735 break;
3736 case QEMU_OPTION_smbios:
3737 if(smbios_entry_add(optarg) < 0) {
3738 fprintf(stderr, "Wrong smbios provided\n");
3739 exit(1);
3740 }
3741 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003742#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003743#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003744 case QEMU_OPTION_no_kqemu:
3745 kqemu_allowed = 0;
3746 break;
3747 case QEMU_OPTION_kernel_kqemu:
3748 kqemu_allowed = 2;
3749 break;
3750#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003751#ifdef CONFIG_KVM
3752 case QEMU_OPTION_enable_kvm:
3753 kvm_allowed = 1;
3754#ifdef CONFIG_KQEMU
3755 kqemu_allowed = 0;
3756#endif
3757 break;
3758#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003759 case QEMU_OPTION_usb:
3760 usb_enabled = 1;
3761 break;
3762 case QEMU_OPTION_usbdevice:
3763 usb_enabled = 1;
3764 if (usb_devices_index >= MAX_USB_CMDLINE) {
3765 fprintf(stderr, "Too many USB devices\n");
3766 exit(1);
3767 }
3768 usb_devices[usb_devices_index] = optarg;
3769 usb_devices_index++;
3770 break;
3771 case QEMU_OPTION_smp:
3772 smp_cpus = atoi(optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003773 if (smp_cpus < 1) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003774 fprintf(stderr, "Invalid number of CPUs\n");
3775 exit(1);
3776 }
3777 break;
3778 case QEMU_OPTION_vnc:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003779 display_type = DT_VNC;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003780 vnc_display = optarg;
3781 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003782#ifdef TARGET_I386
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003783 case QEMU_OPTION_no_acpi:
3784 acpi_enabled = 0;
3785 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003786 case QEMU_OPTION_no_hpet:
3787 no_hpet = 1;
3788 break;
3789 case QEMU_OPTION_no_virtio_balloon:
3790 no_virtio_balloon = 1;
3791 break;
3792#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003793 case QEMU_OPTION_no_reboot:
3794 no_reboot = 1;
3795 break;
3796 case QEMU_OPTION_no_shutdown:
3797 no_shutdown = 1;
3798 break;
3799 case QEMU_OPTION_show_cursor:
3800 cursor_hide = 0;
3801 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003802 case QEMU_OPTION_uuid:
3803 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
3804 fprintf(stderr, "Fail to parse UUID string."
3805 " Wrong format.\n");
3806 exit(1);
3807 }
3808 break;
3809#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003810 case QEMU_OPTION_daemonize:
3811 daemonize = 1;
3812 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003813#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003814 case QEMU_OPTION_option_rom:
3815 if (nb_option_roms >= MAX_OPTION_ROMS) {
3816 fprintf(stderr, "Too many option ROMs\n");
3817 exit(1);
3818 }
3819 option_rom[nb_option_roms] = optarg;
3820 nb_option_roms++;
3821 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003822#if defined(TARGET_ARM) || defined(TARGET_M68K)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003823 case QEMU_OPTION_semihosting:
3824 semihosting_enabled = 1;
3825 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003826#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003827 case QEMU_OPTION_name:
3828 qemu_name = optarg;
3829 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003830#if defined(TARGET_SPARC) || defined(TARGET_PPC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003831 case QEMU_OPTION_prom_env:
3832 if (nb_prom_envs >= MAX_PROM_ENVS) {
3833 fprintf(stderr, "Too many prom variables\n");
3834 exit(1);
3835 }
3836 prom_envs[nb_prom_envs] = optarg;
3837 nb_prom_envs++;
3838 break;
3839#endif
3840#ifdef TARGET_ARM
3841 case QEMU_OPTION_old_param:
3842 old_param = 1;
3843 break;
3844#endif
3845 case QEMU_OPTION_clock:
3846 configure_alarms(optarg);
3847 break;
3848 case QEMU_OPTION_startdate:
3849 {
3850 struct tm tm;
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003851 time_t rtc_start_date = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003852 if (!strcmp(optarg, "now")) {
3853 rtc_date_offset = -1;
3854 } else {
3855 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
3856 &tm.tm_year,
3857 &tm.tm_mon,
3858 &tm.tm_mday,
3859 &tm.tm_hour,
3860 &tm.tm_min,
3861 &tm.tm_sec) == 6) {
3862 /* OK */
3863 } else if (sscanf(optarg, "%d-%d-%d",
3864 &tm.tm_year,
3865 &tm.tm_mon,
3866 &tm.tm_mday) == 3) {
3867 tm.tm_hour = 0;
3868 tm.tm_min = 0;
3869 tm.tm_sec = 0;
3870 } else {
3871 goto date_fail;
3872 }
3873 tm.tm_year -= 1900;
3874 tm.tm_mon--;
3875 rtc_start_date = mktimegm(&tm);
3876 if (rtc_start_date == -1) {
3877 date_fail:
3878 fprintf(stderr, "Invalid date format. Valid format are:\n"
3879 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
3880 exit(1);
3881 }
3882 rtc_date_offset = time(NULL) - rtc_start_date;
3883 }
3884 }
3885 break;
3886 case QEMU_OPTION_tb_size:
3887 tb_size = strtol(optarg, NULL, 0);
3888 if (tb_size < 0)
3889 tb_size = 0;
3890 break;
3891 case QEMU_OPTION_icount:
David Turner6a9ef172010-09-09 22:54:36 +02003892 icount_option = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003893 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003894 case QEMU_OPTION_incoming:
3895 incoming = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003896 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003897#ifdef CONFIG_XEN
3898 case QEMU_OPTION_xen_domid:
3899 xen_domid = atoi(optarg);
3900 break;
3901 case QEMU_OPTION_xen_create:
3902 xen_mode = XEN_CREATE;
3903 break;
3904 case QEMU_OPTION_xen_attach:
3905 xen_mode = XEN_ATTACH;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003906 break;
3907#endif
3908 }
3909 }
3910 }
3911
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003912 /* If no data_dir is specified then try to find it relative to the
3913 executable path. */
3914 if (!data_dir) {
3915 data_dir = find_datadir(argv[0]);
3916 }
3917 /* If all else fails use the install patch specified when building. */
3918 if (!data_dir) {
3919 data_dir = CONFIG_QEMU_SHAREDIR;
3920 }
3921
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003922 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
3923 os_pidfile_error();
3924 exit(1);
3925 }
3926
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003927#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
3928 if (kvm_allowed && kqemu_allowed) {
3929 fprintf(stderr,
3930 "You can not enable both KVM and kqemu at the same time\n");
3931 exit(1);
3932 }
3933#endif
3934
3935 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
3936 if (smp_cpus > machine->max_cpus) {
3937 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
3938 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
3939 machine->max_cpus);
3940 exit(1);
3941 }
3942
3943 if (display_type == DT_NOGRAPHIC) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003944 if (serial_device_index == 0)
3945 serial_devices[0] = "stdio";
3946 if (parallel_device_index == 0)
3947 parallel_devices[0] = "null";
3948 if (strncmp(monitor_device, "vc", 2) == 0)
3949 monitor_device = "stdio";
3950 }
3951
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003952#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003953 if (smp_cpus > 1)
3954 kqemu_allowed = 0;
3955#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003956 if (qemu_init_main_loop()) {
3957 fprintf(stderr, "qemu_init_main_loop failed\n");
3958 exit(1);
3959 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003960 linux_boot = (kernel_filename != NULL);
3961 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
3962
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003963 if (!linux_boot && *kernel_cmdline != '\0') {
3964 fprintf(stderr, "-append only allowed with -kernel option\n");
3965 exit(1);
3966 }
3967
3968 if (!linux_boot && initrd_filename != NULL) {
3969 fprintf(stderr, "-initrd only allowed with -kernel option\n");
3970 exit(1);
3971 }
3972
3973 /* boot to floppy or the default cd if no hard disk defined yet */
3974 if (!boot_devices[0]) {
3975 boot_devices = "cad";
3976 }
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02003977 os_set_line_buffering();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003978
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003979 if (init_timer_alarm() < 0) {
3980 fprintf(stderr, "could not initialize alarm timer\n");
3981 exit(1);
3982 }
David Turner6a9ef172010-09-09 22:54:36 +02003983 configure_icount(icount_option);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003984
3985#ifdef _WIN32
3986 socket_init();
3987#endif
3988
3989 /* init network clients */
3990 if (nb_net_clients == 0) {
3991 /* if no clients, we use a default config */
3992 net_clients[nb_net_clients++] = "nic";
3993#ifdef CONFIG_SLIRP
3994 net_clients[nb_net_clients++] = "user";
3995#endif
3996 }
3997
3998 for(i = 0;i < nb_net_clients; i++) {
3999 if (net_client_parse(net_clients[i]) < 0)
4000 exit(1);
4001 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004002 net_client_check();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004003
4004#ifdef TARGET_I386
4005 /* XXX: this should be moved in the PC machine instantiation code */
4006 if (net_boot != 0) {
4007 int netroms = 0;
4008 for (i = 0; i < nb_nics && i < 4; i++) {
4009 const char *model = nd_table[i].model;
4010 char buf[1024];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004011 char *filename;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004012 if (net_boot & (1 << i)) {
4013 if (model == NULL)
4014 model = "ne2k_pci";
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004015 snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
4016 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
4017 if (filename && get_image_size(filename) > 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004018 if (nb_option_roms >= MAX_OPTION_ROMS) {
4019 fprintf(stderr, "Too many option ROMs\n");
4020 exit(1);
4021 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004022 option_rom[nb_option_roms] = qemu_strdup(buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004023 nb_option_roms++;
4024 netroms++;
4025 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004026 if (filename) {
4027 qemu_free(filename);
4028 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004029 }
4030 }
4031 if (netroms == 0) {
4032 fprintf(stderr, "No valid PXE rom found for network device\n");
4033 exit(1);
4034 }
4035 }
4036#endif
4037
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004038 /* init the bluetooth world */
4039 for (i = 0; i < nb_bt_opts; i++)
4040 if (bt_parse(bt_opts[i]))
4041 exit(1);
4042
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004043 /* init the memory */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004044 if (ram_size == 0)
4045 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004046
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004047#ifdef CONFIG_KQEMU
4048 /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
4049 guest ram allocation. It needs to go away. */
4050 if (kqemu_allowed) {
4051 kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
4052 kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
4053 if (!kqemu_phys_ram_base) {
4054 fprintf(stderr, "Could not allocate physical memory\n");
4055 exit(1);
4056 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004057 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004058#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004059
4060 /* init the dynamic translator */
4061 cpu_exec_init_all(tb_size * 1024 * 1024);
4062
4063 bdrv_init();
4064
4065 /* we always create the cdrom drive, even if no disk is there */
4066
4067 if (nb_drives_opt < MAX_DRIVES)
4068 drive_add(NULL, CDROM_ALIAS);
4069
4070 /* we always create at least one floppy */
4071
4072 if (nb_drives_opt < MAX_DRIVES)
4073 drive_add(NULL, FD_ALIAS, 0);
4074
4075 /* we always create one sd slot, even if no card is in it */
4076
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004077 if (nb_drives_opt < MAX_DRIVES) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004078 drive_add(NULL, SD_ALIAS);
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004079 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004080
4081 /* open the virtual block devices */
David 'Digit' Turnercb42a1b2010-12-23 02:54:08 +01004082 if (snapshot)
4083 qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
4084 if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
4085 exit(1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004086
David Turner6a9ef172010-09-09 22:54:36 +02004087 //register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004088 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004089
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004090 /* must be after terminal init, SDL library changes signal handlers */
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004091 os_setup_signal_handling();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004092
4093 /* Maintain compatibility with multiple stdio monitors */
4094 if (!strcmp(monitor_device,"stdio")) {
4095 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
4096 const char *devname = serial_devices[i];
4097 if (devname && !strcmp(devname,"mon:stdio")) {
4098 monitor_device = NULL;
4099 break;
4100 } else if (devname && !strcmp(devname,"stdio")) {
4101 monitor_device = NULL;
4102 serial_devices[i] = "mon:stdio";
4103 break;
4104 }
4105 }
4106 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004107
4108 if (nb_numa_nodes > 0) {
4109 int i;
4110
4111 if (nb_numa_nodes > smp_cpus) {
4112 nb_numa_nodes = smp_cpus;
4113 }
4114
4115 /* If no memory size if given for any node, assume the default case
4116 * and distribute the available memory equally across all nodes
4117 */
4118 for (i = 0; i < nb_numa_nodes; i++) {
4119 if (node_mem[i] != 0)
4120 break;
4121 }
4122 if (i == nb_numa_nodes) {
4123 uint64_t usedmem = 0;
4124
4125 /* On Linux, the each node's border has to be 8MB aligned,
4126 * the final node gets the rest.
4127 */
4128 for (i = 0; i < nb_numa_nodes - 1; i++) {
4129 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
4130 usedmem += node_mem[i];
4131 }
4132 node_mem[i] = ram_size - usedmem;
4133 }
4134
4135 for (i = 0; i < nb_numa_nodes; i++) {
4136 if (node_cpumask[i] != 0)
4137 break;
4138 }
4139 /* assigning the VCPUs round-robin is easier to implement, guest OSes
4140 * must cope with this anyway, because there are BIOSes out there in
4141 * real machines which also use this scheme.
4142 */
4143 if (i == nb_numa_nodes) {
4144 for (i = 0; i < smp_cpus; i++) {
4145 node_cpumask[i % nb_numa_nodes] |= 1 << i;
4146 }
4147 }
4148 }
4149
4150 if (kvm_enabled()) {
4151 int ret;
4152
4153 ret = kvm_init(smp_cpus);
4154 if (ret < 0) {
4155 fprintf(stderr, "failed to initialize KVM\n");
4156 exit(1);
4157 }
4158 }
4159
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004160 if (monitor_device) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004161 monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004162 if (!monitor_hd) {
4163 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
4164 exit(1);
4165 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004166 }
4167
4168 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
4169 const char *devname = serial_devices[i];
4170 if (devname && strcmp(devname, "none")) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004171 char label[32];
4172 snprintf(label, sizeof(label), "serial%d", i);
4173 serial_hds[i] = qemu_chr_open(label, devname, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004174 if (!serial_hds[i]) {
4175 fprintf(stderr, "qemu: could not open serial device '%s'\n",
4176 devname);
4177 exit(1);
4178 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004179 }
4180 }
4181
4182 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
4183 const char *devname = parallel_devices[i];
4184 if (devname && strcmp(devname, "none")) {
4185 char label[32];
4186 snprintf(label, sizeof(label), "parallel%d", i);
4187 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
4188 if (!parallel_hds[i]) {
4189 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
4190 devname);
4191 exit(1);
4192 }
4193 }
4194 }
4195
4196 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
4197 const char *devname = virtio_consoles[i];
4198 if (devname && strcmp(devname, "none")) {
4199 char label[32];
4200 snprintf(label, sizeof(label), "virtcon%d", i);
4201 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
4202 if (!virtcon_hds[i]) {
4203 fprintf(stderr, "qemu: could not open virtio console '%s'\n",
4204 devname);
4205 exit(1);
4206 }
4207 }
4208 }
4209
4210 module_call_init(MODULE_INIT_DEVICE);
4211
4212 machine->init(ram_size, boot_devices,
4213 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
4214
4215
4216 for (env = first_cpu; env != NULL; env = env->next_cpu) {
4217 for (i = 0; i < nb_numa_nodes; i++) {
4218 if (node_cpumask[i] & (1 << env->cpu_index)) {
4219 env->numa_node = i;
4220 }
4221 }
4222 }
4223
4224 current_machine = machine;
4225
4226 /* Set KVM's vcpu state to qemu's initial CPUState. */
4227 if (kvm_enabled()) {
4228 int ret;
4229
4230 ret = kvm_sync_vcpus();
4231 if (ret < 0) {
4232 fprintf(stderr, "failed to initialize vcpus\n");
4233 exit(1);
4234 }
4235 }
4236
4237 /* init USB devices */
4238 if (usb_enabled) {
4239 for(i = 0; i < usb_devices_index; i++) {
4240 if (usb_device_add(usb_devices[i], 0) < 0) {
4241 fprintf(stderr, "Warning: could not add USB device %s\n",
4242 usb_devices[i]);
4243 }
4244 }
4245 }
4246
4247 if (!display_state)
4248 dumb_display_init();
4249 /* just use the first displaystate for the moment */
4250 ds = display_state;
4251
4252 if (display_type == DT_DEFAULT) {
4253#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
4254 display_type = DT_SDL;
4255#else
4256 display_type = DT_VNC;
4257 vnc_display = "localhost:0,to=99";
4258 show_vnc_port = 1;
4259#endif
4260 }
David 'Digit' Turner707c8a82010-12-22 22:35:58 +01004261
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004262
4263 switch (display_type) {
4264 case DT_NOGRAPHIC:
4265 break;
4266#if defined(CONFIG_CURSES)
4267 case DT_CURSES:
4268 curses_display_init(ds, full_screen);
4269 break;
4270#endif
4271#if defined(CONFIG_SDL)
4272 case DT_SDL:
4273 sdl_display_init(ds, full_screen, no_frame);
4274 break;
4275#elif defined(CONFIG_COCOA)
4276 case DT_SDL:
4277 cocoa_display_init(ds, full_screen);
4278 break;
4279#endif
4280 case DT_VNC:
4281 vnc_display_init(ds);
4282 if (vnc_display_open(ds, vnc_display) < 0)
4283 exit(1);
4284
4285 if (show_vnc_port) {
4286 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
4287 }
4288 break;
4289 default:
4290 break;
4291 }
4292 dpy_resize(ds);
4293
4294 dcl = ds->listeners;
4295 while (dcl != NULL) {
4296 if (dcl->dpy_refresh != NULL) {
David 'Digit' Turner5973c772011-05-10 07:06:00 +02004297 ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
4298 qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004299 }
4300 dcl = dcl->next;
4301 }
4302
4303 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
David 'Digit' Turner5973c772011-05-10 07:06:00 +02004304 nographic_timer = qemu_new_timer_ms(rt_clock, nographic_update, NULL);
4305 qemu_mod_timer(nographic_timer, qemu_get_clock_ms(rt_clock));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004306 }
4307
4308 text_consoles_set_display(display_state);
4309 qemu_chr_initial_reset();
4310
4311 if (monitor_device && monitor_hd)
4312 monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
4313
4314 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
4315 const char *devname = serial_devices[i];
4316 if (devname && strcmp(devname, "none")) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004317 if (strstart(devname, "vc", 0))
4318 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
4319 }
4320 }
4321
4322 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
4323 const char *devname = parallel_devices[i];
4324 if (devname && strcmp(devname, "none")) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004325 if (strstart(devname, "vc", 0))
4326 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
4327 }
4328 }
4329
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004330 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
4331 const char *devname = virtio_consoles[i];
4332 if (virtcon_hds[i] && devname) {
4333 if (strstart(devname, "vc", 0))
4334 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004335 }
4336 }
4337
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004338 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
4339 fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
4340 gdbstub_dev);
4341 exit(1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004342 }
4343
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004344 if (loadvm)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004345 do_loadvm(cur_mon, loadvm);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004346
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004347 if (incoming) {
4348 autostart = 0; /* fixme how to deal with -daemonize */
4349 qemu_start_incoming_migration(incoming);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004350 }
4351
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004352 if (autostart)
4353 vm_start();
4354
David 'Digit' Turnerc1ac40a2011-06-01 16:12:04 +02004355 os_setup_post();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004356
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004357 main_loop();
4358 quit_timers();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004359 net_cleanup();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004360
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004361 return 0;
4362}