blob: 3ad20e0be4bcd25e9217fda0fee4843f7a784a2e [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
129#undef main
130#define main qemu_main
131#endif /* CONFIG_COCOA */
132
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700133#include "hw/hw.h"
134#include "hw/boards.h"
135#include "hw/usb.h"
136#include "hw/pcmcia.h"
137#include "hw/pc.h"
138#include "hw/audiodev.h"
139#include "hw/isa.h"
140#include "hw/baum.h"
141#include "hw/bt.h"
142#include "hw/watchdog.h"
143#include "hw/smbios.h"
144#include "hw/xen.h"
145#include "bt-host.h"
146#include "net.h"
147#include "monitor.h"
148#include "console.h"
149#include "sysemu.h"
150#include "gdbstub.h"
151#include "qemu-timer.h"
152#include "qemu-char.h"
153#include "cache-utils.h"
154#include "block.h"
155#include "dma.h"
156#include "audio/audio.h"
157#include "migration.h"
158#include "kvm.h"
159#include "balloon.h"
160#include "qemu-option.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800161
162#include "disas.h"
163
164#include "exec-all.h"
165
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700166#include "qemu_socket.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800167
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700168#if defined(CONFIG_SLIRP)
169#include "libslirp.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800170#endif
171
172//#define DEBUG_UNUSED_IOPORT
173//#define DEBUG_IOPORT
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700174//#define DEBUG_NET
175//#define DEBUG_SLIRP
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800176
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700177
178#ifdef DEBUG_IOPORT
179# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800180#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700181# define LOG_IOPORT(...) do { } while (0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800182#endif
183
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700184#define DEFAULT_RAM_SIZE 128
185
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800186/* Max number of USB devices that can be specified on the commandline. */
187#define MAX_USB_CMDLINE 8
188
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700189/* Max number of bluetooth switches on the commandline. */
190#define MAX_BT_CMDLINE 10
191
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800192/* XXX: use a two level table to limit memory usage */
193#define MAX_IOPORTS 65536
194
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700195static const char *data_dir;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800196const char *bios_name = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700197static void *ioport_opaque[MAX_IOPORTS];
198static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
199static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800200/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
201 to store the VM snapshots */
202DriveInfo drives_table[MAX_DRIVES+1];
203int nb_drives;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700204enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
205static DisplayState *display_state;
206DisplayType display_type = DT_DEFAULT;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800207const char* keyboard_layout = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800208ram_addr_t ram_size;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800209int nb_nics;
210NICInfo nd_table[MAX_NICS];
211int vm_running;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700212static int autostart;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800213static int rtc_utc = 1;
214static int rtc_date_offset = -1; /* -1 means no change */
215int cirrus_vga_enabled = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700216int std_vga_enabled = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800217int vmsvga_enabled = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700218int xenfb_enabled = 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700219QEMUClock *rtc_clock;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800220#ifdef TARGET_SPARC
221int graphic_width = 1024;
222int graphic_height = 768;
223int graphic_depth = 8;
224#else
225int graphic_width = 800;
226int graphic_height = 600;
227int graphic_depth = 15;
228#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700229static int full_screen = 0;
230#ifdef CONFIG_SDL
231static int no_frame = 0;
232#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800233int no_quit = 0;
234CharDriverState *serial_hds[MAX_SERIAL_PORTS];
235CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700236CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800237#ifdef TARGET_I386
238int win2k_install_hack = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700239int rtc_td_hack = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800240#endif
241int usb_enabled = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700242int singlestep = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800243int smp_cpus = 1;
244const char *vnc_display;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800245int acpi_enabled = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700246int no_hpet = 0;
247int no_virtio_balloon = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800248int fd_bootchk = 1;
249int no_reboot = 0;
250int no_shutdown = 0;
251int cursor_hide = 1;
252int graphic_rotate = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700253#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800254int daemonize = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700255#endif
256WatchdogTimerModel *watchdog = NULL;
257int watchdog_action = WDT_RESET;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800258const char *option_rom[MAX_OPTION_ROMS];
259int nb_option_roms;
260int semihosting_enabled = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800261#ifdef TARGET_ARM
262int old_param = 0;
263#endif
264const char *qemu_name;
265int alt_grab = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700266#if defined(TARGET_SPARC) || defined(TARGET_PPC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800267unsigned int nb_prom_envs = 0;
268const char *prom_envs[MAX_PROM_ENVS];
269#endif
270int nb_drives_opt;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700271struct drive_opt drives_opt[MAX_DRIVES];
272
273int nb_numa_nodes;
274uint64_t node_mem[MAX_NODES];
275uint64_t node_cpumask[MAX_NODES];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800276
277static CPUState *cur_cpu;
278static CPUState *next_cpu;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700279static int timer_alarm_pending = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700280static QEMUTimer *nographic_timer;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800281
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700282uint8_t qemu_uuid[16];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800283
284/***********************************************************/
285/* x86 ISA bus support */
286
287target_phys_addr_t isa_mem_base = 0;
288PicState2 *isa_pic;
289
290static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
291static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
292
293static uint32_t ioport_read(int index, uint32_t address)
294{
295 static IOPortReadFunc *default_func[3] = {
296 default_ioport_readb,
297 default_ioport_readw,
298 default_ioport_readl
299 };
300 IOPortReadFunc *func = ioport_read_table[index][address];
301 if (!func)
302 func = default_func[index];
303 return func(ioport_opaque[address], address);
304}
305
306static void ioport_write(int index, uint32_t address, uint32_t data)
307{
308 static IOPortWriteFunc *default_func[3] = {
309 default_ioport_writeb,
310 default_ioport_writew,
311 default_ioport_writel
312 };
313 IOPortWriteFunc *func = ioport_write_table[index][address];
314 if (!func)
315 func = default_func[index];
316 func(ioport_opaque[address], address, data);
317}
318
319static uint32_t default_ioport_readb(void *opaque, uint32_t address)
320{
321#ifdef DEBUG_UNUSED_IOPORT
322 fprintf(stderr, "unused inb: port=0x%04x\n", address);
323#endif
324 return 0xff;
325}
326
327static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
328{
329#ifdef DEBUG_UNUSED_IOPORT
330 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
331#endif
332}
333
334/* default is to make two byte accesses */
335static uint32_t default_ioport_readw(void *opaque, uint32_t address)
336{
337 uint32_t data;
338 data = ioport_read(0, address);
339 address = (address + 1) & (MAX_IOPORTS - 1);
340 data |= ioport_read(0, address) << 8;
341 return data;
342}
343
344static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
345{
346 ioport_write(0, address, data & 0xff);
347 address = (address + 1) & (MAX_IOPORTS - 1);
348 ioport_write(0, address, (data >> 8) & 0xff);
349}
350
351static uint32_t default_ioport_readl(void *opaque, uint32_t address)
352{
353#ifdef DEBUG_UNUSED_IOPORT
354 fprintf(stderr, "unused inl: port=0x%04x\n", address);
355#endif
356 return 0xffffffff;
357}
358
359static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
360{
361#ifdef DEBUG_UNUSED_IOPORT
362 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
363#endif
364}
365
366/* size is the word size in byte */
367int register_ioport_read(int start, int length, int size,
368 IOPortReadFunc *func, void *opaque)
369{
370 int i, bsize;
371
372 if (size == 1) {
373 bsize = 0;
374 } else if (size == 2) {
375 bsize = 1;
376 } else if (size == 4) {
377 bsize = 2;
378 } else {
379 hw_error("register_ioport_read: invalid size");
380 return -1;
381 }
382 for(i = start; i < start + length; i += size) {
383 ioport_read_table[bsize][i] = func;
384 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
385 hw_error("register_ioport_read: invalid opaque");
386 ioport_opaque[i] = opaque;
387 }
388 return 0;
389}
390
391/* size is the word size in byte */
392int register_ioport_write(int start, int length, int size,
393 IOPortWriteFunc *func, void *opaque)
394{
395 int i, bsize;
396
397 if (size == 1) {
398 bsize = 0;
399 } else if (size == 2) {
400 bsize = 1;
401 } else if (size == 4) {
402 bsize = 2;
403 } else {
404 hw_error("register_ioport_write: invalid size");
405 return -1;
406 }
407 for(i = start; i < start + length; i += size) {
408 ioport_write_table[bsize][i] = func;
409 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
410 hw_error("register_ioport_write: invalid opaque");
411 ioport_opaque[i] = opaque;
412 }
413 return 0;
414}
415
416void isa_unassign_ioport(int start, int length)
417{
418 int i;
419
420 for(i = start; i < start + length; i++) {
421 ioport_read_table[0][i] = default_ioport_readb;
422 ioport_read_table[1][i] = default_ioport_readw;
423 ioport_read_table[2][i] = default_ioport_readl;
424
425 ioport_write_table[0][i] = default_ioport_writeb;
426 ioport_write_table[1][i] = default_ioport_writew;
427 ioport_write_table[2][i] = default_ioport_writel;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700428
429 ioport_opaque[i] = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800430 }
431}
432
433/***********************************************************/
434
435void cpu_outb(CPUState *env, int addr, int val)
436{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700437 LOG_IOPORT("outb: %04x %02x\n", addr, val);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800438 ioport_write(0, addr, val);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700439#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800440 if (env)
441 env->last_io_time = cpu_get_time_fast();
442#endif
443}
444
445void cpu_outw(CPUState *env, int addr, int val)
446{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700447 LOG_IOPORT("outw: %04x %04x\n", addr, val);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800448 ioport_write(1, addr, val);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700449#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800450 if (env)
451 env->last_io_time = cpu_get_time_fast();
452#endif
453}
454
455void cpu_outl(CPUState *env, int addr, int val)
456{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700457 LOG_IOPORT("outl: %04x %08x\n", addr, val);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800458 ioport_write(2, addr, val);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700459#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800460 if (env)
461 env->last_io_time = cpu_get_time_fast();
462#endif
463}
464
465int cpu_inb(CPUState *env, int addr)
466{
467 int val;
468 val = ioport_read(0, addr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700469 LOG_IOPORT("inb : %04x %02x\n", addr, val);
470#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800471 if (env)
472 env->last_io_time = cpu_get_time_fast();
473#endif
474 return val;
475}
476
477int cpu_inw(CPUState *env, int addr)
478{
479 int val;
480 val = ioport_read(1, addr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700481 LOG_IOPORT("inw : %04x %04x\n", addr, val);
482#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800483 if (env)
484 env->last_io_time = cpu_get_time_fast();
485#endif
486 return val;
487}
488
489int cpu_inl(CPUState *env, int addr)
490{
491 int val;
492 val = ioport_read(2, addr);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700493 LOG_IOPORT("inl : %04x %08x\n", addr, val);
494#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800495 if (env)
496 env->last_io_time = cpu_get_time_fast();
497#endif
498 return val;
499}
500
501/***********************************************************/
502void hw_error(const char *fmt, ...)
503{
504 va_list ap;
505 CPUState *env;
506
507 va_start(ap, fmt);
508 fprintf(stderr, "qemu: hardware error: ");
509 vfprintf(stderr, fmt, ap);
510 fprintf(stderr, "\n");
511 for(env = first_cpu; env != NULL; env = env->next_cpu) {
512 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
513#ifdef TARGET_I386
514 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
515#else
516 cpu_dump_state(env, stderr, fprintf, 0);
517#endif
518 }
519 va_end(ap);
520 abort();
521}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700522
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700523static void set_proc_name(const char *s)
524{
525#if defined(__linux__) && defined(PR_SET_NAME)
526 char name[16];
527 if (!s)
528 return;
529 name[sizeof(name) - 1] = 0;
530 strncpy(name, s, sizeof(name));
531 /* Could rewrite argv[0] too, but that's a bit more complicated.
532 This simple way is enough for `top'. */
533 prctl(PR_SET_NAME, name);
534#endif
535}
536
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700537/***************/
538/* ballooning */
539
540static QEMUBalloonEvent *qemu_balloon_event;
541void *qemu_balloon_event_opaque;
542
543void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
544{
545 qemu_balloon_event = func;
546 qemu_balloon_event_opaque = opaque;
547}
548
549void qemu_balloon(ram_addr_t target)
550{
551 if (qemu_balloon_event)
552 qemu_balloon_event(qemu_balloon_event_opaque, target);
553}
554
555ram_addr_t qemu_balloon_status(void)
556{
557 if (qemu_balloon_event)
558 return qemu_balloon_event(qemu_balloon_event_opaque, 0);
559 return 0;
560}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800561
562/***********************************************************/
563/* keyboard/mouse */
564
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700565static QEMUPutKBDEvent *qemu_put_kbd_event;
566static void *qemu_put_kbd_event_opaque;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800567static QEMUPutMouseEntry *qemu_put_mouse_event_head;
568static QEMUPutMouseEntry *qemu_put_mouse_event_current;
569
570void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
571{
572 qemu_put_kbd_event_opaque = opaque;
573 qemu_put_kbd_event = func;
574}
575
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800576QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
577 void *opaque, int absolute,
578 const char *name)
579{
580 QEMUPutMouseEntry *s, *cursor;
581
582 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800583
584 s->qemu_put_mouse_event = func;
585 s->qemu_put_mouse_event_opaque = opaque;
586 s->qemu_put_mouse_event_absolute = absolute;
587 s->qemu_put_mouse_event_name = qemu_strdup(name);
588 s->next = NULL;
589
590 if (!qemu_put_mouse_event_head) {
591 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
592 return s;
593 }
594
595 cursor = qemu_put_mouse_event_head;
596 while (cursor->next != NULL)
597 cursor = cursor->next;
598
599 cursor->next = s;
600 qemu_put_mouse_event_current = s;
601
602 return s;
603}
604
605void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
606{
607 QEMUPutMouseEntry *prev = NULL, *cursor;
608
609 if (!qemu_put_mouse_event_head || entry == NULL)
610 return;
611
612 cursor = qemu_put_mouse_event_head;
613 while (cursor != NULL && cursor != entry) {
614 prev = cursor;
615 cursor = cursor->next;
616 }
617
618 if (cursor == NULL) // does not exist or list empty
619 return;
620 else if (prev == NULL) { // entry is head
621 qemu_put_mouse_event_head = cursor->next;
622 if (qemu_put_mouse_event_current == entry)
623 qemu_put_mouse_event_current = cursor->next;
624 qemu_free(entry->qemu_put_mouse_event_name);
625 qemu_free(entry);
626 return;
627 }
628
629 prev->next = entry->next;
630
631 if (qemu_put_mouse_event_current == entry)
632 qemu_put_mouse_event_current = prev;
633
634 qemu_free(entry->qemu_put_mouse_event_name);
635 qemu_free(entry);
636}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800637
638void kbd_put_keycode(int keycode)
639{
640 if (qemu_put_kbd_event) {
641 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
642 }
643}
644
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800645void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
646{
647 QEMUPutMouseEvent *mouse_event;
648 void *mouse_event_opaque;
649 int width;
650
651 if (!qemu_put_mouse_event_current) {
652 return;
653 }
654
655 mouse_event =
656 qemu_put_mouse_event_current->qemu_put_mouse_event;
657 mouse_event_opaque =
658 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
659
660 if (mouse_event) {
661 if (graphic_rotate) {
662 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
663 width = 0x7fff;
664 else
665 width = graphic_width - 1;
666 mouse_event(mouse_event_opaque,
667 width - dy, dx, dz, buttons_state);
668 } else
669 mouse_event(mouse_event_opaque,
670 dx, dy, dz, buttons_state);
671 }
672}
673
674int kbd_mouse_is_absolute(void)
675{
676 if (!qemu_put_mouse_event_current)
677 return 0;
678
679 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
680}
681
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700682void do_info_mice(Monitor *mon)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800683{
684 QEMUPutMouseEntry *cursor;
685 int index = 0;
686
687 if (!qemu_put_mouse_event_head) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700688 monitor_printf(mon, "No mouse devices connected\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800689 return;
690 }
691
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700692 monitor_printf(mon, "Mouse devices available:\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800693 cursor = qemu_put_mouse_event_head;
694 while (cursor != NULL) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700695 monitor_printf(mon, "%c Mouse #%d: %s\n",
696 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
697 index, cursor->qemu_put_mouse_event_name);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800698 index++;
699 cursor = cursor->next;
700 }
701}
702
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700703void do_mouse_set(Monitor *mon, int index)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800704{
705 QEMUPutMouseEntry *cursor;
706 int i = 0;
707
708 if (!qemu_put_mouse_event_head) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700709 monitor_printf(mon, "No mouse devices connected\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800710 return;
711 }
712
713 cursor = qemu_put_mouse_event_head;
714 while (cursor != NULL && index != i) {
715 i++;
716 cursor = cursor->next;
717 }
718
719 if (cursor != NULL)
720 qemu_put_mouse_event_current = cursor;
721 else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700722 monitor_printf(mon, "Mouse at given index not found\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800723}
724
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -0700725/***********************************************************/
726/* real time host monotonic timer */
727
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800728/* compute with 96 bit intermediate result: (a*b)/c */
729uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
730{
731 union {
732 uint64_t ll;
733 struct {
David 'Digit' Turner20894ae2010-05-10 17:07:36 -0700734#ifdef HOST_WORDS_BIGENDIAN
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800735 uint32_t high, low;
736#else
737 uint32_t low, high;
738#endif
739 } l;
740 } u, res;
741 uint64_t rl, rh;
742
743 u.ll = a;
744 rl = (uint64_t)u.l.low * (uint64_t)b;
745 rh = (uint64_t)u.l.high * (uint64_t)b;
746 rh += (rl >> 32);
747 res.l.high = rh / c;
748 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
749 return res.ll;
750}
751
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800752/***********************************************************/
753/* host time/date access */
754void qemu_get_timedate(struct tm *tm, int offset)
755{
756 time_t ti;
757 struct tm *ret;
758
759 time(&ti);
760 ti += offset;
761 if (rtc_date_offset == -1) {
762 if (rtc_utc)
763 ret = gmtime(&ti);
764 else
765 ret = localtime(&ti);
766 } else {
767 ti -= rtc_date_offset;
768 ret = gmtime(&ti);
769 }
770
771 memcpy(tm, ret, sizeof(struct tm));
772}
773
774int qemu_timedate_diff(struct tm *tm)
775{
776 time_t seconds;
777
778 if (rtc_date_offset == -1)
779 if (rtc_utc)
780 seconds = mktimegm(tm);
781 else
782 seconds = mktime(tm);
783 else
784 seconds = mktimegm(tm) + rtc_date_offset;
785
786 return seconds - time(NULL);
787}
788
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800789#ifdef _WIN32
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700790static void socket_cleanup(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800791{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700792 WSACleanup();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800793}
794
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700795static int socket_init(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800796{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700797 WSADATA Data;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800798 int ret, err;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800799
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700800 ret = WSAStartup(MAKEWORD(2,2), &Data);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800801 if (ret != 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700802 err = WSAGetLastError();
803 fprintf(stderr, "WSAStartup: %d\n", err);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800804 return -1;
805 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700806 atexit(socket_cleanup);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800807 return 0;
808}
809#endif
810
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700811int get_param_value(char *buf, int buf_size,
812 const char *tag, const char *str)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800813{
814 const char *p;
815 char option[128];
816
817 p = str;
818 for(;;) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700819 p = get_opt_name(option, sizeof(option), p, '=');
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800820 if (*p != '=')
821 break;
822 p++;
823 if (!strcmp(tag, option)) {
824 (void)get_opt_value(buf, buf_size, p);
825 return strlen(buf);
826 } else {
827 p = get_opt_value(NULL, 0, p);
828 }
829 if (*p != ',')
830 break;
831 p++;
832 }
833 return 0;
834}
835
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700836int check_params(char *buf, int buf_size,
837 const char * const *params, const char *str)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800838{
839 const char *p;
840 int i;
841
842 p = str;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700843 while (*p != '\0') {
844 p = get_opt_name(buf, buf_size, p, '=');
845 if (*p != '=') {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800846 return -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700847 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800848 p++;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700849 for (i = 0; params[i] != NULL; i++) {
850 if (!strcmp(params[i], buf)) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800851 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700852 }
853 }
854 if (params[i] == NULL) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800855 return -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700856 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800857 p = get_opt_value(NULL, 0, p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700858 if (*p != ',') {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800859 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700860 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800861 p++;
862 }
863 return 0;
864}
865
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700866/***********************************************************/
867/* Bluetooth support */
868static int nb_hcis;
869static int cur_hci;
870static struct HCIInfo *hci_table[MAX_NICS];
871
872static struct bt_vlan_s {
873 struct bt_scatternet_s net;
874 int id;
875 struct bt_vlan_s *next;
876} *first_bt_vlan;
877
878/* find or alloc a new bluetooth "VLAN" */
879static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800880{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700881 struct bt_vlan_s **pvlan, *vlan;
882 for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
883 if (vlan->id == id)
884 return &vlan->net;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800885 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700886 vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
887 vlan->id = id;
888 pvlan = &first_bt_vlan;
889 while (*pvlan != NULL)
890 pvlan = &(*pvlan)->next;
891 *pvlan = vlan;
892 return &vlan->net;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800893}
894
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700895static void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800896{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800897}
898
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700899static int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800900{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700901 return -ENOTSUP;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800902}
903
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700904static struct HCIInfo null_hci = {
905 .cmd_send = null_hci_send,
906 .sco_send = null_hci_send,
907 .acl_send = null_hci_send,
908 .bdaddr_set = null_hci_addr_set,
909};
910
911struct HCIInfo *qemu_next_hci(void)
912{
913 if (cur_hci == nb_hcis)
914 return &null_hci;
915
916 return hci_table[cur_hci++];
917}
918
919static struct HCIInfo *hci_init(const char *str)
920{
921 char *endp;
922 struct bt_scatternet_s *vlan = 0;
923
924 if (!strcmp(str, "null"))
925 /* null */
926 return &null_hci;
927 else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
928 /* host[:hciN] */
929 return bt_host_hci(str[4] ? str + 5 : "hci0");
930 else if (!strncmp(str, "hci", 3)) {
931 /* hci[,vlan=n] */
932 if (str[3]) {
933 if (!strncmp(str + 3, ",vlan=", 6)) {
934 vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
935 if (*endp)
936 vlan = 0;
937 }
938 } else
939 vlan = qemu_find_bt_vlan(0);
940 if (vlan)
941 return bt_new_hci(vlan);
942 }
943
944 fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
945
946 return 0;
947}
948
949static int bt_hci_parse(const char *str)
950{
951 struct HCIInfo *hci;
952 bdaddr_t bdaddr;
953
954 if (nb_hcis >= MAX_NICS) {
955 fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
956 return -1;
957 }
958
959 hci = hci_init(str);
960 if (!hci)
961 return -1;
962
963 bdaddr.b[0] = 0x52;
964 bdaddr.b[1] = 0x54;
965 bdaddr.b[2] = 0x00;
966 bdaddr.b[3] = 0x12;
967 bdaddr.b[4] = 0x34;
968 bdaddr.b[5] = 0x56 + nb_hcis;
969 hci->bdaddr_set(hci, bdaddr.b);
970
971 hci_table[nb_hcis++] = hci;
972
973 return 0;
974}
975
976static void bt_vhci_add(int vlan_id)
977{
978 struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
979
980 if (!vlan->slave)
981 fprintf(stderr, "qemu: warning: adding a VHCI to "
982 "an empty scatternet %i\n", vlan_id);
983
984 bt_vhci_init(bt_new_hci(vlan));
985}
986
987static struct bt_device_s *bt_device_add(const char *opt)
988{
989 struct bt_scatternet_s *vlan;
990 int vlan_id = 0;
991 char *endp = strstr(opt, ",vlan=");
992 int len = (endp ? endp - opt : strlen(opt)) + 1;
993 char devname[10];
994
995 pstrcpy(devname, MIN(sizeof(devname), len), opt);
996
997 if (endp) {
998 vlan_id = strtol(endp + 6, &endp, 0);
999 if (*endp) {
1000 fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
1001 return 0;
1002 }
1003 }
1004
1005 vlan = qemu_find_bt_vlan(vlan_id);
1006
1007 if (!vlan->slave)
1008 fprintf(stderr, "qemu: warning: adding a slave device to "
1009 "an empty scatternet %i\n", vlan_id);
1010
1011 if (!strcmp(devname, "keyboard"))
1012 return bt_keyboard_init(vlan);
1013
1014 fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
1015 return 0;
1016}
1017
1018static int bt_parse(const char *opt)
1019{
1020 const char *endp, *p;
1021 int vlan;
1022
1023 if (strstart(opt, "hci", &endp)) {
1024 if (!*endp || *endp == ',') {
1025 if (*endp)
1026 if (!strstart(endp, ",vlan=", 0))
1027 opt = endp + 1;
1028
1029 return bt_hci_parse(opt);
1030 }
1031 } else if (strstart(opt, "vhci", &endp)) {
1032 if (!*endp || *endp == ',') {
1033 if (*endp) {
1034 if (strstart(endp, ",vlan=", &p)) {
1035 vlan = strtol(p, (char **) &endp, 0);
1036 if (*endp) {
1037 fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
1038 return 1;
1039 }
1040 } else {
1041 fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
1042 return 1;
1043 }
1044 } else
1045 vlan = 0;
1046
1047 bt_vhci_add(vlan);
1048 return 0;
1049 }
1050 } else if (strstart(opt, "device:", &endp))
1051 return !bt_device_add(endp);
1052
1053 fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
1054 return 1;
1055}
1056
1057/***********************************************************/
1058/* QEMU Block devices */
1059
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001060#define HD_ALIAS "index=%d,media=disk"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001061#define CDROM_ALIAS "index=2,media=cdrom"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001062#define FD_ALIAS "index=%d,if=floppy"
1063#define PFLASH_ALIAS "if=pflash"
1064#define MTD_ALIAS "if=mtd"
1065#define SD_ALIAS "index=0,if=sd"
1066
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001067static int drive_opt_get_free_idx(void)
1068{
1069 int index;
1070
1071 for (index = 0; index < MAX_DRIVES; index++)
1072 if (!drives_opt[index].used) {
1073 drives_opt[index].used = 1;
1074 return index;
1075 }
1076
1077 return -1;
1078}
1079
1080static int drive_get_free_idx(void)
1081{
1082 int index;
1083
1084 for (index = 0; index < MAX_DRIVES; index++)
1085 if (!drives_table[index].used) {
1086 drives_table[index].used = 1;
1087 return index;
1088 }
1089
1090 return -1;
1091}
1092
1093int drive_add(const char *file, const char *fmt, ...)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001094{
1095 va_list ap;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001096 int index = drive_opt_get_free_idx();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001097
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001098 if (nb_drives_opt >= MAX_DRIVES || index == -1) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001099 fprintf(stderr, "qemu: too many drives\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001100 return -1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001101 }
1102
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001103 drives_opt[index].file = file;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001104 va_start(ap, fmt);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001105 vsnprintf(drives_opt[index].opt,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001106 sizeof(drives_opt[0].opt), fmt, ap);
1107 va_end(ap);
1108
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001109 nb_drives_opt++;
1110 return index;
1111}
1112
1113void drive_remove(int index)
1114{
1115 drives_opt[index].used = 0;
1116 nb_drives_opt--;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001117}
1118
1119int drive_get_index(BlockInterfaceType type, int bus, int unit)
1120{
1121 int index;
1122
1123 /* seek interface, bus and unit */
1124
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001125 for (index = 0; index < MAX_DRIVES; index++)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001126 if (drives_table[index].type == type &&
1127 drives_table[index].bus == bus &&
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001128 drives_table[index].unit == unit &&
1129 drives_table[index].used)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001130 return index;
1131
1132 return -1;
1133}
1134
1135int drive_get_max_bus(BlockInterfaceType type)
1136{
1137 int max_bus;
1138 int index;
1139
1140 max_bus = -1;
1141 for (index = 0; index < nb_drives; index++) {
1142 if(drives_table[index].type == type &&
1143 drives_table[index].bus > max_bus)
1144 max_bus = drives_table[index].bus;
1145 }
1146 return max_bus;
1147}
1148
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001149const char *drive_get_serial(BlockDriverState *bdrv)
1150{
1151 int index;
1152
1153 for (index = 0; index < nb_drives; index++)
1154 if (drives_table[index].bdrv == bdrv)
1155 return drives_table[index].serial;
1156
1157 return "\0";
1158}
1159
1160BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
1161{
1162 int index;
1163
1164 for (index = 0; index < nb_drives; index++)
1165 if (drives_table[index].bdrv == bdrv)
1166 return drives_table[index].onerror;
1167
1168 return BLOCK_ERR_STOP_ENOSPC;
1169}
1170
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001171static void bdrv_format_print(void *opaque, const char *name)
1172{
1173 fprintf(stderr, " %s", name);
1174}
1175
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001176void drive_uninit(BlockDriverState *bdrv)
1177{
1178 int i;
1179
1180 for (i = 0; i < MAX_DRIVES; i++)
1181 if (drives_table[i].bdrv == bdrv) {
1182 drives_table[i].bdrv = NULL;
1183 drives_table[i].used = 0;
1184 drive_remove(drives_table[i].drive_opt_idx);
1185 nb_drives--;
1186 break;
1187 }
1188}
1189
1190int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001191{
1192 char buf[128];
1193 char file[1024];
1194 char devname[128];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001195 char serial[21];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001196 const char *mediastr = "";
1197 BlockInterfaceType type;
1198 enum { MEDIA_DISK, MEDIA_CDROM } media;
1199 int bus_id, unit_id;
1200 int cyls, heads, secs, translation;
1201 BlockDriverState *bdrv;
1202 BlockDriver *drv = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001203 QEMUMachine *machine = opaque;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001204 int max_devs;
1205 int index;
1206 int cache;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001207 int bdrv_flags, onerror;
1208 int drives_table_idx;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001209 char *str = arg->opt;
1210 static const char * const params[] = { "bus", "unit", "if", "index",
1211 "cyls", "heads", "secs", "trans",
1212 "media", "snapshot", "file",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001213 "cache", "format", "serial", "werror",
1214 NULL };
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001215
1216 if (check_params(buf, sizeof(buf), params, str) < 0) {
1217 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
1218 buf, str);
1219 return -1;
1220 }
1221
1222 file[0] = 0;
1223 cyls = heads = secs = 0;
1224 bus_id = 0;
1225 unit_id = -1;
1226 translation = BIOS_ATA_TRANSLATION_AUTO;
1227 index = -1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001228 cache = 3;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001229
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001230 if (machine->use_scsi) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001231 type = IF_SCSI;
1232 max_devs = MAX_SCSI_DEVS;
1233 pstrcpy(devname, sizeof(devname), "scsi");
1234 } else {
1235 type = IF_IDE;
1236 max_devs = MAX_IDE_DEVS;
1237 pstrcpy(devname, sizeof(devname), "ide");
1238 }
1239 media = MEDIA_DISK;
1240
1241 /* extract parameters */
1242
1243 if (get_param_value(buf, sizeof(buf), "bus", str)) {
1244 bus_id = strtol(buf, NULL, 0);
1245 if (bus_id < 0) {
1246 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
1247 return -1;
1248 }
1249 }
1250
1251 if (get_param_value(buf, sizeof(buf), "unit", str)) {
1252 unit_id = strtol(buf, NULL, 0);
1253 if (unit_id < 0) {
1254 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
1255 return -1;
1256 }
1257 }
1258
1259 if (get_param_value(buf, sizeof(buf), "if", str)) {
1260 pstrcpy(devname, sizeof(devname), buf);
1261 if (!strcmp(buf, "ide")) {
1262 type = IF_IDE;
1263 max_devs = MAX_IDE_DEVS;
1264 } else if (!strcmp(buf, "scsi")) {
1265 type = IF_SCSI;
1266 max_devs = MAX_SCSI_DEVS;
1267 } else if (!strcmp(buf, "floppy")) {
1268 type = IF_FLOPPY;
1269 max_devs = 0;
1270 } else if (!strcmp(buf, "pflash")) {
1271 type = IF_PFLASH;
1272 max_devs = 0;
1273 } else if (!strcmp(buf, "mtd")) {
1274 type = IF_MTD;
1275 max_devs = 0;
1276 } else if (!strcmp(buf, "sd")) {
1277 type = IF_SD;
1278 max_devs = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001279 } else if (!strcmp(buf, "virtio")) {
1280 type = IF_VIRTIO;
1281 max_devs = 0;
1282 } else if (!strcmp(buf, "xen")) {
1283 type = IF_XEN;
1284 max_devs = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001285 } else {
1286 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
1287 return -1;
1288 }
1289 }
1290
1291 if (get_param_value(buf, sizeof(buf), "index", str)) {
1292 index = strtol(buf, NULL, 0);
1293 if (index < 0) {
1294 fprintf(stderr, "qemu: '%s' invalid index\n", str);
1295 return -1;
1296 }
1297 }
1298
1299 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
1300 cyls = strtol(buf, NULL, 0);
1301 }
1302
1303 if (get_param_value(buf, sizeof(buf), "heads", str)) {
1304 heads = strtol(buf, NULL, 0);
1305 }
1306
1307 if (get_param_value(buf, sizeof(buf), "secs", str)) {
1308 secs = strtol(buf, NULL, 0);
1309 }
1310
1311 if (cyls || heads || secs) {
1312 if (cyls < 1 || cyls > 16383) {
1313 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
1314 return -1;
1315 }
1316 if (heads < 1 || heads > 16) {
1317 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
1318 return -1;
1319 }
1320 if (secs < 1 || secs > 63) {
1321 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
1322 return -1;
1323 }
1324 }
1325
1326 if (get_param_value(buf, sizeof(buf), "trans", str)) {
1327 if (!cyls) {
1328 fprintf(stderr,
1329 "qemu: '%s' trans must be used with cyls,heads and secs\n",
1330 str);
1331 return -1;
1332 }
1333 if (!strcmp(buf, "none"))
1334 translation = BIOS_ATA_TRANSLATION_NONE;
1335 else if (!strcmp(buf, "lba"))
1336 translation = BIOS_ATA_TRANSLATION_LBA;
1337 else if (!strcmp(buf, "auto"))
1338 translation = BIOS_ATA_TRANSLATION_AUTO;
1339 else {
1340 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
1341 return -1;
1342 }
1343 }
1344
1345 if (get_param_value(buf, sizeof(buf), "media", str)) {
1346 if (!strcmp(buf, "disk")) {
1347 media = MEDIA_DISK;
1348 } else if (!strcmp(buf, "cdrom")) {
1349 if (cyls || secs || heads) {
1350 fprintf(stderr,
1351 "qemu: '%s' invalid physical CHS format\n", str);
1352 return -1;
1353 }
1354 media = MEDIA_CDROM;
1355 } else {
1356 fprintf(stderr, "qemu: '%s' invalid media\n", str);
1357 return -1;
1358 }
1359 }
1360
1361 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
1362 if (!strcmp(buf, "on"))
1363 snapshot = 1;
1364 else if (!strcmp(buf, "off"))
1365 snapshot = 0;
1366 else {
1367 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
1368 return -1;
1369 }
1370 }
1371
1372 if (get_param_value(buf, sizeof(buf), "cache", str)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001373 if (!strcmp(buf, "off") || !strcmp(buf, "none"))
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001374 cache = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001375 else if (!strcmp(buf, "writethrough"))
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001376 cache = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001377 else if (!strcmp(buf, "writeback"))
1378 cache = 2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001379 else {
1380 fprintf(stderr, "qemu: invalid cache option\n");
1381 return -1;
1382 }
1383 }
1384
1385 if (get_param_value(buf, sizeof(buf), "format", str)) {
1386 if (strcmp(buf, "?") == 0) {
1387 fprintf(stderr, "qemu: Supported formats:");
1388 bdrv_iterate_format(bdrv_format_print, NULL);
1389 fprintf(stderr, "\n");
1390 return -1;
1391 }
1392 drv = bdrv_find_format(buf);
1393 if (!drv) {
1394 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
1395 return -1;
1396 }
1397 }
1398
1399 if (arg->file == NULL)
1400 get_param_value(file, sizeof(file), "file", str);
1401 else
1402 pstrcpy(file, sizeof(file), arg->file);
1403
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001404 if (!get_param_value(serial, sizeof(serial), "serial", str))
1405 memset(serial, 0, sizeof(serial));
1406
1407 onerror = BLOCK_ERR_STOP_ENOSPC;
1408 if (get_param_value(buf, sizeof(serial), "werror", str)) {
1409 if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
1410 fprintf(stderr, "werror is no supported by this format\n");
1411 return -1;
1412 }
1413 if (!strcmp(buf, "ignore"))
1414 onerror = BLOCK_ERR_IGNORE;
1415 else if (!strcmp(buf, "enospc"))
1416 onerror = BLOCK_ERR_STOP_ENOSPC;
1417 else if (!strcmp(buf, "stop"))
1418 onerror = BLOCK_ERR_STOP_ANY;
1419 else if (!strcmp(buf, "report"))
1420 onerror = BLOCK_ERR_REPORT;
1421 else {
1422 fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
1423 return -1;
1424 }
1425 }
1426
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001427 /* compute bus and unit according index */
1428
1429 if (index != -1) {
1430 if (bus_id != 0 || unit_id != -1) {
1431 fprintf(stderr,
1432 "qemu: '%s' index cannot be used with bus and unit\n", str);
1433 return -1;
1434 }
1435 if (max_devs == 0)
1436 {
1437 unit_id = index;
1438 bus_id = 0;
1439 } else {
1440 unit_id = index % max_devs;
1441 bus_id = index / max_devs;
1442 }
1443 }
1444
1445 /* if user doesn't specify a unit_id,
1446 * try to find the first free
1447 */
1448
1449 if (unit_id == -1) {
1450 unit_id = 0;
1451 while (drive_get_index(type, bus_id, unit_id) != -1) {
1452 unit_id++;
1453 if (max_devs && unit_id >= max_devs) {
1454 unit_id -= max_devs;
1455 bus_id++;
1456 }
1457 }
1458 }
1459
1460 /* check unit id */
1461
1462 if (max_devs && unit_id >= max_devs) {
1463 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
1464 str, unit_id, max_devs - 1);
1465 return -1;
1466 }
1467
1468 /*
1469 * ignore multiple definitions
1470 */
1471
1472 if (drive_get_index(type, bus_id, unit_id) != -1)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001473 return -2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001474
1475 /* init */
1476
1477 if (type == IF_IDE || type == IF_SCSI)
1478 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
1479 if (max_devs)
1480 snprintf(buf, sizeof(buf), "%s%i%s%i",
1481 devname, bus_id, mediastr, unit_id);
1482 else
1483 snprintf(buf, sizeof(buf), "%s%s%i",
1484 devname, mediastr, unit_id);
1485 bdrv = bdrv_new(buf);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001486 drives_table_idx = drive_get_free_idx();
1487 drives_table[drives_table_idx].bdrv = bdrv;
1488 drives_table[drives_table_idx].type = type;
1489 drives_table[drives_table_idx].bus = bus_id;
1490 drives_table[drives_table_idx].unit = unit_id;
1491 drives_table[drives_table_idx].onerror = onerror;
1492 drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
1493 strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001494 nb_drives++;
1495
1496 switch(type) {
1497 case IF_IDE:
1498 case IF_SCSI:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001499 case IF_XEN:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001500 switch(media) {
1501 case MEDIA_DISK:
1502 if (cyls != 0) {
1503 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
1504 bdrv_set_translation_hint(bdrv, translation);
1505 }
1506 break;
1507 case MEDIA_CDROM:
1508 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
1509 break;
1510 }
1511 break;
1512 case IF_SD:
1513 /* FIXME: This isn't really a floppy, but it's a reasonable
1514 approximation. */
1515 case IF_FLOPPY:
1516 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
1517 break;
1518 case IF_PFLASH:
1519 case IF_MTD:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001520 case IF_VIRTIO:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001521 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001522 case IF_COUNT:
1523 abort();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001524 }
1525 if (!file[0])
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001526 return -2;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001527 bdrv_flags = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001528 if (snapshot) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001529 bdrv_flags |= BDRV_O_SNAPSHOT;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001530 cache = 2; /* always use write-back with snapshot */
1531 }
1532 if (cache == 0) /* no caching */
1533 bdrv_flags |= BDRV_O_NOCACHE;
1534 else if (cache == 2) /* write-back */
1535 bdrv_flags |= BDRV_O_CACHE_WB;
1536 else if (cache == 3) /* not specified */
1537 bdrv_flags |= BDRV_O_CACHE_DEF;
1538 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001539 fprintf(stderr, "qemu: could not open disk image %s\n",
1540 file);
1541 return -1;
1542 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001543 if (bdrv_key_required(bdrv))
1544 autostart = 0;
1545 return drives_table_idx;
1546}
1547
1548static void numa_add(const char *optarg)
1549{
1550 char option[128];
1551 char *endptr;
1552 unsigned long long value, endvalue;
1553 int nodenr;
1554
1555 optarg = get_opt_name(option, 128, optarg, ',') + 1;
1556 if (!strcmp(option, "node")) {
1557 if (get_param_value(option, 128, "nodeid", optarg) == 0) {
1558 nodenr = nb_numa_nodes;
1559 } else {
1560 nodenr = strtoull(option, NULL, 10);
1561 }
1562
1563 if (get_param_value(option, 128, "mem", optarg) == 0) {
1564 node_mem[nodenr] = 0;
1565 } else {
1566 value = strtoull(option, &endptr, 0);
1567 switch (*endptr) {
1568 case 0: case 'M': case 'm':
1569 value <<= 20;
1570 break;
1571 case 'G': case 'g':
1572 value <<= 30;
1573 break;
1574 }
1575 node_mem[nodenr] = value;
1576 }
1577 if (get_param_value(option, 128, "cpus", optarg) == 0) {
1578 node_cpumask[nodenr] = 0;
1579 } else {
1580 value = strtoull(option, &endptr, 10);
1581 if (value >= 64) {
1582 value = 63;
1583 fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
1584 } else {
1585 if (*endptr == '-') {
1586 endvalue = strtoull(endptr+1, &endptr, 10);
1587 if (endvalue >= 63) {
1588 endvalue = 62;
1589 fprintf(stderr,
1590 "only 63 CPUs in NUMA mode supported.\n");
1591 }
1592 value = (1 << (endvalue + 1)) - (1 << value);
1593 } else {
1594 value = 1 << value;
1595 }
1596 }
1597 node_cpumask[nodenr] = value;
1598 }
1599 nb_numa_nodes++;
1600 }
1601 return;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001602}
1603
1604/***********************************************************/
1605/* USB devices */
1606
1607static USBPort *used_usb_ports;
1608static USBPort *free_usb_ports;
1609
1610/* ??? Maybe change this to register a hub to keep track of the topology. */
1611void qemu_register_usb_port(USBPort *port, void *opaque, int index,
1612 usb_attachfn attach)
1613{
1614 port->opaque = opaque;
1615 port->index = index;
1616 port->attach = attach;
1617 port->next = free_usb_ports;
1618 free_usb_ports = port;
1619}
1620
1621int usb_device_add_dev(USBDevice *dev)
1622{
1623 USBPort *port;
1624
1625 /* Find a USB port to add the device to. */
1626 port = free_usb_ports;
1627 if (!port->next) {
1628 USBDevice *hub;
1629
1630 /* Create a new hub and chain it on. */
1631 free_usb_ports = NULL;
1632 port->next = used_usb_ports;
1633 used_usb_ports = port;
1634
1635 hub = usb_hub_init(VM_USB_HUB_SIZE);
1636 usb_attach(port, hub);
1637 port = free_usb_ports;
1638 }
1639
1640 free_usb_ports = port->next;
1641 port->next = used_usb_ports;
1642 used_usb_ports = port;
1643 usb_attach(port, dev);
1644 return 0;
1645}
1646
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001647static void usb_msd_password_cb(void *opaque, int err)
1648{
1649 USBDevice *dev = opaque;
1650
1651 if (!err)
1652 usb_device_add_dev(dev);
1653 else
1654 dev->handle_destroy(dev);
1655}
1656
1657static int usb_device_add(const char *devname, int is_hotplug)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001658{
1659 const char *p;
1660 USBDevice *dev;
1661
1662 if (!free_usb_ports)
1663 return -1;
1664
1665 if (strstart(devname, "host:", &p)) {
1666 dev = usb_host_device_open(p);
1667 } else if (!strcmp(devname, "mouse")) {
1668 dev = usb_mouse_init();
1669 } else if (!strcmp(devname, "tablet")) {
1670 dev = usb_tablet_init();
1671 } else if (!strcmp(devname, "keyboard")) {
1672 dev = usb_keyboard_init();
1673 } else if (strstart(devname, "disk:", &p)) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001674 BlockDriverState *bs;
1675
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001676 dev = usb_msd_init(p);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001677 if (!dev)
1678 return -1;
1679 bs = usb_msd_get_bdrv(dev);
1680 if (bdrv_key_required(bs)) {
1681 autostart = 0;
1682 if (is_hotplug) {
1683 monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
1684 dev);
1685 return 0;
1686 }
1687 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001688 } else if (!strcmp(devname, "wacom-tablet")) {
1689 dev = usb_wacom_init();
1690 } else if (strstart(devname, "serial:", &p)) {
1691 dev = usb_serial_init(p);
1692#ifdef CONFIG_BRLAPI
1693 } else if (!strcmp(devname, "braille")) {
1694 dev = usb_baum_init();
1695#endif
1696 } else if (strstart(devname, "net:", &p)) {
1697 int nic = nb_nics;
1698
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001699 if (net_client_init(NULL, "nic", p) < 0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001700 return -1;
1701 nd_table[nic].model = "usb";
1702 dev = usb_net_init(&nd_table[nic]);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001703 } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
1704 dev = usb_bt_init(devname[2] ? hci_init(p) :
1705 bt_new_hci(qemu_find_bt_vlan(0)));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001706 } else {
1707 return -1;
1708 }
1709 if (!dev)
1710 return -1;
1711
1712 return usb_device_add_dev(dev);
1713}
1714
1715int usb_device_del_addr(int bus_num, int addr)
1716{
1717 USBPort *port;
1718 USBPort **lastp;
1719 USBDevice *dev;
1720
1721 if (!used_usb_ports)
1722 return -1;
1723
1724 if (bus_num != 0)
1725 return -1;
1726
1727 lastp = &used_usb_ports;
1728 port = used_usb_ports;
1729 while (port && port->dev->addr != addr) {
1730 lastp = &port->next;
1731 port = port->next;
1732 }
1733
1734 if (!port)
1735 return -1;
1736
1737 dev = port->dev;
1738 *lastp = port->next;
1739 usb_attach(port, NULL);
1740 dev->handle_destroy(dev);
1741 port->next = free_usb_ports;
1742 free_usb_ports = port;
1743 return 0;
1744}
1745
1746static int usb_device_del(const char *devname)
1747{
1748 int bus_num, addr;
1749 const char *p;
1750
1751 if (strstart(devname, "host:", &p))
1752 return usb_host_device_close(p);
1753
1754 if (!used_usb_ports)
1755 return -1;
1756
1757 p = strchr(devname, '.');
1758 if (!p)
1759 return -1;
1760 bus_num = strtoul(devname, NULL, 0);
1761 addr = strtoul(p + 1, NULL, 0);
1762
1763 return usb_device_del_addr(bus_num, addr);
1764}
1765
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001766void do_usb_add(Monitor *mon, const char *devname)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001767{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001768 usb_device_add(devname, 1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001769}
1770
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001771void do_usb_del(Monitor *mon, const char *devname)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001772{
1773 usb_device_del(devname);
1774}
1775
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001776void usb_info(Monitor *mon)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001777{
1778 USBDevice *dev;
1779 USBPort *port;
1780 const char *speed_str;
1781
1782 if (!usb_enabled) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001783 monitor_printf(mon, "USB support not enabled\n");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001784 return;
1785 }
1786
1787 for (port = used_usb_ports; port; port = port->next) {
1788 dev = port->dev;
1789 if (!dev)
1790 continue;
1791 switch(dev->speed) {
1792 case USB_SPEED_LOW:
1793 speed_str = "1.5";
1794 break;
1795 case USB_SPEED_FULL:
1796 speed_str = "12";
1797 break;
1798 case USB_SPEED_HIGH:
1799 speed_str = "480";
1800 break;
1801 default:
1802 speed_str = "?";
1803 break;
1804 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001805 monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
1806 0, dev->addr, speed_str, dev->devname);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001807 }
1808}
1809
1810/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001811/* PCMCIA/Cardbus */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001812
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001813static struct pcmcia_socket_entry_s {
1814 PCMCIASocket *socket;
1815 struct pcmcia_socket_entry_s *next;
1816} *pcmcia_sockets = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001817
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001818void pcmcia_socket_register(PCMCIASocket *socket)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001819{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001820 struct pcmcia_socket_entry_s *entry;
1821
1822 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
1823 entry->socket = socket;
1824 entry->next = pcmcia_sockets;
1825 pcmcia_sockets = entry;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001826}
1827
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001828void pcmcia_socket_unregister(PCMCIASocket *socket)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001829{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001830 struct pcmcia_socket_entry_s *entry, **ptr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001831
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001832 ptr = &pcmcia_sockets;
1833 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
1834 if (entry->socket == socket) {
1835 *ptr = entry->next;
1836 qemu_free(entry);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001837 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001838}
1839
1840void pcmcia_info(Monitor *mon)
1841{
1842 struct pcmcia_socket_entry_s *iter;
1843
1844 if (!pcmcia_sockets)
1845 monitor_printf(mon, "No PCMCIA sockets\n");
1846
1847 for (iter = pcmcia_sockets; iter; iter = iter->next)
1848 monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
1849 iter->socket->attached ? iter->socket->card_string :
1850 "Empty");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001851}
1852
1853/***********************************************************/
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001854/* register display */
1855
1856struct DisplayAllocator default_allocator = {
1857 defaultallocator_create_displaysurface,
1858 defaultallocator_resize_displaysurface,
1859 defaultallocator_free_displaysurface
1860};
1861
1862void register_displaystate(DisplayState *ds)
1863{
1864 DisplayState **s;
1865 s = &display_state;
1866 while (*s != NULL)
1867 s = &(*s)->next;
1868 ds->next = NULL;
1869 *s = ds;
1870}
1871
1872DisplayState *get_displaystate(void)
1873{
1874 return display_state;
1875}
1876
1877DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
1878{
1879 if(ds->allocator == &default_allocator) ds->allocator = da;
1880 return ds->allocator;
1881}
1882
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001883/* dumb display */
1884
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001885static void dumb_display_init(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001886{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001887 DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
1888 ds->allocator = &default_allocator;
1889 ds->surface = qemu_create_displaysurface(ds, 640, 480);
1890 register_displaystate(ds);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001891}
1892
1893/***********************************************************/
1894/* I/O handling */
1895
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001896typedef struct IOHandlerRecord {
1897 int fd;
1898 IOCanRWHandler *fd_read_poll;
1899 IOHandler *fd_read;
1900 IOHandler *fd_write;
1901 int deleted;
1902 void *opaque;
1903 /* temporary data */
1904 struct pollfd *ufd;
1905 struct IOHandlerRecord *next;
1906} IOHandlerRecord;
1907
1908static IOHandlerRecord *first_io_handler;
1909
1910/* XXX: fd_read_poll should be suppressed, but an API change is
1911 necessary in the character devices to suppress fd_can_read(). */
1912int qemu_set_fd_handler2(int fd,
1913 IOCanRWHandler *fd_read_poll,
1914 IOHandler *fd_read,
1915 IOHandler *fd_write,
1916 void *opaque)
1917{
1918 IOHandlerRecord **pioh, *ioh;
1919
1920 if (!fd_read && !fd_write) {
1921 pioh = &first_io_handler;
1922 for(;;) {
1923 ioh = *pioh;
1924 if (ioh == NULL)
1925 break;
1926 if (ioh->fd == fd) {
1927 ioh->deleted = 1;
1928 break;
1929 }
1930 pioh = &ioh->next;
1931 }
1932 } else {
1933 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
1934 if (ioh->fd == fd)
1935 goto found;
1936 }
1937 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001938 ioh->next = first_io_handler;
1939 first_io_handler = ioh;
1940 found:
1941 ioh->fd = fd;
1942 ioh->fd_read_poll = fd_read_poll;
1943 ioh->fd_read = fd_read;
1944 ioh->fd_write = fd_write;
1945 ioh->opaque = opaque;
1946 ioh->deleted = 0;
1947 }
1948 return 0;
1949}
1950
1951int qemu_set_fd_handler(int fd,
1952 IOHandler *fd_read,
1953 IOHandler *fd_write,
1954 void *opaque)
1955{
1956 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
1957}
1958
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001959#ifdef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001960/***********************************************************/
1961/* Polling handling */
1962
1963typedef struct PollingEntry {
1964 PollingFunc *func;
1965 void *opaque;
1966 struct PollingEntry *next;
1967} PollingEntry;
1968
1969static PollingEntry *first_polling_entry;
1970
1971int qemu_add_polling_cb(PollingFunc *func, void *opaque)
1972{
1973 PollingEntry **ppe, *pe;
1974 pe = qemu_mallocz(sizeof(PollingEntry));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001975 pe->func = func;
1976 pe->opaque = opaque;
1977 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
1978 *ppe = pe;
1979 return 0;
1980}
1981
1982void qemu_del_polling_cb(PollingFunc *func, void *opaque)
1983{
1984 PollingEntry **ppe, *pe;
1985 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
1986 pe = *ppe;
1987 if (pe->func == func && pe->opaque == opaque) {
1988 *ppe = pe->next;
1989 qemu_free(pe);
1990 break;
1991 }
1992 }
1993}
1994
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001995/***********************************************************/
1996/* Wait objects support */
1997typedef struct WaitObjects {
1998 int num;
1999 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
2000 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
2001 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
2002} WaitObjects;
2003
2004static WaitObjects wait_objects = {0};
2005
2006int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2007{
2008 WaitObjects *w = &wait_objects;
2009
2010 if (w->num >= MAXIMUM_WAIT_OBJECTS)
2011 return -1;
2012 w->events[w->num] = handle;
2013 w->func[w->num] = func;
2014 w->opaque[w->num] = opaque;
2015 w->num++;
2016 return 0;
2017}
2018
2019void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
2020{
2021 int i, found;
2022 WaitObjects *w = &wait_objects;
2023
2024 found = 0;
2025 for (i = 0; i < w->num; i++) {
2026 if (w->events[i] == handle)
2027 found = 1;
2028 if (found) {
2029 w->events[i] = w->events[i + 1];
2030 w->func[i] = w->func[i + 1];
2031 w->opaque[i] = w->opaque[i + 1];
2032 }
2033 }
2034 if (found)
2035 w->num--;
2036}
2037#endif
2038
2039/***********************************************************/
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002040/* ram save/restore */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002041
2042static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
2043{
2044 int v;
2045
2046 v = qemu_get_byte(f);
2047 switch(v) {
2048 case 0:
2049 if (qemu_get_buffer(f, buf, len) != len)
2050 return -EIO;
2051 break;
2052 case 1:
2053 v = qemu_get_byte(f);
2054 memset(buf, v, len);
2055 break;
2056 default:
2057 return -EINVAL;
2058 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002059
2060 if (qemu_file_has_error(f))
2061 return -EIO;
2062
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002063 return 0;
2064}
2065
2066static int ram_load_v1(QEMUFile *f, void *opaque)
2067{
2068 int ret;
2069 ram_addr_t i;
2070
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002071 if (qemu_get_be32(f) != last_ram_offset)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002072 return -EINVAL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002073 for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
2074 ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002075 if (ret)
2076 return ret;
2077 }
2078 return 0;
2079}
2080
2081#define BDRV_HASH_BLOCK_SIZE 1024
2082#define IOBUF_SIZE 4096
2083#define RAM_CBLOCK_MAGIC 0xfabe
2084
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002085typedef struct RamDecompressState {
2086 z_stream zstream;
2087 QEMUFile *f;
2088 uint8_t buf[IOBUF_SIZE];
2089} RamDecompressState;
2090
2091static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
2092{
2093 int ret;
2094 memset(s, 0, sizeof(*s));
2095 s->f = f;
2096 ret = inflateInit(&s->zstream);
2097 if (ret != Z_OK)
2098 return -1;
2099 return 0;
2100}
2101
2102static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
2103{
2104 int ret, clen;
2105
2106 s->zstream.avail_out = len;
2107 s->zstream.next_out = buf;
2108 while (s->zstream.avail_out > 0) {
2109 if (s->zstream.avail_in == 0) {
2110 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
2111 return -1;
2112 clen = qemu_get_be16(s->f);
2113 if (clen > IOBUF_SIZE)
2114 return -1;
2115 qemu_get_buffer(s->f, s->buf, clen);
2116 s->zstream.avail_in = clen;
2117 s->zstream.next_in = s->buf;
2118 }
2119 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
2120 if (ret != Z_OK && ret != Z_STREAM_END) {
2121 return -1;
2122 }
2123 }
2124 return 0;
2125}
2126
2127static void ram_decompress_close(RamDecompressState *s)
2128{
2129 inflateEnd(&s->zstream);
2130}
2131
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002132#define RAM_SAVE_FLAG_FULL 0x01
2133#define RAM_SAVE_FLAG_COMPRESS 0x02
2134#define RAM_SAVE_FLAG_MEM_SIZE 0x04
2135#define RAM_SAVE_FLAG_PAGE 0x08
2136#define RAM_SAVE_FLAG_EOS 0x10
2137
2138static int is_dup_page(uint8_t *page, uint8_t ch)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002139{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002140 uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
2141 uint32_t *array = (uint32_t *)page;
2142 int i;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002143
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002144 for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
2145 if (array[i] != val)
2146 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002147 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002148
2149 return 1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002150}
2151
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002152static int ram_save_block(QEMUFile *f)
2153{
2154 static ram_addr_t current_addr = 0;
2155 ram_addr_t saved_addr = current_addr;
2156 ram_addr_t addr = 0;
2157 int found = 0;
2158
2159 while (addr < last_ram_offset) {
2160 if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
2161 uint8_t *p;
2162
2163 cpu_physical_memory_reset_dirty(current_addr,
2164 current_addr + TARGET_PAGE_SIZE,
2165 MIGRATION_DIRTY_FLAG);
2166
2167 p = qemu_get_ram_ptr(current_addr);
2168
2169 if (is_dup_page(p, *p)) {
2170 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
2171 qemu_put_byte(f, *p);
2172 } else {
2173 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
2174 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
2175 }
2176
2177 found = 1;
2178 break;
2179 }
2180 addr += TARGET_PAGE_SIZE;
2181 current_addr = (saved_addr + addr) % last_ram_offset;
2182 }
2183
2184 return found;
2185}
2186
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002187static uint64_t bytes_transferred;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002188
2189static ram_addr_t ram_save_remaining(void)
2190{
2191 ram_addr_t addr;
2192 ram_addr_t count = 0;
2193
2194 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2195 if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2196 count++;
2197 }
2198
2199 return count;
2200}
2201
2202uint64_t ram_bytes_remaining(void)
2203{
2204 return ram_save_remaining() * TARGET_PAGE_SIZE;
2205}
2206
2207uint64_t ram_bytes_transferred(void)
2208{
2209 return bytes_transferred;
2210}
2211
2212uint64_t ram_bytes_total(void)
2213{
2214 return last_ram_offset;
2215}
2216
2217static int ram_save_live(QEMUFile *f, int stage, void *opaque)
2218{
2219 ram_addr_t addr;
2220 uint64_t bytes_transferred_last;
2221 double bwidth = 0;
2222 uint64_t expected_time = 0;
2223
2224 if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
2225 qemu_file_set_error(f);
2226 return 0;
2227 }
2228
2229 if (stage == 1) {
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002230 bytes_transferred = 0;
2231
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002232 /* Make sure all dirty bits are set */
2233 for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
2234 if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
2235 cpu_physical_memory_set_dirty(addr);
2236 }
2237
2238 /* Enable dirty memory tracking */
2239 cpu_physical_memory_set_dirty_tracking(1);
2240
2241 qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
2242 }
2243
2244 bytes_transferred_last = bytes_transferred;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002245 bwidth = qemu_get_clock_ns(rt_clock);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002246
2247 while (!qemu_file_rate_limit(f)) {
2248 int ret;
2249
2250 ret = ram_save_block(f);
2251 bytes_transferred += ret * TARGET_PAGE_SIZE;
2252 if (ret == 0) /* no more blocks */
2253 break;
2254 }
2255
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002256 bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002257 bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
2258
2259 /* if we haven't transferred anything this round, force expected_time to a
2260 * a very high value, but without crashing */
2261 if (bwidth == 0)
2262 bwidth = 0.000001;
2263
2264 /* try transferring iterative blocks of memory */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002265 if (stage == 3) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002266 /* flush all remaining blocks regardless of rate limiting */
2267 while (ram_save_block(f) != 0) {
2268 bytes_transferred += TARGET_PAGE_SIZE;
2269 }
2270 cpu_physical_memory_set_dirty_tracking(0);
2271 }
2272
2273 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
2274
2275 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
2276
2277 return (stage == 2) && (expected_time <= migrate_max_downtime());
2278}
2279
2280static int ram_load_dead(QEMUFile *f, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002281{
2282 RamDecompressState s1, *s = &s1;
2283 uint8_t buf[10];
2284 ram_addr_t i;
2285
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002286 if (ram_decompress_open(s, f) < 0)
2287 return -EINVAL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002288 for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002289 if (ram_decompress_buf(s, buf, 1) < 0) {
2290 fprintf(stderr, "Error while reading ram block header\n");
2291 goto error;
2292 }
2293 if (buf[0] == 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002294 if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
2295 BDRV_HASH_BLOCK_SIZE) < 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002296 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
2297 goto error;
2298 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002299 } else {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002300 error:
2301 printf("Error block header\n");
2302 return -EINVAL;
2303 }
2304 }
2305 ram_decompress_close(s);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002306
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002307 return 0;
2308}
2309
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002310static int ram_load(QEMUFile *f, void *opaque, int version_id)
2311{
2312 ram_addr_t addr;
2313 int flags;
2314
2315 if (version_id == 1)
2316 return ram_load_v1(f, opaque);
2317
2318 if (version_id == 2) {
2319 if (qemu_get_be32(f) != last_ram_offset)
2320 return -EINVAL;
2321 return ram_load_dead(f, opaque);
2322 }
2323
2324 if (version_id != 3)
2325 return -EINVAL;
2326
2327 do {
2328 addr = qemu_get_be64(f);
2329
2330 flags = addr & ~TARGET_PAGE_MASK;
2331 addr &= TARGET_PAGE_MASK;
2332
2333 if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
2334 if (addr != last_ram_offset)
2335 return -EINVAL;
2336 }
2337
2338 if (flags & RAM_SAVE_FLAG_FULL) {
2339 if (ram_load_dead(f, opaque) < 0)
2340 return -EINVAL;
2341 }
2342
2343 if (flags & RAM_SAVE_FLAG_COMPRESS) {
2344 uint8_t ch = qemu_get_byte(f);
2345 memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
2346 } else if (flags & RAM_SAVE_FLAG_PAGE)
2347 qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
2348 } while (!(flags & RAM_SAVE_FLAG_EOS));
2349
2350 return 0;
2351}
2352
2353void qemu_service_io(void)
2354{
2355 qemu_notify_event();
2356}
2357
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002358/***********************************************************/
2359/* bottom halves (can be seen as timers which expire ASAP) */
2360
2361struct QEMUBH {
2362 QEMUBHFunc *cb;
2363 void *opaque;
2364 int scheduled;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002365 int idle;
2366 int deleted;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002367 QEMUBH *next;
2368};
2369
2370static QEMUBH *first_bh = NULL;
2371
2372QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
2373{
2374 QEMUBH *bh;
2375 bh = qemu_mallocz(sizeof(QEMUBH));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002376 bh->cb = cb;
2377 bh->opaque = opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002378 bh->next = first_bh;
2379 first_bh = bh;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002380 return bh;
2381}
2382
2383int qemu_bh_poll(void)
2384{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002385 QEMUBH *bh, **bhp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002386 int ret;
2387
2388 ret = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002389 for (bh = first_bh; bh; bh = bh->next) {
2390 if (!bh->deleted && bh->scheduled) {
2391 bh->scheduled = 0;
2392 if (!bh->idle)
2393 ret = 1;
2394 bh->idle = 0;
2395 bh->cb(bh->opaque);
2396 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002397 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002398
2399 /* remove deleted bhs */
2400 bhp = &first_bh;
2401 while (*bhp) {
2402 bh = *bhp;
2403 if (bh->deleted) {
2404 *bhp = bh->next;
2405 qemu_free(bh);
2406 } else
2407 bhp = &bh->next;
2408 }
2409
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002410 return ret;
2411}
2412
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002413void qemu_bh_schedule_idle(QEMUBH *bh)
2414{
2415 if (bh->scheduled)
2416 return;
2417 bh->scheduled = 1;
2418 bh->idle = 1;
2419}
2420
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002421void qemu_bh_schedule(QEMUBH *bh)
2422{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002423 if (bh->scheduled)
2424 return;
2425 bh->scheduled = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002426 bh->idle = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002427 /* stop the currently executing CPU to execute the BH ASAP */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002428 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002429}
2430
2431void qemu_bh_cancel(QEMUBH *bh)
2432{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002433 bh->scheduled = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002434}
2435
2436void qemu_bh_delete(QEMUBH *bh)
2437{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002438 bh->scheduled = 0;
2439 bh->deleted = 1;
2440}
2441
2442static void qemu_bh_update_timeout(int *timeout)
2443{
2444 QEMUBH *bh;
2445
2446 for (bh = first_bh; bh; bh = bh->next) {
2447 if (!bh->deleted && bh->scheduled) {
2448 if (bh->idle) {
2449 /* idle bottom halves will be polled at least
2450 * every 10ms */
2451 *timeout = MIN(10, *timeout);
2452 } else {
2453 /* non-idle bottom halves will be executed
2454 * immediately */
2455 *timeout = 0;
2456 break;
2457 }
2458 }
2459 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002460}
2461
2462/***********************************************************/
2463/* machine registration */
2464
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002465static QEMUMachine *first_machine = NULL;
2466QEMUMachine *current_machine = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002467
2468int qemu_register_machine(QEMUMachine *m)
2469{
2470 QEMUMachine **pm;
2471 pm = &first_machine;
2472 while (*pm != NULL)
2473 pm = &(*pm)->next;
2474 m->next = NULL;
2475 *pm = m;
2476 return 0;
2477}
2478
2479static QEMUMachine *find_machine(const char *name)
2480{
2481 QEMUMachine *m;
2482
2483 for(m = first_machine; m != NULL; m = m->next) {
2484 if (!strcmp(m->name, name))
2485 return m;
2486 }
2487 return NULL;
2488}
2489
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002490static QEMUMachine *find_default_machine(void)
2491{
2492 QEMUMachine *m;
2493
2494 for(m = first_machine; m != NULL; m = m->next) {
2495 if (m->is_default) {
2496 return m;
2497 }
2498 }
2499 return NULL;
2500}
2501
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002502/***********************************************************/
2503/* main execution loop */
2504
2505static void gui_update(void *opaque)
2506{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002507 uint64_t interval = GUI_REFRESH_INTERVAL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002508 DisplayState *ds = opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002509 DisplayChangeListener *dcl = ds->listeners;
2510
2511 dpy_refresh(ds);
2512
2513 while (dcl != NULL) {
2514 if (dcl->gui_timer_interval &&
2515 dcl->gui_timer_interval < interval)
2516 interval = dcl->gui_timer_interval;
2517 dcl = dcl->next;
2518 }
2519 qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
2520}
2521
2522static void nographic_update(void *opaque)
2523{
2524 uint64_t interval = GUI_REFRESH_INTERVAL;
2525
2526 qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002527}
2528
2529struct vm_change_state_entry {
2530 VMChangeStateHandler *cb;
2531 void *opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002532 QLIST_ENTRY (vm_change_state_entry) entries;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002533};
2534
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002535static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002536
2537VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
2538 void *opaque)
2539{
2540 VMChangeStateEntry *e;
2541
2542 e = qemu_mallocz(sizeof (*e));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002543
2544 e->cb = cb;
2545 e->opaque = opaque;
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002546 QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002547 return e;
2548}
2549
2550void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
2551{
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002552 QLIST_REMOVE (e, entries);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002553 qemu_free (e);
2554}
2555
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002556static void vm_state_notify(int running, int reason)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002557{
2558 VMChangeStateEntry *e;
2559
2560 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002561 e->cb(e->opaque, running, reason);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002562 }
2563}
2564
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002565static void resume_all_vcpus(void);
2566static void pause_all_vcpus(void);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002567
2568void vm_start(void)
2569{
2570 if (!vm_running) {
2571 cpu_enable_ticks();
2572 vm_running = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002573 vm_state_notify(1, 0);
David Turner6a9ef172010-09-09 22:54:36 +02002574 //qemu_rearm_alarm_timer(alarm_timer);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002575 resume_all_vcpus();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002576 }
2577}
2578
2579/* reset/shutdown handler */
2580
2581typedef struct QEMUResetEntry {
2582 QEMUResetHandler *func;
2583 void *opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002584 int order;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002585 struct QEMUResetEntry *next;
2586} QEMUResetEntry;
2587
2588static QEMUResetEntry *first_reset_entry;
2589static int reset_requested;
2590static int shutdown_requested;
2591static int powerdown_requested;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002592static int debug_requested;
2593static int vmstop_requested;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002594
2595int qemu_shutdown_requested(void)
2596{
2597 int r = shutdown_requested;
2598 shutdown_requested = 0;
2599 return r;
2600}
2601
2602int qemu_reset_requested(void)
2603{
2604 int r = reset_requested;
2605 reset_requested = 0;
2606 return r;
2607}
2608
2609int qemu_powerdown_requested(void)
2610{
2611 int r = powerdown_requested;
2612 powerdown_requested = 0;
2613 return r;
2614}
2615
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002616static int qemu_debug_requested(void)
2617{
2618 int r = debug_requested;
2619 debug_requested = 0;
2620 return r;
2621}
2622
2623static int qemu_vmstop_requested(void)
2624{
2625 int r = vmstop_requested;
2626 vmstop_requested = 0;
2627 return r;
2628}
2629
2630static void do_vm_stop(int reason)
2631{
2632 if (vm_running) {
2633 cpu_disable_ticks();
2634 vm_running = 0;
2635 pause_all_vcpus();
2636 vm_state_notify(0, reason);
2637 }
2638}
2639
2640void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002641{
2642 QEMUResetEntry **pre, *re;
2643
2644 pre = &first_reset_entry;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002645 while (*pre != NULL && (*pre)->order >= order) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002646 pre = &(*pre)->next;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002647 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002648 re = qemu_mallocz(sizeof(QEMUResetEntry));
2649 re->func = func;
2650 re->opaque = opaque;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002651 re->order = order;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002652 re->next = NULL;
2653 *pre = re;
2654}
2655
2656void qemu_system_reset(void)
2657{
2658 QEMUResetEntry *re;
2659
2660 /* reset all devices */
2661 for(re = first_reset_entry; re != NULL; re = re->next) {
2662 re->func(re->opaque);
2663 }
2664}
2665
2666void qemu_system_reset_request(void)
2667{
2668 if (no_reboot) {
2669 shutdown_requested = 1;
2670 } else {
2671 reset_requested = 1;
2672 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002673 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002674}
2675
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002676void qemu_system_shutdown_request(void)
2677{
2678 shutdown_requested = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002679 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002680}
2681
2682void qemu_system_powerdown_request(void)
2683{
2684 powerdown_requested = 1;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002685 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002686}
2687
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002688#ifdef CONFIG_IOTHREAD
2689static void qemu_system_vmstop_request(int reason)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002690{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002691 vmstop_requested = reason;
2692 qemu_notify_event();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002693}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002694#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002695
2696#ifndef _WIN32
2697static int io_thread_fd = -1;
2698
2699static void qemu_event_increment(void)
2700{
2701 static const char byte = 0;
2702
2703 if (io_thread_fd == -1)
2704 return;
2705
2706 write(io_thread_fd, &byte, sizeof(byte));
2707}
2708
2709static void qemu_event_read(void *opaque)
2710{
2711 int fd = (unsigned long)opaque;
2712 ssize_t len;
2713
2714 /* Drain the notify pipe */
2715 do {
2716 char buffer[512];
2717 len = read(fd, buffer, sizeof(buffer));
2718 } while ((len == -1 && errno == EINTR) || len > 0);
2719}
2720
2721static int qemu_event_init(void)
2722{
2723 int err;
2724 int fds[2];
2725
2726 err = pipe(fds);
2727 if (err == -1)
2728 return -errno;
2729
2730 err = fcntl_setfl(fds[0], O_NONBLOCK);
2731 if (err < 0)
2732 goto fail;
2733
2734 err = fcntl_setfl(fds[1], O_NONBLOCK);
2735 if (err < 0)
2736 goto fail;
2737
2738 qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
2739 (void *)(unsigned long)fds[0]);
2740
2741 io_thread_fd = fds[1];
2742 return 0;
2743
2744fail:
2745 close(fds[0]);
2746 close(fds[1]);
2747 return err;
2748}
2749#else
2750HANDLE qemu_event_handle;
2751
2752static void dummy_event_handler(void *opaque)
2753{
2754}
2755
2756static int qemu_event_init(void)
2757{
2758 qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
2759 if (!qemu_event_handle) {
2760 perror("Failed CreateEvent");
2761 return -1;
2762 }
2763 qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
2764 return 0;
2765}
2766
2767static void qemu_event_increment(void)
2768{
2769 SetEvent(qemu_event_handle);
2770}
2771#endif
2772
2773static int cpu_can_run(CPUState *env)
2774{
2775 if (env->stop)
2776 return 0;
2777 if (env->stopped)
2778 return 0;
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07002779 if (!vm_running)
2780 return 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002781 return 1;
2782}
2783
2784#ifndef CONFIG_IOTHREAD
2785static int qemu_init_main_loop(void)
2786{
2787 return qemu_event_init();
2788}
2789
2790void qemu_init_vcpu(void *_env)
2791{
2792 CPUState *env = _env;
2793
2794 if (kvm_enabled())
2795 kvm_init_vcpu(env);
2796 return;
2797}
2798
2799int qemu_cpu_self(void *env)
2800{
2801 return 1;
2802}
2803
2804static void resume_all_vcpus(void)
2805{
2806}
2807
2808static void pause_all_vcpus(void)
2809{
2810}
2811
2812void qemu_cpu_kick(void *env)
2813{
2814 return;
2815}
2816
2817void qemu_notify_event(void)
2818{
2819 CPUState *env = cpu_single_env;
2820
2821 if (env) {
2822 cpu_exit(env);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002823 }
2824}
2825
2826#define qemu_mutex_lock_iothread() do { } while (0)
2827#define qemu_mutex_unlock_iothread() do { } while (0)
2828
2829void vm_stop(int reason)
2830{
2831 do_vm_stop(reason);
2832}
2833
2834#else /* CONFIG_IOTHREAD */
2835
2836#include "qemu-thread.h"
2837
2838QemuMutex qemu_global_mutex;
2839static QemuMutex qemu_fair_mutex;
2840
2841static QemuThread io_thread;
2842
2843static QemuThread *tcg_cpu_thread;
2844static QemuCond *tcg_halt_cond;
2845
2846static int qemu_system_ready;
2847/* cpu creation */
2848static QemuCond qemu_cpu_cond;
2849/* system init */
2850static QemuCond qemu_system_cond;
2851static QemuCond qemu_pause_cond;
2852
2853static void block_io_signals(void);
2854static void unblock_io_signals(void);
2855static int tcg_has_work(void);
2856
2857static int qemu_init_main_loop(void)
2858{
2859 int ret;
2860
2861 ret = qemu_event_init();
2862 if (ret)
2863 return ret;
2864
2865 qemu_cond_init(&qemu_pause_cond);
2866 qemu_mutex_init(&qemu_fair_mutex);
2867 qemu_mutex_init(&qemu_global_mutex);
2868 qemu_mutex_lock(&qemu_global_mutex);
2869
2870 unblock_io_signals();
2871 qemu_thread_self(&io_thread);
2872
2873 return 0;
2874}
2875
2876static void qemu_wait_io_event(CPUState *env)
2877{
2878 while (!tcg_has_work())
2879 qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
2880
2881 qemu_mutex_unlock(&qemu_global_mutex);
2882
2883 /*
2884 * Users of qemu_global_mutex can be starved, having no chance
2885 * to acquire it since this path will get to it first.
2886 * So use another lock to provide fairness.
2887 */
2888 qemu_mutex_lock(&qemu_fair_mutex);
2889 qemu_mutex_unlock(&qemu_fair_mutex);
2890
2891 qemu_mutex_lock(&qemu_global_mutex);
2892 if (env->stop) {
2893 env->stop = 0;
2894 env->stopped = 1;
2895 qemu_cond_signal(&qemu_pause_cond);
2896 }
2897}
2898
2899static int qemu_cpu_exec(CPUState *env);
2900
2901static void *kvm_cpu_thread_fn(void *arg)
2902{
2903 CPUState *env = arg;
2904
2905 block_io_signals();
2906 qemu_thread_self(env->thread);
2907
2908 /* signal CPU creation */
2909 qemu_mutex_lock(&qemu_global_mutex);
2910 env->created = 1;
2911 qemu_cond_signal(&qemu_cpu_cond);
2912
2913 /* and wait for machine initialization */
2914 while (!qemu_system_ready)
2915 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2916
2917 while (1) {
2918 if (cpu_can_run(env))
2919 qemu_cpu_exec(env);
2920 qemu_wait_io_event(env);
2921 }
2922
2923 return NULL;
2924}
2925
2926static void tcg_cpu_exec(void);
2927
2928static void *tcg_cpu_thread_fn(void *arg)
2929{
2930 CPUState *env = arg;
2931
2932 block_io_signals();
2933 qemu_thread_self(env->thread);
2934
2935 /* signal CPU creation */
2936 qemu_mutex_lock(&qemu_global_mutex);
2937 for (env = first_cpu; env != NULL; env = env->next_cpu)
2938 env->created = 1;
2939 qemu_cond_signal(&qemu_cpu_cond);
2940
2941 /* and wait for machine initialization */
2942 while (!qemu_system_ready)
2943 qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
2944
2945 while (1) {
2946 tcg_cpu_exec();
2947 qemu_wait_io_event(cur_cpu);
2948 }
2949
2950 return NULL;
2951}
2952
2953void qemu_cpu_kick(void *_env)
2954{
2955 CPUState *env = _env;
2956 qemu_cond_broadcast(env->halt_cond);
2957 if (kvm_enabled())
2958 qemu_thread_signal(env->thread, SIGUSR1);
2959}
2960
2961int qemu_cpu_self(void *env)
2962{
2963 return (cpu_single_env != NULL);
2964}
2965
2966static void cpu_signal(int sig)
2967{
2968 if (cpu_single_env)
2969 cpu_exit(cpu_single_env);
2970}
2971
2972static void block_io_signals(void)
2973{
2974 sigset_t set;
2975 struct sigaction sigact;
2976
2977 sigemptyset(&set);
2978 sigaddset(&set, SIGUSR2);
2979 sigaddset(&set, SIGIO);
2980 sigaddset(&set, SIGALRM);
2981 pthread_sigmask(SIG_BLOCK, &set, NULL);
2982
2983 sigemptyset(&set);
2984 sigaddset(&set, SIGUSR1);
2985 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
2986
2987 memset(&sigact, 0, sizeof(sigact));
2988 sigact.sa_handler = cpu_signal;
2989 sigaction(SIGUSR1, &sigact, NULL);
2990}
2991
2992static void unblock_io_signals(void)
2993{
2994 sigset_t set;
2995
2996 sigemptyset(&set);
2997 sigaddset(&set, SIGUSR2);
2998 sigaddset(&set, SIGIO);
2999 sigaddset(&set, SIGALRM);
3000 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
3001
3002 sigemptyset(&set);
3003 sigaddset(&set, SIGUSR1);
3004 pthread_sigmask(SIG_BLOCK, &set, NULL);
3005}
3006
3007static void qemu_signal_lock(unsigned int msecs)
3008{
3009 qemu_mutex_lock(&qemu_fair_mutex);
3010
3011 while (qemu_mutex_trylock(&qemu_global_mutex)) {
3012 qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
3013 if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
3014 break;
3015 }
3016 qemu_mutex_unlock(&qemu_fair_mutex);
3017}
3018
3019static void qemu_mutex_lock_iothread(void)
3020{
3021 if (kvm_enabled()) {
3022 qemu_mutex_lock(&qemu_fair_mutex);
3023 qemu_mutex_lock(&qemu_global_mutex);
3024 qemu_mutex_unlock(&qemu_fair_mutex);
3025 } else
3026 qemu_signal_lock(100);
3027}
3028
3029static void qemu_mutex_unlock_iothread(void)
3030{
3031 qemu_mutex_unlock(&qemu_global_mutex);
3032}
3033
3034static int all_vcpus_paused(void)
3035{
3036 CPUState *penv = first_cpu;
3037
3038 while (penv) {
3039 if (!penv->stopped)
3040 return 0;
3041 penv = (CPUState *)penv->next_cpu;
3042 }
3043
3044 return 1;
3045}
3046
3047static void pause_all_vcpus(void)
3048{
3049 CPUState *penv = first_cpu;
3050
3051 while (penv) {
3052 penv->stop = 1;
3053 qemu_thread_signal(penv->thread, SIGUSR1);
3054 qemu_cpu_kick(penv);
3055 penv = (CPUState *)penv->next_cpu;
3056 }
3057
3058 while (!all_vcpus_paused()) {
3059 qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
3060 penv = first_cpu;
3061 while (penv) {
3062 qemu_thread_signal(penv->thread, SIGUSR1);
3063 penv = (CPUState *)penv->next_cpu;
3064 }
3065 }
3066}
3067
3068static void resume_all_vcpus(void)
3069{
3070 CPUState *penv = first_cpu;
3071
3072 while (penv) {
3073 penv->stop = 0;
3074 penv->stopped = 0;
3075 qemu_thread_signal(penv->thread, SIGUSR1);
3076 qemu_cpu_kick(penv);
3077 penv = (CPUState *)penv->next_cpu;
3078 }
3079}
3080
3081static void tcg_init_vcpu(void *_env)
3082{
3083 CPUState *env = _env;
3084 /* share a single thread for all cpus with TCG */
3085 if (!tcg_cpu_thread) {
3086 env->thread = qemu_mallocz(sizeof(QemuThread));
3087 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3088 qemu_cond_init(env->halt_cond);
3089 qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
3090 while (env->created == 0)
3091 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3092 tcg_cpu_thread = env->thread;
3093 tcg_halt_cond = env->halt_cond;
3094 } else {
3095 env->thread = tcg_cpu_thread;
3096 env->halt_cond = tcg_halt_cond;
3097 }
3098}
3099
3100static void kvm_start_vcpu(CPUState *env)
3101{
3102 kvm_init_vcpu(env);
3103 env->thread = qemu_mallocz(sizeof(QemuThread));
3104 env->halt_cond = qemu_mallocz(sizeof(QemuCond));
3105 qemu_cond_init(env->halt_cond);
3106 qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
3107 while (env->created == 0)
3108 qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
3109}
3110
3111void qemu_init_vcpu(void *_env)
3112{
3113 CPUState *env = _env;
3114
3115 if (kvm_enabled())
3116 kvm_start_vcpu(env);
3117 else
3118 tcg_init_vcpu(env);
3119}
3120
3121void qemu_notify_event(void)
3122{
3123 qemu_event_increment();
3124}
3125
3126void vm_stop(int reason)
3127{
3128 QemuThread me;
3129 qemu_thread_self(&me);
3130
3131 if (!qemu_thread_equal(&me, &io_thread)) {
3132 qemu_system_vmstop_request(reason);
3133 /*
3134 * FIXME: should not return to device code in case
3135 * vm_stop() has been requested.
3136 */
3137 if (cpu_single_env) {
3138 cpu_exit(cpu_single_env);
3139 cpu_single_env->stop = 1;
3140 }
3141 return;
3142 }
3143 do_vm_stop(reason);
3144}
3145
3146#endif
3147
3148
3149#ifdef _WIN32
3150static void host_main_loop_wait(int *timeout)
3151{
3152 int ret, ret2, i;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003153 PollingEntry *pe;
3154
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003155
3156 /* XXX: need to suppress polling by better using win32 events */
3157 ret = 0;
3158 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
3159 ret |= pe->func(pe->opaque);
3160 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003161 if (ret == 0) {
3162 int err;
3163 WaitObjects *w = &wait_objects;
3164
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003165 ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003166 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
3167 if (w->func[ret - WAIT_OBJECT_0])
3168 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
3169
3170 /* Check for additional signaled events */
3171 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
3172
3173 /* Check if event is signaled */
3174 ret2 = WaitForSingleObject(w->events[i], 0);
3175 if(ret2 == WAIT_OBJECT_0) {
3176 if (w->func[i])
3177 w->func[i](w->opaque[i]);
3178 } else if (ret2 == WAIT_TIMEOUT) {
3179 } else {
3180 err = GetLastError();
3181 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
3182 }
3183 }
3184 } else if (ret == WAIT_TIMEOUT) {
3185 } else {
3186 err = GetLastError();
3187 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
3188 }
3189 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003190
3191 *timeout = 0;
3192}
3193#else
3194static void host_main_loop_wait(int *timeout)
3195{
3196}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003197#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003198
3199void main_loop_wait(int timeout)
3200{
3201 IOHandlerRecord *ioh;
3202 fd_set rfds, wfds, xfds;
3203 int ret, nfds;
3204 struct timeval tv;
3205
3206 qemu_bh_update_timeout(&timeout);
3207
3208 host_main_loop_wait(&timeout);
3209
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003210 /* poll any events */
3211 /* XXX: separate device handlers from system ones */
3212 nfds = -1;
3213 FD_ZERO(&rfds);
3214 FD_ZERO(&wfds);
3215 FD_ZERO(&xfds);
3216 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
3217 if (ioh->deleted)
3218 continue;
3219 if (ioh->fd_read &&
3220 (!ioh->fd_read_poll ||
3221 ioh->fd_read_poll(ioh->opaque) != 0)) {
3222 FD_SET(ioh->fd, &rfds);
3223 if (ioh->fd > nfds)
3224 nfds = ioh->fd;
3225 }
3226 if (ioh->fd_write) {
3227 FD_SET(ioh->fd, &wfds);
3228 if (ioh->fd > nfds)
3229 nfds = ioh->fd;
3230 }
3231 }
3232
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003233 tv.tv_sec = timeout / 1000;
3234 tv.tv_usec = (timeout % 1000) * 1000;
3235
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003236#if defined(CONFIG_SLIRP)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003237 if (slirp_is_inited()) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003238 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
3239 }
3240#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003241 qemu_mutex_unlock_iothread();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003242 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003243 qemu_mutex_lock_iothread();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003244 if (ret > 0) {
3245 IOHandlerRecord **pioh;
3246
3247 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
3248 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
3249 ioh->fd_read(ioh->opaque);
3250 }
3251 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
3252 ioh->fd_write(ioh->opaque);
3253 }
3254 }
3255
3256 /* remove deleted IO handlers */
3257 pioh = &first_io_handler;
3258 while (*pioh) {
3259 ioh = *pioh;
3260 if (ioh->deleted) {
3261 *pioh = ioh->next;
3262 qemu_free(ioh);
3263 } else
3264 pioh = &ioh->next;
3265 }
3266 }
3267#if defined(CONFIG_SLIRP)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003268 if (slirp_is_inited()) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003269 if (ret < 0) {
3270 FD_ZERO(&rfds);
3271 FD_ZERO(&wfds);
3272 FD_ZERO(&xfds);
3273 }
3274 slirp_select_poll(&rfds, &wfds, &xfds);
3275 }
3276#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003277
David Turner6a9ef172010-09-09 22:54:36 +02003278#if 0
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003279 /* rearm timer, if not periodic */
3280 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
3281 alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
3282 qemu_rearm_alarm_timer(alarm_timer);
3283 }
3284
3285 /* vm time timers */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003286 if (vm_running) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003287 if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003288 qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003289 qemu_get_clock(vm_clock));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003290 }
3291
3292 /* real time timers */
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003293 qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003294 qemu_get_clock(rt_clock));
3295
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003296 qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
3297 qemu_get_clock(host_clock));
David Turner6a9ef172010-09-09 22:54:36 +02003298#endif
3299 qemu_run_all_timers();
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003300
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003301 /* Check bottom-halves last in case any of the earlier events triggered
3302 them. */
3303 qemu_bh_poll();
3304
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003305}
3306
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003307static int qemu_cpu_exec(CPUState *env)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003308{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003309 int ret;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003310#ifdef CONFIG_PROFILER
3311 int64_t ti;
3312#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003313
3314#ifdef CONFIG_PROFILER
3315 ti = profile_getclock();
3316#endif
3317 if (use_icount) {
3318 int64_t count;
3319 int decr;
3320 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
3321 env->icount_decr.u16.low = 0;
3322 env->icount_extra = 0;
3323 count = qemu_next_deadline();
3324 count = (count + (1 << icount_time_shift) - 1)
3325 >> icount_time_shift;
3326 qemu_icount += count;
3327 decr = (count > 0xffff) ? 0xffff : count;
3328 count -= decr;
3329 env->icount_decr.u16.low = decr;
3330 env->icount_extra = count;
3331 }
3332 ret = cpu_exec(env);
3333#ifdef CONFIG_PROFILER
3334 qemu_time += profile_getclock() - ti;
3335#endif
3336 if (use_icount) {
3337 /* Fold pending instructions back into the
3338 instruction counter, and clear the interrupt flag. */
3339 qemu_icount -= (env->icount_decr.u16.low
3340 + env->icount_extra);
3341 env->icount_decr.u32 = 0;
3342 env->icount_extra = 0;
3343 }
3344 return ret;
3345}
3346
3347static void tcg_cpu_exec(void)
3348{
3349 int ret = 0;
3350
3351 if (next_cpu == NULL)
3352 next_cpu = first_cpu;
3353 for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
3354 CPUState *env = cur_cpu = next_cpu;
3355
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003356 if (timer_alarm_pending) {
3357 timer_alarm_pending = 0;
3358 break;
3359 }
3360 if (cpu_can_run(env))
3361 ret = qemu_cpu_exec(env);
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003362 else if (env->stop)
3363 break;
3364
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003365 if (ret == EXCP_DEBUG) {
3366 gdb_set_stop_cpu(env);
3367 debug_requested = 1;
3368 break;
3369 }
3370 }
3371}
3372
3373static int cpu_has_work(CPUState *env)
3374{
3375 if (env->stop)
3376 return 1;
3377 if (env->stopped)
3378 return 0;
3379 if (!env->halted)
3380 return 1;
3381 if (qemu_cpu_has_work(env))
3382 return 1;
3383 return 0;
3384}
3385
3386static int tcg_has_work(void)
3387{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003388 CPUState *env;
3389
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003390 for (env = first_cpu; env != NULL; env = env->next_cpu)
3391 if (cpu_has_work(env))
3392 return 1;
3393 return 0;
3394}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003395
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003396
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003397static int vm_can_run(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003398{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003399 if (powerdown_requested)
3400 return 0;
3401 if (reset_requested)
3402 return 0;
3403 if (shutdown_requested)
3404 return 0;
3405 if (debug_requested)
3406 return 0;
3407 return 1;
3408}
3409
3410static void main_loop(void)
3411{
3412 int r;
3413
3414#ifdef CONFIG_IOTHREAD
3415 qemu_system_ready = 1;
3416 qemu_cond_broadcast(&qemu_system_cond);
3417#endif
3418
3419 for (;;) {
3420 do {
3421#ifdef CONFIG_PROFILER
3422 int64_t ti;
3423#endif
3424#ifndef CONFIG_IOTHREAD
3425 tcg_cpu_exec();
3426#endif
3427#ifdef CONFIG_PROFILER
3428 ti = profile_getclock();
3429#endif
3430 main_loop_wait(qemu_calculate_timeout());
3431#ifdef CONFIG_PROFILER
3432 dev_time += profile_getclock() - ti;
3433#endif
3434 } while (vm_can_run());
3435
3436 if (qemu_debug_requested())
3437 vm_stop(EXCP_DEBUG);
3438 if (qemu_shutdown_requested()) {
3439 if (no_shutdown) {
3440 vm_stop(0);
3441 no_shutdown = 0;
3442 } else
3443 break;
3444 }
3445 if (qemu_reset_requested()) {
3446 pause_all_vcpus();
3447 qemu_system_reset();
3448 resume_all_vcpus();
3449 }
3450 if (qemu_powerdown_requested())
3451 qemu_system_powerdown();
3452 if ((r = qemu_vmstop_requested()))
3453 vm_stop(r);
3454 }
3455 pause_all_vcpus();
3456}
3457
3458static void version(void)
3459{
3460 printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
3461}
3462
3463static void help(int exitcode)
3464{
3465 version();
3466 printf("usage: %s [options] [disk_image]\n"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003467 "\n"
3468 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
3469 "\n"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003470#define DEF(option, opt_arg, opt_enum, opt_help) \
3471 opt_help
3472#define DEFHEADING(text) stringify(text) "\n"
3473#include "qemu-options.h"
3474#undef DEF
3475#undef DEFHEADING
3476#undef GEN_DOCS
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003477 "\n"
3478 "During emulation, the following keys are useful:\n"
3479 "ctrl-alt-f toggle full screen\n"
3480 "ctrl-alt-n switch to virtual console 'n'\n"
3481 "ctrl-alt toggle mouse and keyboard grab\n"
3482 "\n"
3483 "When using -nographic, press 'ctrl-a h' to get some help.\n"
3484 ,
3485 "qemu",
3486 DEFAULT_RAM_SIZE,
3487#ifndef _WIN32
3488 DEFAULT_NETWORK_SCRIPT,
3489 DEFAULT_NETWORK_DOWN_SCRIPT,
3490#endif
3491 DEFAULT_GDBSTUB_PORT,
3492 "/tmp/qemu.log");
3493 exit(exitcode);
3494}
3495
3496#define HAS_ARG 0x0001
3497
3498enum {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003499#define DEF(option, opt_arg, opt_enum, opt_help) \
3500 opt_enum,
3501#define DEFHEADING(text)
3502#include "qemu-options.h"
3503#undef DEF
3504#undef DEFHEADING
3505#undef GEN_DOCS
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003506};
3507
3508typedef struct QEMUOption {
3509 const char *name;
3510 int flags;
3511 int index;
3512} QEMUOption;
3513
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003514static const QEMUOption qemu_options[] = {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003515 { "h", 0, QEMU_OPTION_h },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003516#define DEF(option, opt_arg, opt_enum, opt_help) \
3517 { option, opt_arg, opt_enum },
3518#define DEFHEADING(text)
3519#include "qemu-options.h"
3520#undef DEF
3521#undef DEFHEADING
3522#undef GEN_DOCS
3523 { NULL },
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003524};
3525
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003526#ifdef HAS_AUDIO
3527struct soundhw soundhw[] = {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003528#ifdef HAS_AUDIO_CHOICE
3529#if defined(TARGET_I386) || defined(TARGET_MIPS)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003530 {
3531 "pcspk",
3532 "PC speaker",
3533 0,
3534 1,
3535 { .init_isa = pcspk_audio_init }
3536 },
3537#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003538
3539#ifdef CONFIG_SB16
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003540 {
3541 "sb16",
3542 "Creative Sound Blaster 16",
3543 0,
3544 1,
3545 { .init_isa = SB16_init }
3546 },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003547#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003548
3549#ifdef CONFIG_CS4231A
3550 {
3551 "cs4231a",
3552 "CS4231A",
3553 0,
3554 1,
3555 { .init_isa = cs4231a_init }
3556 },
3557#endif
3558
3559#ifdef CONFIG_ADLIB
3560 {
3561 "adlib",
3562#ifdef HAS_YMF262
3563 "Yamaha YMF262 (OPL3)",
3564#else
3565 "Yamaha YM3812 (OPL2)",
3566#endif
3567 0,
3568 1,
3569 { .init_isa = Adlib_init }
3570 },
3571#endif
3572
3573#ifdef CONFIG_GUS
3574 {
3575 "gus",
3576 "Gravis Ultrasound GF1",
3577 0,
3578 1,
3579 { .init_isa = GUS_init }
3580 },
3581#endif
3582
3583#ifdef CONFIG_AC97
3584 {
3585 "ac97",
3586 "Intel 82801AA AC97 Audio",
3587 0,
3588 0,
3589 { .init_pci = ac97_init }
3590 },
3591#endif
3592
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003593#ifdef CONFIG_ES1370
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003594 {
3595 "es1370",
3596 "ENSONIQ AudioPCI ES1370",
3597 0,
3598 0,
3599 { .init_pci = es1370_init }
3600 },
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003601#endif
3602
3603#endif /* HAS_AUDIO_CHOICE */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003604
3605 { NULL, NULL, 0, 0, { NULL } }
3606};
3607
3608static void select_soundhw (const char *optarg)
3609{
3610 struct soundhw *c;
3611
3612 if (*optarg == '?') {
3613 show_valid_cards:
3614
3615 printf ("Valid sound card names (comma separated):\n");
3616 for (c = soundhw; c->name; ++c) {
3617 printf ("%-11s %s\n", c->name, c->descr);
3618 }
3619 printf ("\n-soundhw all will enable all of the above\n");
3620 exit (*optarg != '?');
3621 }
3622 else {
3623 size_t l;
3624 const char *p;
3625 char *e;
3626 int bad_card = 0;
3627
3628 if (!strcmp (optarg, "all")) {
3629 for (c = soundhw; c->name; ++c) {
3630 c->enabled = 1;
3631 }
3632 return;
3633 }
3634
3635 p = optarg;
3636 while (*p) {
3637 e = strchr (p, ',');
3638 l = !e ? strlen (p) : (size_t) (e - p);
3639
3640 for (c = soundhw; c->name; ++c) {
3641 if (!strncmp (c->name, p, l)) {
3642 c->enabled = 1;
3643 break;
3644 }
3645 }
3646
3647 if (!c->name) {
3648 if (l > 80) {
3649 fprintf (stderr,
3650 "Unknown sound card name (too big to show)\n");
3651 }
3652 else {
3653 fprintf (stderr, "Unknown sound card name `%.*s'\n",
3654 (int) l, p);
3655 }
3656 bad_card = 1;
3657 }
3658 p += l + (e != NULL);
3659 }
3660
3661 if (bad_card)
3662 goto show_valid_cards;
3663 }
3664}
3665#endif
3666
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003667static void select_vgahw (const char *p)
3668{
3669 const char *opts;
3670
3671 cirrus_vga_enabled = 0;
3672 std_vga_enabled = 0;
3673 vmsvga_enabled = 0;
3674 xenfb_enabled = 0;
3675 if (strstart(p, "std", &opts)) {
3676 std_vga_enabled = 1;
3677 } else if (strstart(p, "cirrus", &opts)) {
3678 cirrus_vga_enabled = 1;
3679 } else if (strstart(p, "vmware", &opts)) {
3680 vmsvga_enabled = 1;
3681 } else if (strstart(p, "xenfb", &opts)) {
3682 xenfb_enabled = 1;
3683 } else if (!strstart(p, "none", &opts)) {
3684 invalid_vga:
3685 fprintf(stderr, "Unknown vga type: %s\n", p);
3686 exit(1);
3687 }
3688 while (*opts) {
3689 const char *nextopt;
3690
3691 if (strstart(opts, ",retrace=", &nextopt)) {
3692 opts = nextopt;
3693 if (strstart(opts, "dumb", &nextopt))
3694 vga_retrace_method = VGA_RETRACE_DUMB;
3695 else if (strstart(opts, "precise", &nextopt))
3696 vga_retrace_method = VGA_RETRACE_PRECISE;
3697 else goto invalid_vga;
3698 } else goto invalid_vga;
3699 opts = nextopt;
3700 }
3701}
3702
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003703#ifdef _WIN32
3704static BOOL WINAPI qemu_ctrl_handler(DWORD type)
3705{
3706 exit(STATUS_CONTROL_C_EXIT);
3707 return TRUE;
3708}
3709#endif
3710
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003711int qemu_uuid_parse(const char *str, uint8_t *uuid)
3712{
3713 int ret;
3714
3715 if(strlen(str) != 36)
3716 return -1;
3717
3718 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
3719 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
3720 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
3721
3722 if(ret != 16)
3723 return -1;
3724
3725#ifdef TARGET_I386
3726 smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
3727#endif
3728
3729 return 0;
3730}
3731
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003732#define MAX_NET_CLIENTS 32
3733
3734#ifndef _WIN32
3735
3736static void termsig_handler(int signal)
3737{
3738 qemu_system_shutdown_request();
3739}
3740
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003741static void sigchld_handler(int signal)
3742{
3743 waitpid(-1, NULL, WNOHANG);
3744}
3745
3746static void sighandler_setup(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003747{
3748 struct sigaction act;
3749
3750 memset(&act, 0, sizeof(act));
3751 act.sa_handler = termsig_handler;
3752 sigaction(SIGINT, &act, NULL);
3753 sigaction(SIGHUP, &act, NULL);
3754 sigaction(SIGTERM, &act, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003755
3756 act.sa_handler = sigchld_handler;
3757 act.sa_flags = SA_NOCLDSTOP;
3758 sigaction(SIGCHLD, &act, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003759}
3760
3761#endif
3762
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003763#ifdef _WIN32
3764/* Look for support files in the same directory as the executable. */
3765static char *find_datadir(const char *argv0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003766{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003767 char *p;
3768 char buf[MAX_PATH];
3769 DWORD len;
3770
3771 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
3772 if (len == 0) {
3773 return NULL;
3774 }
3775
3776 buf[len] = 0;
3777 p = buf + len - 1;
3778 while (p != buf && *p != '\\')
3779 p--;
3780 *p = 0;
3781 if (access(buf, R_OK) == 0) {
3782 return qemu_strdup(buf);
3783 }
3784 return NULL;
3785}
3786#else /* !_WIN32 */
3787
3788/* Find a likely location for support files using the location of the binary.
3789 For installed binaries this will be "$bindir/../share/qemu". When
3790 running from the build tree this will be "$bindir/../pc-bios". */
3791#define SHARE_SUFFIX "/share/qemu"
3792#define BUILD_SUFFIX "/pc-bios"
3793static char *find_datadir(const char *argv0)
3794{
3795 char *dir;
3796 char *p = NULL;
3797 char *res;
3798#ifdef PATH_MAX
3799 char buf[PATH_MAX];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003800#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003801 size_t max_len;
3802
3803#if defined(__linux__)
3804 {
3805 int len;
3806 len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
3807 if (len > 0) {
3808 buf[len] = 0;
3809 p = buf;
3810 }
3811 }
3812#elif defined(__FreeBSD__)
3813 {
3814 int len;
3815 len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
3816 if (len > 0) {
3817 buf[len] = 0;
3818 p = buf;
3819 }
3820 }
3821#endif
3822 /* If we don't have any way of figuring out the actual executable
3823 location then try argv[0]. */
3824 if (!p) {
3825#ifdef PATH_MAX
3826 p = buf;
3827#endif
3828 p = realpath(argv0, p);
3829 if (!p) {
3830 return NULL;
3831 }
3832 }
3833 dir = dirname(p);
3834 dir = dirname(dir);
3835
3836 max_len = strlen(dir) +
3837 MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
3838 res = qemu_mallocz(max_len);
3839 snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
3840 if (access(res, R_OK)) {
3841 snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
3842 if (access(res, R_OK)) {
3843 qemu_free(res);
3844 res = NULL;
3845 }
3846 }
3847#ifndef PATH_MAX
3848 free(p);
3849#endif
3850 return res;
3851}
3852#undef SHARE_SUFFIX
3853#undef BUILD_SUFFIX
3854#endif
3855
3856char *qemu_find_file(int type, const char *name)
3857{
3858 int len;
3859 const char *subdir;
3860 char *buf;
3861
3862 /* If name contains path separators then try it as a straight path. */
3863 if ((strchr(name, '/') || strchr(name, '\\'))
3864 && access(name, R_OK) == 0) {
3865 return strdup(name);
3866 }
3867 switch (type) {
3868 case QEMU_FILE_TYPE_BIOS:
3869 subdir = "";
3870 break;
3871 case QEMU_FILE_TYPE_KEYMAP:
3872 subdir = "keymaps/";
3873 break;
3874 default:
3875 abort();
3876 }
3877 len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
3878 buf = qemu_mallocz(len);
3879 snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
3880 if (access(buf, R_OK)) {
3881 qemu_free(buf);
3882 return NULL;
3883 }
3884 return buf;
3885}
3886
3887int main(int argc, char **argv, char **envp)
3888{
3889 const char *gdbstub_dev = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003890 uint32_t boot_devices_bitmap = 0;
3891 int i;
3892 int snapshot, linux_boot, net_boot;
David Turner6a9ef172010-09-09 22:54:36 +02003893 const char *icount_option = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003894 const char *initrd_filename;
3895 const char *kernel_filename, *kernel_cmdline;
3896 const char *boot_devices = "";
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003897 DisplayState *ds;
3898 DisplayChangeListener *dcl;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003899 int cyls, heads, secs, translation;
3900 const char *net_clients[MAX_NET_CLIENTS];
3901 int nb_net_clients;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003902 const char *bt_opts[MAX_BT_CMDLINE];
3903 int nb_bt_opts;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003904 int hda_index;
3905 int optind;
3906 const char *r, *optarg;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003907 CharDriverState *monitor_hd = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003908 const char *monitor_device;
3909 const char *serial_devices[MAX_SERIAL_PORTS];
3910 int serial_device_index;
3911 const char *parallel_devices[MAX_PARALLEL_PORTS];
3912 int parallel_device_index;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003913 const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
3914 int virtio_console_index;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003915 const char *loadvm = NULL;
3916 QEMUMachine *machine;
3917 const char *cpu_model;
3918 const char *usb_devices[MAX_USB_CMDLINE];
3919 int usb_devices_index;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003920#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003921 int fds[2];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003922#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003923 int tb_size;
3924 const char *pid_file = NULL;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003925 const char *incoming = NULL;
3926#ifndef _WIN32
3927 int fd = 0;
3928 struct passwd *pwd = NULL;
3929 const char *chroot_dir = NULL;
3930 const char *run_as = NULL;
3931#endif
3932 CPUState *env;
3933 int show_vnc_port = 0;
3934
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07003935 init_clocks();
3936
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003937 qemu_cache_utils_init(envp);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003938
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07003939 QLIST_INIT (&vm_change_state_head);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003940#ifndef _WIN32
3941 {
3942 struct sigaction act;
3943 sigfillset(&act.sa_mask);
3944 act.sa_flags = 0;
3945 act.sa_handler = SIG_IGN;
3946 sigaction(SIGPIPE, &act, NULL);
3947 }
3948#else
3949 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
3950 /* Note: cpu_interrupt() is currently not SMP safe, so we force
3951 QEMU to run on a single CPU */
3952 {
3953 HANDLE h;
3954 DWORD mask, smask;
3955 int i;
3956 h = GetCurrentProcess();
3957 if (GetProcessAffinityMask(h, &mask, &smask)) {
3958 for(i = 0; i < 32; i++) {
3959 if (mask & (1 << i))
3960 break;
3961 }
3962 if (i != 32) {
3963 mask = 1 << i;
3964 SetProcessAffinityMask(h, mask);
3965 }
3966 }
3967 }
3968#endif
3969
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003970 module_call_init(MODULE_INIT_MACHINE);
3971 machine = find_default_machine();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003972 cpu_model = NULL;
3973 initrd_filename = NULL;
3974 ram_size = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003975 snapshot = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003976 kernel_filename = NULL;
3977 kernel_cmdline = "";
3978 cyls = heads = secs = 0;
3979 translation = BIOS_ATA_TRANSLATION_AUTO;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003980 monitor_device = "vc:80Cx24C";
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003981
3982 serial_devices[0] = "vc:80Cx24C";
3983 for(i = 1; i < MAX_SERIAL_PORTS; i++)
3984 serial_devices[i] = NULL;
3985 serial_device_index = 0;
3986
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003987 parallel_devices[0] = "vc:80Cx24C";
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08003988 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
3989 parallel_devices[i] = NULL;
3990 parallel_device_index = 0;
3991
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003992 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
3993 virtio_consoles[i] = NULL;
3994 virtio_console_index = 0;
3995
3996 for (i = 0; i < MAX_NODES; i++) {
3997 node_mem[i] = 0;
3998 node_cpumask[i] = 0;
3999 }
4000
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004001 usb_devices_index = 0;
4002
4003 nb_net_clients = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004004 nb_bt_opts = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004005 nb_drives = 0;
4006 nb_drives_opt = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004007 nb_numa_nodes = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004008 hda_index = -1;
4009
4010 nb_nics = 0;
4011
4012 tb_size = 0;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004013 autostart= 1;
4014
4015 register_watchdogs();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004016
4017 optind = 1;
4018 for(;;) {
4019 if (optind >= argc)
4020 break;
4021 r = argv[optind];
4022 if (r[0] != '-') {
4023 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
4024 } else {
4025 const QEMUOption *popt;
4026
4027 optind++;
4028 /* Treat --foo the same as -foo. */
4029 if (r[1] == '-')
4030 r++;
4031 popt = qemu_options;
4032 for(;;) {
4033 if (!popt->name) {
4034 fprintf(stderr, "%s: invalid option -- '%s'\n",
4035 argv[0], r);
4036 exit(1);
4037 }
4038 if (!strcmp(popt->name, r + 1))
4039 break;
4040 popt++;
4041 }
4042 if (popt->flags & HAS_ARG) {
4043 if (optind >= argc) {
4044 fprintf(stderr, "%s: option '%s' requires an argument\n",
4045 argv[0], r);
4046 exit(1);
4047 }
4048 optarg = argv[optind++];
4049 } else {
4050 optarg = NULL;
4051 }
4052
4053 switch(popt->index) {
4054 case QEMU_OPTION_M:
4055 machine = find_machine(optarg);
4056 if (!machine) {
4057 QEMUMachine *m;
4058 printf("Supported machines are:\n");
4059 for(m = first_machine; m != NULL; m = m->next) {
4060 printf("%-10s %s%s\n",
4061 m->name, m->desc,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004062 m->is_default ? " (default)" : "");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004063 }
4064 exit(*optarg != '?');
4065 }
4066 break;
4067 case QEMU_OPTION_cpu:
4068 /* hw initialization will check this */
4069 if (*optarg == '?') {
4070/* XXX: implement xxx_cpu_list for targets that still miss it */
4071#if defined(cpu_list)
4072 cpu_list(stdout, &fprintf);
4073#endif
4074 exit(0);
4075 } else {
4076 cpu_model = optarg;
4077 }
4078 break;
4079 case QEMU_OPTION_initrd:
4080 initrd_filename = optarg;
4081 break;
4082 case QEMU_OPTION_hda:
4083 if (cyls == 0)
4084 hda_index = drive_add(optarg, HD_ALIAS, 0);
4085 else
4086 hda_index = drive_add(optarg, HD_ALIAS
4087 ",cyls=%d,heads=%d,secs=%d%s",
4088 0, cyls, heads, secs,
4089 translation == BIOS_ATA_TRANSLATION_LBA ?
4090 ",trans=lba" :
4091 translation == BIOS_ATA_TRANSLATION_NONE ?
4092 ",trans=none" : "");
4093 break;
4094 case QEMU_OPTION_hdb:
4095 case QEMU_OPTION_hdc:
4096 case QEMU_OPTION_hdd:
4097 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
4098 break;
4099 case QEMU_OPTION_drive:
4100 drive_add(NULL, "%s", optarg);
4101 break;
4102 case QEMU_OPTION_mtdblock:
4103 drive_add(optarg, MTD_ALIAS);
4104 break;
4105 case QEMU_OPTION_sd:
4106 drive_add(optarg, SD_ALIAS);
4107 break;
4108 case QEMU_OPTION_pflash:
4109 drive_add(optarg, PFLASH_ALIAS);
4110 break;
4111 case QEMU_OPTION_snapshot:
4112 snapshot = 1;
4113 break;
4114 case QEMU_OPTION_hdachs:
4115 {
4116 const char *p;
4117 p = optarg;
4118 cyls = strtol(p, (char **)&p, 0);
4119 if (cyls < 1 || cyls > 16383)
4120 goto chs_fail;
4121 if (*p != ',')
4122 goto chs_fail;
4123 p++;
4124 heads = strtol(p, (char **)&p, 0);
4125 if (heads < 1 || heads > 16)
4126 goto chs_fail;
4127 if (*p != ',')
4128 goto chs_fail;
4129 p++;
4130 secs = strtol(p, (char **)&p, 0);
4131 if (secs < 1 || secs > 63)
4132 goto chs_fail;
4133 if (*p == ',') {
4134 p++;
4135 if (!strcmp(p, "none"))
4136 translation = BIOS_ATA_TRANSLATION_NONE;
4137 else if (!strcmp(p, "lba"))
4138 translation = BIOS_ATA_TRANSLATION_LBA;
4139 else if (!strcmp(p, "auto"))
4140 translation = BIOS_ATA_TRANSLATION_AUTO;
4141 else
4142 goto chs_fail;
4143 } else if (*p != '\0') {
4144 chs_fail:
4145 fprintf(stderr, "qemu: invalid physical CHS format\n");
4146 exit(1);
4147 }
4148 if (hda_index != -1)
4149 snprintf(drives_opt[hda_index].opt,
4150 sizeof(drives_opt[hda_index].opt),
4151 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
4152 0, cyls, heads, secs,
4153 translation == BIOS_ATA_TRANSLATION_LBA ?
4154 ",trans=lba" :
4155 translation == BIOS_ATA_TRANSLATION_NONE ?
4156 ",trans=none" : "");
4157 }
4158 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004159 case QEMU_OPTION_numa:
4160 if (nb_numa_nodes >= MAX_NODES) {
4161 fprintf(stderr, "qemu: too many NUMA nodes\n");
4162 exit(1);
4163 }
4164 numa_add(optarg);
4165 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004166 case QEMU_OPTION_nographic:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004167 display_type = DT_NOGRAPHIC;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004168 break;
4169#ifdef CONFIG_CURSES
4170 case QEMU_OPTION_curses:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004171 display_type = DT_CURSES;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004172 break;
4173#endif
4174 case QEMU_OPTION_portrait:
4175 graphic_rotate = 1;
4176 break;
4177 case QEMU_OPTION_kernel:
4178 kernel_filename = optarg;
4179 break;
4180 case QEMU_OPTION_append:
4181 kernel_cmdline = optarg;
4182 break;
4183 case QEMU_OPTION_cdrom:
4184 drive_add(optarg, CDROM_ALIAS);
4185 break;
4186 case QEMU_OPTION_boot:
4187 boot_devices = optarg;
4188 /* We just do some generic consistency checks */
4189 {
4190 /* Could easily be extended to 64 devices if needed */
4191 const char *p;
4192
4193 boot_devices_bitmap = 0;
4194 for (p = boot_devices; *p != '\0'; p++) {
4195 /* Allowed boot devices are:
4196 * a b : floppy disk drives
4197 * c ... f : IDE disk drives
4198 * g ... m : machine implementation dependant drives
4199 * n ... p : network devices
4200 * It's up to each machine implementation to check
4201 * if the given boot devices match the actual hardware
4202 * implementation and firmware features.
4203 */
4204 if (*p < 'a' || *p > 'q') {
4205 fprintf(stderr, "Invalid boot device '%c'\n", *p);
4206 exit(1);
4207 }
4208 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
4209 fprintf(stderr,
4210 "Boot device '%c' was given twice\n",*p);
4211 exit(1);
4212 }
4213 boot_devices_bitmap |= 1 << (*p - 'a');
4214 }
4215 }
4216 break;
4217 case QEMU_OPTION_fda:
4218 case QEMU_OPTION_fdb:
4219 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
4220 break;
4221#ifdef TARGET_I386
4222 case QEMU_OPTION_no_fd_bootchk:
4223 fd_bootchk = 0;
4224 break;
4225#endif
4226 case QEMU_OPTION_net:
4227 if (nb_net_clients >= MAX_NET_CLIENTS) {
4228 fprintf(stderr, "qemu: too many network clients\n");
4229 exit(1);
4230 }
4231 net_clients[nb_net_clients] = optarg;
4232 nb_net_clients++;
4233 break;
4234#ifdef CONFIG_SLIRP
4235 case QEMU_OPTION_tftp:
4236 tftp_prefix = optarg;
4237 break;
4238 case QEMU_OPTION_bootp:
4239 bootp_filename = optarg;
4240 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004241#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004242 case QEMU_OPTION_smb:
4243 net_slirp_smb(optarg);
4244 break;
4245#endif
4246 case QEMU_OPTION_redir:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004247 net_slirp_redir(NULL, optarg, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004248 break;
4249#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004250 case QEMU_OPTION_bt:
4251 if (nb_bt_opts >= MAX_BT_CMDLINE) {
4252 fprintf(stderr, "qemu: too many bluetooth options\n");
4253 exit(1);
4254 }
4255 bt_opts[nb_bt_opts++] = optarg;
4256 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004257#ifdef HAS_AUDIO
4258 case QEMU_OPTION_audio_help:
4259 AUD_help ();
4260 exit (0);
4261 break;
4262 case QEMU_OPTION_soundhw:
4263 select_soundhw (optarg);
4264 break;
4265#endif
4266 case QEMU_OPTION_h:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004267 help(0);
4268 break;
4269 case QEMU_OPTION_version:
4270 version();
4271 exit(0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004272 break;
4273 case QEMU_OPTION_m: {
4274 uint64_t value;
4275 char *ptr;
4276
4277 value = strtoul(optarg, &ptr, 10);
4278 switch (*ptr) {
4279 case 0: case 'M': case 'm':
4280 value <<= 20;
4281 break;
4282 case 'G': case 'g':
4283 value <<= 30;
4284 break;
4285 default:
4286 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
4287 exit(1);
4288 }
4289
4290 /* On 32-bit hosts, QEMU is limited by virtual address space */
4291 if (value > (2047 << 20)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004292#ifndef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004293 && HOST_LONG_BITS == 32
4294#endif
4295 ) {
4296 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
4297 exit(1);
4298 }
4299 if (value != (uint64_t)(ram_addr_t)value) {
4300 fprintf(stderr, "qemu: ram size too large\n");
4301 exit(1);
4302 }
4303 ram_size = value;
4304 break;
4305 }
4306 case QEMU_OPTION_d:
4307 {
4308 int mask;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004309 const CPULogItem *item;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004310
4311 mask = cpu_str_to_log_mask(optarg);
4312 if (!mask) {
4313 printf("Log items (comma separated):\n");
4314 for(item = cpu_log_items; item->mask != 0; item++) {
4315 printf("%-10s %s\n", item->name, item->help);
4316 }
4317 exit(1);
4318 }
4319 cpu_set_log(mask);
4320 }
4321 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004322 case QEMU_OPTION_s:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004323 gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004324 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004325 case QEMU_OPTION_gdb:
4326 gdbstub_dev = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004327 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004328 case QEMU_OPTION_L:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004329 data_dir = optarg;
4330 break;
4331 case QEMU_OPTION_bios:
4332 bios_name = optarg;
4333 break;
4334 case QEMU_OPTION_singlestep:
4335 singlestep = 1;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004336 break;
4337 case QEMU_OPTION_S:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004338 autostart = 0;
4339 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004340#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004341 case QEMU_OPTION_k:
4342 keyboard_layout = optarg;
4343 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004344#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004345 case QEMU_OPTION_localtime:
4346 rtc_utc = 0;
4347 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004348 case QEMU_OPTION_vga:
4349 select_vgahw (optarg);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004350 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004351#if defined(TARGET_PPC) || defined(TARGET_SPARC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004352 case QEMU_OPTION_g:
4353 {
4354 const char *p;
4355 int w, h, depth;
4356 p = optarg;
4357 w = strtol(p, (char **)&p, 10);
4358 if (w <= 0) {
4359 graphic_error:
4360 fprintf(stderr, "qemu: invalid resolution or depth\n");
4361 exit(1);
4362 }
4363 if (*p != 'x')
4364 goto graphic_error;
4365 p++;
4366 h = strtol(p, (char **)&p, 10);
4367 if (h <= 0)
4368 goto graphic_error;
4369 if (*p == 'x') {
4370 p++;
4371 depth = strtol(p, (char **)&p, 10);
4372 if (depth != 8 && depth != 15 && depth != 16 &&
4373 depth != 24 && depth != 32)
4374 goto graphic_error;
4375 } else if (*p == '\0') {
4376 depth = graphic_depth;
4377 } else {
4378 goto graphic_error;
4379 }
4380
4381 graphic_width = w;
4382 graphic_height = h;
4383 graphic_depth = depth;
4384 }
4385 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004386#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004387 case QEMU_OPTION_echr:
4388 {
4389 char *r;
4390 term_escape_char = strtol(optarg, &r, 0);
4391 if (r == optarg)
4392 printf("Bad argument to echr\n");
4393 break;
4394 }
4395 case QEMU_OPTION_monitor:
4396 monitor_device = optarg;
4397 break;
4398 case QEMU_OPTION_serial:
4399 if (serial_device_index >= MAX_SERIAL_PORTS) {
4400 fprintf(stderr, "qemu: too many serial ports\n");
4401 exit(1);
4402 }
4403 serial_devices[serial_device_index] = optarg;
4404 serial_device_index++;
4405 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004406 case QEMU_OPTION_watchdog:
4407 i = select_watchdog(optarg);
4408 if (i > 0)
4409 exit (i == 1 ? 1 : 0);
4410 break;
4411 case QEMU_OPTION_watchdog_action:
4412 if (select_watchdog_action(optarg) == -1) {
4413 fprintf(stderr, "Unknown -watchdog-action parameter\n");
4414 exit(1);
4415 }
4416 break;
4417 case QEMU_OPTION_virtiocon:
4418 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
4419 fprintf(stderr, "qemu: too many virtio consoles\n");
4420 exit(1);
4421 }
4422 virtio_consoles[virtio_console_index] = optarg;
4423 virtio_console_index++;
4424 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004425 case QEMU_OPTION_parallel:
4426 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
4427 fprintf(stderr, "qemu: too many parallel ports\n");
4428 exit(1);
4429 }
4430 parallel_devices[parallel_device_index] = optarg;
4431 parallel_device_index++;
4432 break;
4433 case QEMU_OPTION_loadvm:
4434 loadvm = optarg;
4435 break;
4436 case QEMU_OPTION_full_screen:
4437 full_screen = 1;
4438 break;
4439#ifdef CONFIG_SDL
4440 case QEMU_OPTION_no_frame:
4441 no_frame = 1;
4442 break;
4443 case QEMU_OPTION_alt_grab:
4444 alt_grab = 1;
4445 break;
4446 case QEMU_OPTION_no_quit:
4447 no_quit = 1;
4448 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004449 case QEMU_OPTION_sdl:
4450 display_type = DT_SDL;
4451 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004452#endif
4453 case QEMU_OPTION_pidfile:
4454 pid_file = optarg;
4455 break;
4456#ifdef TARGET_I386
4457 case QEMU_OPTION_win2k_hack:
4458 win2k_install_hack = 1;
4459 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004460 case QEMU_OPTION_rtc_td_hack:
4461 rtc_td_hack = 1;
4462 break;
4463 case QEMU_OPTION_acpitable:
4464 if(acpi_table_add(optarg) < 0) {
4465 fprintf(stderr, "Wrong acpi table provided\n");
4466 exit(1);
4467 }
4468 break;
4469 case QEMU_OPTION_smbios:
4470 if(smbios_entry_add(optarg) < 0) {
4471 fprintf(stderr, "Wrong smbios provided\n");
4472 exit(1);
4473 }
4474 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004475#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004476#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004477 case QEMU_OPTION_no_kqemu:
4478 kqemu_allowed = 0;
4479 break;
4480 case QEMU_OPTION_kernel_kqemu:
4481 kqemu_allowed = 2;
4482 break;
4483#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004484#ifdef CONFIG_KVM
4485 case QEMU_OPTION_enable_kvm:
4486 kvm_allowed = 1;
4487#ifdef CONFIG_KQEMU
4488 kqemu_allowed = 0;
4489#endif
4490 break;
4491#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004492 case QEMU_OPTION_usb:
4493 usb_enabled = 1;
4494 break;
4495 case QEMU_OPTION_usbdevice:
4496 usb_enabled = 1;
4497 if (usb_devices_index >= MAX_USB_CMDLINE) {
4498 fprintf(stderr, "Too many USB devices\n");
4499 exit(1);
4500 }
4501 usb_devices[usb_devices_index] = optarg;
4502 usb_devices_index++;
4503 break;
4504 case QEMU_OPTION_smp:
4505 smp_cpus = atoi(optarg);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004506 if (smp_cpus < 1) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004507 fprintf(stderr, "Invalid number of CPUs\n");
4508 exit(1);
4509 }
4510 break;
4511 case QEMU_OPTION_vnc:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004512 display_type = DT_VNC;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004513 vnc_display = optarg;
4514 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004515#ifdef TARGET_I386
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004516 case QEMU_OPTION_no_acpi:
4517 acpi_enabled = 0;
4518 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004519 case QEMU_OPTION_no_hpet:
4520 no_hpet = 1;
4521 break;
4522 case QEMU_OPTION_no_virtio_balloon:
4523 no_virtio_balloon = 1;
4524 break;
4525#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004526 case QEMU_OPTION_no_reboot:
4527 no_reboot = 1;
4528 break;
4529 case QEMU_OPTION_no_shutdown:
4530 no_shutdown = 1;
4531 break;
4532 case QEMU_OPTION_show_cursor:
4533 cursor_hide = 0;
4534 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004535 case QEMU_OPTION_uuid:
4536 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
4537 fprintf(stderr, "Fail to parse UUID string."
4538 " Wrong format.\n");
4539 exit(1);
4540 }
4541 break;
4542#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004543 case QEMU_OPTION_daemonize:
4544 daemonize = 1;
4545 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004546#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004547 case QEMU_OPTION_option_rom:
4548 if (nb_option_roms >= MAX_OPTION_ROMS) {
4549 fprintf(stderr, "Too many option ROMs\n");
4550 exit(1);
4551 }
4552 option_rom[nb_option_roms] = optarg;
4553 nb_option_roms++;
4554 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004555#if defined(TARGET_ARM) || defined(TARGET_M68K)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004556 case QEMU_OPTION_semihosting:
4557 semihosting_enabled = 1;
4558 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004559#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004560 case QEMU_OPTION_name:
4561 qemu_name = optarg;
4562 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004563#if defined(TARGET_SPARC) || defined(TARGET_PPC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004564 case QEMU_OPTION_prom_env:
4565 if (nb_prom_envs >= MAX_PROM_ENVS) {
4566 fprintf(stderr, "Too many prom variables\n");
4567 exit(1);
4568 }
4569 prom_envs[nb_prom_envs] = optarg;
4570 nb_prom_envs++;
4571 break;
4572#endif
4573#ifdef TARGET_ARM
4574 case QEMU_OPTION_old_param:
4575 old_param = 1;
4576 break;
4577#endif
4578 case QEMU_OPTION_clock:
4579 configure_alarms(optarg);
4580 break;
4581 case QEMU_OPTION_startdate:
4582 {
4583 struct tm tm;
4584 time_t rtc_start_date;
4585 if (!strcmp(optarg, "now")) {
4586 rtc_date_offset = -1;
4587 } else {
4588 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
4589 &tm.tm_year,
4590 &tm.tm_mon,
4591 &tm.tm_mday,
4592 &tm.tm_hour,
4593 &tm.tm_min,
4594 &tm.tm_sec) == 6) {
4595 /* OK */
4596 } else if (sscanf(optarg, "%d-%d-%d",
4597 &tm.tm_year,
4598 &tm.tm_mon,
4599 &tm.tm_mday) == 3) {
4600 tm.tm_hour = 0;
4601 tm.tm_min = 0;
4602 tm.tm_sec = 0;
4603 } else {
4604 goto date_fail;
4605 }
4606 tm.tm_year -= 1900;
4607 tm.tm_mon--;
4608 rtc_start_date = mktimegm(&tm);
4609 if (rtc_start_date == -1) {
4610 date_fail:
4611 fprintf(stderr, "Invalid date format. Valid format are:\n"
4612 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
4613 exit(1);
4614 }
4615 rtc_date_offset = time(NULL) - rtc_start_date;
4616 }
4617 }
4618 break;
4619 case QEMU_OPTION_tb_size:
4620 tb_size = strtol(optarg, NULL, 0);
4621 if (tb_size < 0)
4622 tb_size = 0;
4623 break;
4624 case QEMU_OPTION_icount:
David Turner6a9ef172010-09-09 22:54:36 +02004625 icount_option = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004626 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004627 case QEMU_OPTION_incoming:
4628 incoming = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004629 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004630#ifndef _WIN32
4631 case QEMU_OPTION_chroot:
4632 chroot_dir = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004633 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004634 case QEMU_OPTION_runas:
4635 run_as = optarg;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004636 break;
4637#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004638#ifdef CONFIG_XEN
4639 case QEMU_OPTION_xen_domid:
4640 xen_domid = atoi(optarg);
4641 break;
4642 case QEMU_OPTION_xen_create:
4643 xen_mode = XEN_CREATE;
4644 break;
4645 case QEMU_OPTION_xen_attach:
4646 xen_mode = XEN_ATTACH;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004647 break;
4648#endif
4649 }
4650 }
4651 }
4652
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004653 /* If no data_dir is specified then try to find it relative to the
4654 executable path. */
4655 if (!data_dir) {
4656 data_dir = find_datadir(argv[0]);
4657 }
4658 /* If all else fails use the install patch specified when building. */
4659 if (!data_dir) {
4660 data_dir = CONFIG_QEMU_SHAREDIR;
4661 }
4662
4663#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
4664 if (kvm_allowed && kqemu_allowed) {
4665 fprintf(stderr,
4666 "You can not enable both KVM and kqemu at the same time\n");
4667 exit(1);
4668 }
4669#endif
4670
4671 machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
4672 if (smp_cpus > machine->max_cpus) {
4673 fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
4674 "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
4675 machine->max_cpus);
4676 exit(1);
4677 }
4678
4679 if (display_type == DT_NOGRAPHIC) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004680 if (serial_device_index == 0)
4681 serial_devices[0] = "stdio";
4682 if (parallel_device_index == 0)
4683 parallel_devices[0] = "null";
4684 if (strncmp(monitor_device, "vc", 2) == 0)
4685 monitor_device = "stdio";
4686 }
4687
4688#ifndef _WIN32
4689 if (daemonize) {
4690 pid_t pid;
4691
4692 if (pipe(fds) == -1)
4693 exit(1);
4694
4695 pid = fork();
4696 if (pid > 0) {
4697 uint8_t status;
4698 ssize_t len;
4699
4700 close(fds[1]);
4701
4702 again:
4703 len = read(fds[0], &status, 1);
4704 if (len == -1 && (errno == EINTR))
4705 goto again;
4706
4707 if (len != 1)
4708 exit(1);
4709 else if (status == 1) {
4710 fprintf(stderr, "Could not acquire pidfile\n");
4711 exit(1);
4712 } else
4713 exit(0);
4714 } else if (pid < 0)
4715 exit(1);
4716
4717 setsid();
4718
4719 pid = fork();
4720 if (pid > 0)
4721 exit(0);
4722 else if (pid < 0)
4723 exit(1);
4724
4725 umask(027);
4726
4727 signal(SIGTSTP, SIG_IGN);
4728 signal(SIGTTOU, SIG_IGN);
4729 signal(SIGTTIN, SIG_IGN);
4730 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004731
4732 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
4733 if (daemonize) {
4734 uint8_t status = 1;
4735 write(fds[1], &status, 1);
4736 } else
4737 fprintf(stderr, "Could not acquire pid file\n");
4738 exit(1);
4739 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004740#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004741
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004742#ifdef CONFIG_KQEMU
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004743 if (smp_cpus > 1)
4744 kqemu_allowed = 0;
4745#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004746 if (qemu_init_main_loop()) {
4747 fprintf(stderr, "qemu_init_main_loop failed\n");
4748 exit(1);
4749 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004750 linux_boot = (kernel_filename != NULL);
4751 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
4752
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004753 if (!linux_boot && *kernel_cmdline != '\0') {
4754 fprintf(stderr, "-append only allowed with -kernel option\n");
4755 exit(1);
4756 }
4757
4758 if (!linux_boot && initrd_filename != NULL) {
4759 fprintf(stderr, "-initrd only allowed with -kernel option\n");
4760 exit(1);
4761 }
4762
4763 /* boot to floppy or the default cd if no hard disk defined yet */
4764 if (!boot_devices[0]) {
4765 boot_devices = "cad";
4766 }
4767 setvbuf(stdout, NULL, _IOLBF, 0);
4768
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004769 if (init_timer_alarm() < 0) {
4770 fprintf(stderr, "could not initialize alarm timer\n");
4771 exit(1);
4772 }
David Turner6a9ef172010-09-09 22:54:36 +02004773 configure_icount(icount_option);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004774
4775#ifdef _WIN32
4776 socket_init();
4777#endif
4778
4779 /* init network clients */
4780 if (nb_net_clients == 0) {
4781 /* if no clients, we use a default config */
4782 net_clients[nb_net_clients++] = "nic";
4783#ifdef CONFIG_SLIRP
4784 net_clients[nb_net_clients++] = "user";
4785#endif
4786 }
4787
4788 for(i = 0;i < nb_net_clients; i++) {
4789 if (net_client_parse(net_clients[i]) < 0)
4790 exit(1);
4791 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004792 net_client_check();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004793
4794#ifdef TARGET_I386
4795 /* XXX: this should be moved in the PC machine instantiation code */
4796 if (net_boot != 0) {
4797 int netroms = 0;
4798 for (i = 0; i < nb_nics && i < 4; i++) {
4799 const char *model = nd_table[i].model;
4800 char buf[1024];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004801 char *filename;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004802 if (net_boot & (1 << i)) {
4803 if (model == NULL)
4804 model = "ne2k_pci";
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004805 snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
4806 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
4807 if (filename && get_image_size(filename) > 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004808 if (nb_option_roms >= MAX_OPTION_ROMS) {
4809 fprintf(stderr, "Too many option ROMs\n");
4810 exit(1);
4811 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004812 option_rom[nb_option_roms] = qemu_strdup(buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004813 nb_option_roms++;
4814 netroms++;
4815 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004816 if (filename) {
4817 qemu_free(filename);
4818 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004819 }
4820 }
4821 if (netroms == 0) {
4822 fprintf(stderr, "No valid PXE rom found for network device\n");
4823 exit(1);
4824 }
4825 }
4826#endif
4827
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004828 /* init the bluetooth world */
4829 for (i = 0; i < nb_bt_opts; i++)
4830 if (bt_parse(bt_opts[i]))
4831 exit(1);
4832
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004833 /* init the memory */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004834 if (ram_size == 0)
4835 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004836
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004837#ifdef CONFIG_KQEMU
4838 /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
4839 guest ram allocation. It needs to go away. */
4840 if (kqemu_allowed) {
4841 kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
4842 kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
4843 if (!kqemu_phys_ram_base) {
4844 fprintf(stderr, "Could not allocate physical memory\n");
4845 exit(1);
4846 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004847 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004848#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004849
4850 /* init the dynamic translator */
4851 cpu_exec_init_all(tb_size * 1024 * 1024);
4852
4853 bdrv_init();
4854
4855 /* we always create the cdrom drive, even if no disk is there */
4856
4857 if (nb_drives_opt < MAX_DRIVES)
4858 drive_add(NULL, CDROM_ALIAS);
4859
4860 /* we always create at least one floppy */
4861
4862 if (nb_drives_opt < MAX_DRIVES)
4863 drive_add(NULL, FD_ALIAS, 0);
4864
4865 /* we always create one sd slot, even if no card is in it */
4866
4867 if (nb_drives_opt < MAX_DRIVES)
4868 drive_add(NULL, SD_ALIAS);
4869
4870 /* open the virtual block devices */
4871
4872 for(i = 0; i < nb_drives_opt; i++)
4873 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
4874 exit(1);
4875
David Turner6a9ef172010-09-09 22:54:36 +02004876 //register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004877 register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004878
4879#ifndef _WIN32
4880 /* must be after terminal init, SDL library changes signal handlers */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004881 sighandler_setup();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004882#endif
4883
4884 /* Maintain compatibility with multiple stdio monitors */
4885 if (!strcmp(monitor_device,"stdio")) {
4886 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
4887 const char *devname = serial_devices[i];
4888 if (devname && !strcmp(devname,"mon:stdio")) {
4889 monitor_device = NULL;
4890 break;
4891 } else if (devname && !strcmp(devname,"stdio")) {
4892 monitor_device = NULL;
4893 serial_devices[i] = "mon:stdio";
4894 break;
4895 }
4896 }
4897 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004898
4899 if (nb_numa_nodes > 0) {
4900 int i;
4901
4902 if (nb_numa_nodes > smp_cpus) {
4903 nb_numa_nodes = smp_cpus;
4904 }
4905
4906 /* If no memory size if given for any node, assume the default case
4907 * and distribute the available memory equally across all nodes
4908 */
4909 for (i = 0; i < nb_numa_nodes; i++) {
4910 if (node_mem[i] != 0)
4911 break;
4912 }
4913 if (i == nb_numa_nodes) {
4914 uint64_t usedmem = 0;
4915
4916 /* On Linux, the each node's border has to be 8MB aligned,
4917 * the final node gets the rest.
4918 */
4919 for (i = 0; i < nb_numa_nodes - 1; i++) {
4920 node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
4921 usedmem += node_mem[i];
4922 }
4923 node_mem[i] = ram_size - usedmem;
4924 }
4925
4926 for (i = 0; i < nb_numa_nodes; i++) {
4927 if (node_cpumask[i] != 0)
4928 break;
4929 }
4930 /* assigning the VCPUs round-robin is easier to implement, guest OSes
4931 * must cope with this anyway, because there are BIOSes out there in
4932 * real machines which also use this scheme.
4933 */
4934 if (i == nb_numa_nodes) {
4935 for (i = 0; i < smp_cpus; i++) {
4936 node_cpumask[i % nb_numa_nodes] |= 1 << i;
4937 }
4938 }
4939 }
4940
4941 if (kvm_enabled()) {
4942 int ret;
4943
4944 ret = kvm_init(smp_cpus);
4945 if (ret < 0) {
4946 fprintf(stderr, "failed to initialize KVM\n");
4947 exit(1);
4948 }
4949 }
4950
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004951 if (monitor_device) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004952 monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004953 if (!monitor_hd) {
4954 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
4955 exit(1);
4956 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004957 }
4958
4959 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
4960 const char *devname = serial_devices[i];
4961 if (devname && strcmp(devname, "none")) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004962 char label[32];
4963 snprintf(label, sizeof(label), "serial%d", i);
4964 serial_hds[i] = qemu_chr_open(label, devname, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08004965 if (!serial_hds[i]) {
4966 fprintf(stderr, "qemu: could not open serial device '%s'\n",
4967 devname);
4968 exit(1);
4969 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07004970 }
4971 }
4972
4973 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
4974 const char *devname = parallel_devices[i];
4975 if (devname && strcmp(devname, "none")) {
4976 char label[32];
4977 snprintf(label, sizeof(label), "parallel%d", i);
4978 parallel_hds[i] = qemu_chr_open(label, devname, NULL);
4979 if (!parallel_hds[i]) {
4980 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
4981 devname);
4982 exit(1);
4983 }
4984 }
4985 }
4986
4987 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
4988 const char *devname = virtio_consoles[i];
4989 if (devname && strcmp(devname, "none")) {
4990 char label[32];
4991 snprintf(label, sizeof(label), "virtcon%d", i);
4992 virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
4993 if (!virtcon_hds[i]) {
4994 fprintf(stderr, "qemu: could not open virtio console '%s'\n",
4995 devname);
4996 exit(1);
4997 }
4998 }
4999 }
5000
5001 module_call_init(MODULE_INIT_DEVICE);
5002
5003 machine->init(ram_size, boot_devices,
5004 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
5005
5006
5007 for (env = first_cpu; env != NULL; env = env->next_cpu) {
5008 for (i = 0; i < nb_numa_nodes; i++) {
5009 if (node_cpumask[i] & (1 << env->cpu_index)) {
5010 env->numa_node = i;
5011 }
5012 }
5013 }
5014
5015 current_machine = machine;
5016
5017 /* Set KVM's vcpu state to qemu's initial CPUState. */
5018 if (kvm_enabled()) {
5019 int ret;
5020
5021 ret = kvm_sync_vcpus();
5022 if (ret < 0) {
5023 fprintf(stderr, "failed to initialize vcpus\n");
5024 exit(1);
5025 }
5026 }
5027
5028 /* init USB devices */
5029 if (usb_enabled) {
5030 for(i = 0; i < usb_devices_index; i++) {
5031 if (usb_device_add(usb_devices[i], 0) < 0) {
5032 fprintf(stderr, "Warning: could not add USB device %s\n",
5033 usb_devices[i]);
5034 }
5035 }
5036 }
5037
5038 if (!display_state)
5039 dumb_display_init();
5040 /* just use the first displaystate for the moment */
5041 ds = display_state;
5042
5043 if (display_type == DT_DEFAULT) {
5044#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
5045 display_type = DT_SDL;
5046#else
5047 display_type = DT_VNC;
5048 vnc_display = "localhost:0,to=99";
5049 show_vnc_port = 1;
5050#endif
5051 }
5052
5053
5054 switch (display_type) {
5055 case DT_NOGRAPHIC:
5056 break;
5057#if defined(CONFIG_CURSES)
5058 case DT_CURSES:
5059 curses_display_init(ds, full_screen);
5060 break;
5061#endif
5062#if defined(CONFIG_SDL)
5063 case DT_SDL:
5064 sdl_display_init(ds, full_screen, no_frame);
5065 break;
5066#elif defined(CONFIG_COCOA)
5067 case DT_SDL:
5068 cocoa_display_init(ds, full_screen);
5069 break;
5070#endif
5071 case DT_VNC:
5072 vnc_display_init(ds);
5073 if (vnc_display_open(ds, vnc_display) < 0)
5074 exit(1);
5075
5076 if (show_vnc_port) {
5077 printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
5078 }
5079 break;
5080 default:
5081 break;
5082 }
5083 dpy_resize(ds);
5084
5085 dcl = ds->listeners;
5086 while (dcl != NULL) {
5087 if (dcl->dpy_refresh != NULL) {
5088 ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
5089 qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
5090 }
5091 dcl = dcl->next;
5092 }
5093
5094 if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
5095 nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
5096 qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
5097 }
5098
5099 text_consoles_set_display(display_state);
5100 qemu_chr_initial_reset();
5101
5102 if (monitor_device && monitor_hd)
5103 monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
5104
5105 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
5106 const char *devname = serial_devices[i];
5107 if (devname && strcmp(devname, "none")) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005108 if (strstart(devname, "vc", 0))
5109 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
5110 }
5111 }
5112
5113 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
5114 const char *devname = parallel_devices[i];
5115 if (devname && strcmp(devname, "none")) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005116 if (strstart(devname, "vc", 0))
5117 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
5118 }
5119 }
5120
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005121 for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
5122 const char *devname = virtio_consoles[i];
5123 if (virtcon_hds[i] && devname) {
5124 if (strstart(devname, "vc", 0))
5125 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005126 }
5127 }
5128
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005129 if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
5130 fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
5131 gdbstub_dev);
5132 exit(1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005133 }
5134
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005135 if (loadvm)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005136 do_loadvm(cur_mon, loadvm);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005137
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005138 if (incoming) {
5139 autostart = 0; /* fixme how to deal with -daemonize */
5140 qemu_start_incoming_migration(incoming);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005141 }
5142
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005143 if (autostart)
5144 vm_start();
5145
5146#ifndef _WIN32
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005147 if (daemonize) {
5148 uint8_t status = 0;
5149 ssize_t len;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005150
5151 again1:
5152 len = write(fds[1], &status, 1);
5153 if (len == -1 && (errno == EINTR))
5154 goto again1;
5155
5156 if (len != 1)
5157 exit(1);
5158
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005159 if (chdir("/")) {
5160 perror("not able to chdir to /");
5161 exit(1);
5162 }
5163 TFR(fd = qemu_open("/dev/null", O_RDWR));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005164 if (fd == -1)
5165 exit(1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005166 }
5167
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005168 if (run_as) {
5169 pwd = getpwnam(run_as);
5170 if (!pwd) {
5171 fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
5172 exit(1);
5173 }
5174 }
5175
5176 if (chroot_dir) {
5177 if (chroot(chroot_dir) < 0) {
5178 fprintf(stderr, "chroot failed\n");
5179 exit(1);
5180 }
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -07005181 if (chdir("/")) {
5182 perror("not able to chdir to /");
5183 exit(1);
5184 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005185 }
5186
5187 if (run_as) {
5188 if (setgid(pwd->pw_gid) < 0) {
5189 fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
5190 exit(1);
5191 }
5192 if (setuid(pwd->pw_uid) < 0) {
5193 fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
5194 exit(1);
5195 }
5196 if (setuid(0) != -1) {
5197 fprintf(stderr, "Dropping privileges failed\n");
5198 exit(1);
5199 }
5200 }
5201
5202 if (daemonize) {
5203 dup2(fd, 0);
5204 dup2(fd, 1);
5205 dup2(fd, 2);
5206
5207 close(fd);
5208 }
5209#endif
5210
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005211 main_loop();
5212 quit_timers();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07005213 net_cleanup();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005214
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08005215 return 0;
5216}