15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * QEMU System Emulator
35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 2003-2008 Fabrice Bellard
55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Permission is hereby granted, free of charge, to any person obtaining a copy
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * of this software and associated documentation files (the "Software"), to deal
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * in the Software without restriction, including without limitation the rights
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * copies of the Software, and to permit persons to whom the Software is
115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * furnished to do so, subject to the following conditions:
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The above copyright notice and this permission notice shall be included in
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * all copies or substantial portions of the Software.
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * THE SOFTWARE.
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* the following is needed on Linux to define ptsname() in stdlib.h */
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__)
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define _GNU_SOURCE 1
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/hw.h"
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/boards.h"
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/usb.h"
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pcmcia.h"
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pc.h"
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/audiodev.h"
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/isa.h"
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/baum.h"
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/goldfish_nand.h"
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "net.h"
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "console.h"
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "sysemu.h"
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "gdbstub.h"
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-timer.h"
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-char.h"
46cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#include "blockdev.h"
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio/audio.h"
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu_file.h"
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "android/android.h"
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "charpipe.h"
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "modem_driver.h"
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "android/gps.h"
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "android/hw-kmsg.h"
55c0ac73377011befa8a3e6444d61a80cd6ada2659David 'Digit' Turner#include "android/hw-pipe-net.h"
56c0ac73377011befa8a3e6444d61a80cd6ada2659David 'Digit' Turner#include "android/hw-qemud.h"
57c646f5e40ddda3d49b581ac0c78cf748b5dee74cVladimir Chtchetkine#include "android/camera/camera-service.h"
588dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine#include "android/multitouch-port.h"
59eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#include "android/charmap.h"
60074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#include "android/globals.h"
61b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine#include "android/utils/bufprint.h"
625f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner#include "android/utils/debug.h"
6348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner#include "android/utils/filelock.h"
6448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner#include "android/utils/path.h"
655f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner#include "android/utils/stralloc.h"
6640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner#include "android/utils/tempfile.h"
6772d83df9865cf8f5393a41fc3f6e283ab6aaa81bVladimir Chtchetkine#include "android/display-core.h"
6890c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine#include "android/utils/timezone.h"
69bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner#include "android/snapshot.h"
70cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner#include "android/opengles.h"
711a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine#include "android/multitouch-screen.h"
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "targphys.h"
73318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine#include "tcpdump.h"
745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
75b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
76b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#include "memcheck/memcheck.h"
77b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
78b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <unistd.h>
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <fcntl.h>
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <signal.h>
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <time.h>
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <errno.h>
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/time.h>
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <zlib.h>
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
872c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner/* Needed early for CONFIG_BSD etc. */
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config-host.h"
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libgen.h>
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/times.h>
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/wait.h>
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <termios.h>
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/mman.h>
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ioctl.h>
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/resource.h>
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/socket.h>
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__NetBSD__)
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if_tap.h>
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/if_tun.h>
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <arpa/inet.h>
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <dirent.h>
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netdb.h>
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/select.h>
1112c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_BSD
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__FreeBSD__) || defined(__DragonFly__)
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libutil.h>
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <freebsd/stdlib.h>
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <pty.h>
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/rtc.h>
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* For the benefit of older linux systems which don't supply it,
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   we use a local copy of hpet.h. */
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #include <linux/hpet.h> */
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hpet.h"
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/ppdev.h>
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/parport.h>
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __sun__
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ethernet.h>
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/sockio.h>
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/arp.h>
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in_systm.h>
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip.h>
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip_icmp.h> // must come after ip.h
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/udp.h>
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/tcp.h>
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <syslog.h>
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <stropts.h>
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__OpenBSD__)
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_VDE)
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libvdeplug.h>
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <windows.h>
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/timeb.h>
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <mmsystem.h>
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define getopt_long_only getopt_long
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define memalign(align, size) malloc(size)
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16923ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner#include "cpus.h"
170ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner#include "arch_init.h"
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_COCOA
173ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turnerint qemu_main(int argc, char **argv, char **envp);
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_COCOA */
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/hw.h"
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/boards.h"
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/usb.h"
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pcmcia.h"
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pc.h"
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/isa.h"
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/baum.h"
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/bt.h"
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/watchdog.h"
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/smbios.h"
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/xen.h"
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "bt-host.h"
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "net.h"
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "console.h"
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "sysemu.h"
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "gdbstub.h"
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-timer.h"
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-char.h"
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "cache-utils.h"
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block.h"
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "dma.h"
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio/audio.h"
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "migration.h"
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "kvm.h"
203a381ef07088ce479610129e37bfef42538f397daJun Nakajima#include "hax.h"
20436597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#ifdef CONFIG_KVM
20536597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#include "kvm-android.h"
20636597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#endif
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "balloon.h"
208b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine#include "android/hw-lcd.h"
209b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine#include "android/boot-properties.h"
210ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner#include "android/hw-control.h"
2117746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#include "android/core-init-utils.h"
212ca29fbbb188a1aab9b69776d5dc6bc3e7f812a0aDavid 'Digit' Turner#include "android/audio-test.h"
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
214db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine#include "android/snaphost-android.h"
215db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
216eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
217eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine/* Verbose value used by the standalone emulator core (without UI) */
218eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineunsigned long   android_verbose;
219eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
220eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
2215758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine#if !defined(CONFIG_STANDALONE_CORE)
2225758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine/* in android/qemulator.c */
2235758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkineextern void  android_emulator_set_base_port(int  port);
2245758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine#endif
2255758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine
22643552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "disas.h"
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
234406a59bd0a2e7a38cd840a5c08602e3a36bd2df8David 'Digit' Turner#include "android-trace.h"
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu_socket.h"
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "libslirp.h"
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFAULT_RAM_SIZE 128
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of USB devices that can be specified on the commandline.  */
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_USB_CMDLINE 8
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of bluetooth switches on the commandline.  */
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_BT_CMDLINE 10
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: use a two level table to limit memory usage */
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const char *data_dir;
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *bios_name = NULL;
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *ioport_opaque[MAX_IOPORTS];
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
258cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef MAX_DRIVES
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   to store the VM snapshots */
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDriveInfo drives_table[MAX_DRIVES+1];
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives;
263cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayType display_type = DT_DEFAULT;
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char* keyboard_layout = NULL;
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t ticks_per_sec;
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t ram_size;
269280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerconst char *mem_path = NULL;
270280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#ifdef MAP_POPULATE
271280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerint mem_prealloc = 0; /* force preallocation of physical target memory */
272280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#endif
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_nics;
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerNICInfo nd_table[MAX_NICS];
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vm_running;
276cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerint autostart;
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_utc = 1;
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_date_offset = -1; /* -1 means no change */
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cirrus_vga_enabled = 1;
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint std_vga_enabled = 0;
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vmsvga_enabled = 0;
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint xenfb_enabled = 0;
283a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' TurnerQEMUClock *rtc_clock;
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int full_screen = 0;
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int no_frame = 0;
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_quit = 0;
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *serial_hds[MAX_SERIAL_PORTS];
290062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerint              serial_hds_count;
291062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint win2k_install_hack = 0;
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint rtc_td_hack = 0;
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_enabled = 0;
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint singlestep = 0;
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint smp_cpus = 1;
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *vnc_display;
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint acpi_enabled = 1;
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_hpet = 0;
304a381ef07088ce479610129e37bfef42538f397daJun Nakajimaint hax_disabled = 0;
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_virtio_balloon = 0;
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint fd_bootchk = 1;
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_reboot = 0;
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_shutdown = 0;
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cursor_hide = 1;
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_rotate = 0;
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerWatchdogTimerModel *watchdog = NULL;
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint watchdog_action = WDT_RESET;
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *option_rom[MAX_OPTION_ROMS];
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_option_roms;
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint semihosting_enabled = 0;
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint old_param = 0;
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *qemu_name;
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint alt_grab = 0;
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned int nb_prom_envs = 0;
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *prom_envs[MAX_PROM_ENVS];
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
325cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef MAX_DRIVES
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives_opt;
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct drive_opt drives_opt[MAX_DRIVES];
328cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_numa_nodes;
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_mem[MAX_NODES];
3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_cpumask[MAX_NODES];
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUTimer *nographic_timer;
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint8_t qemu_uuid[16];
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
338b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkineint   qemu_cpu_delay;
3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern char* audio_input_source;
3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
341d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_ports;
342d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_port;
343d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_report_console;
344d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* op_http_proxy;
34543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine// Path to the file containing specific key character map.
34643552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkinechar* op_charmap_file = NULL;
347d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
348074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine/* Path to hardware initialization file passed with -android-hw option. */
349074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkinechar* android_op_hwini = NULL;
350074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
351b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine/* Memory checker options. */
352b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkinechar* android_op_memcheck = NULL;
353b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
3547fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine/* -dns-server option value. */
3557fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinechar* android_op_dns_server = NULL;
3567fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
35713f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine/* -radio option value. */
358b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_radio = NULL;
359b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
360b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -gps option value. */
361b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_gps = NULL;
362b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
363b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio option value. */
364b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio = NULL;
365b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
366b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -cpu-delay option value. */
367b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_cpu_delay = NULL;
368b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
369e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
370e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -nand-limits option value. */
371e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_nand_limits = NULL;
372e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
373e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
374e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netspeed option value. */
375e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_netspeed = NULL;
376e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
377e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netdelay option value. */
378e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_netdelay = NULL;
379e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
380e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netfast option value. */
381e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkineint android_op_netfast = 0;
382e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
383318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine/* -tcpdump option value. */
384318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkinechar* android_op_tcpdump = NULL;
385318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
386b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine/* -lcd-density option value. */
387b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkinechar* android_op_lcd_density = NULL;
388b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
3897746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* -ui-port option value. This port will be used to report the core
3907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * initialization completion.
3917746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine */
3927746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinechar* android_op_ui_port = NULL;
3937746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
3947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* -ui-settings option value. This value will be passed to the UI when new UI
3957746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * process is attaching to the core.
3967746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine */
3977746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkinechar* android_op_ui_settings = NULL;
3987746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
39990c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine/* -android-avdname option value. */
40090c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkinechar* android_op_avd_name = "unknown";
40190c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine
402dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_width;
403dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_height;
404dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_bpp;
405dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern void  dprint( const char* format, ... );
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
408d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsconst char* dns_log_filename = NULL;
409d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsconst char* drop_log_filename = NULL;
410d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsstatic int rotate_logs_requested = 0;
411d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
41224204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstockconst char* savevm_on_exit = NULL;
41324204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4167746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* Reports the core initialization failure to the error stdout and to the UI
4177746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * socket before exiting the application.
4187746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * Parameters that are passed to this macro are used to format the error
4197746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine * mesage using sprintf routine.
4207746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine */
4217746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#ifdef CONFIG_ANDROID
4227746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#define  PANIC(...) android_core_init_failure(__VA_ARGS__)
4237746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#else
4247746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#define  PANIC(...) do { fprintf(stderr, __VA_ARGS__);  \
4257746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                         exit(1);                       \
4267746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    } while (0)
4277746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#endif  // CONFIG_ANDROID
4287746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
4297746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine/* Exits the core during initialization. */
4307746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#ifdef CONFIG_ANDROID
4317746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#define  QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
4327746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#else
4337746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#define  QEMU_EXIT(exit_code) exit(exit_code)
4347746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#endif  // CONFIG_ANDROID
4357746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* x86 ISA bus support */
4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertarget_phys_addr_t isa_mem_base = 0;
4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerPicState2 *isa_pic;
4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t ioport_read(int index, uint32_t address)
4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortReadFunc *default_func[3] = {
4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readb,
4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readw,
4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readl
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortReadFunc *func = ioport_read_table[index][address];
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return func(ioport_opaque[address], address);
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void ioport_write(int index, uint32_t address, uint32_t data)
4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortWriteFunc *default_func[3] = {
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writeb,
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writew,
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writel
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortWriteFunc *func = ioport_write_table[index][address];
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    func(ioport_opaque[address], address, data);
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readb(void *opaque, uint32_t address)
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inb: port=0x%04x\n", address);
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xff;
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* default is to make two byte accesses */
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readw(void *opaque, uint32_t address)
4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t data;
4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data = ioport_read(0, address);
4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data |= ioport_read(0, address) << 8;
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return data;
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, data & 0xff);
4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, (data >> 8) & 0xff);
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readl(void *opaque, uint32_t address)
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inl: port=0x%04x\n", address);
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xffffffff;
5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
518d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings/*
519d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * Sets a flag (rotate_logs_requested) to clear both the DNS and the
520d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * drop logs upon receiving a SIGUSR1 signal. We need to clear the logs
521d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * between the tasks that do not require restarting Qemu.
522d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings */
523d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsvoid rotate_qemu_logs_handler(int signum) {
524d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  rotate_logs_requested = 1;
525d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings}
526d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
527d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings/*
528d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * Resets the rotate_log_requested_flag. Normally called after qemu
529d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * logs has been rotated.
530d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings */
531d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsvoid reset_rotate_qemu_logs_request(void) {
532d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  rotate_logs_requested = 0;
533d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings}
534d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
535d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings/*
536d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * Clears the passed qemu log when the rotate_logs_requested
537d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * is set. We need to clear the logs between the tasks that do not
538d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * require restarting Qemu.
539d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings */
540d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsFILE* rotate_qemu_log(FILE* old_log_fd, const char* filename) {
541d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  FILE* new_log_fd = NULL;
542d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  if (old_log_fd) {
543d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    if (fclose(old_log_fd) == -1) {
544d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings      fprintf(stderr, "Cannot close old_log fd\n");
545d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings      exit(errno);
546d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    }
547d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  }
548d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
549d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  if (!filename) {
550d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    fprintf(stderr, "The log filename to be rotated is not provided");
551d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    exit(-1);
552d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  }
553d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
554d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  new_log_fd = fopen(filename , "wb+");
555d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  if (new_log_fd == NULL) {
556d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    fprintf(stderr, "Cannot open the log file: %s for write.\n",
557d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings            filename);
558d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    exit(1);
559d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  }
560d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
561d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  return new_log_fd;
562d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings}
563d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***************/
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ballooning */
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUBalloonEvent *qemu_balloon_event;
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid *qemu_balloon_event_opaque;
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event = func;
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event_opaque = opaque;
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_balloon(ram_addr_t target)
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_balloon_event(qemu_balloon_event_opaque, target);
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t qemu_balloon_status(void)
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_balloon_event(qemu_balloon_event_opaque, 0);
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* host time/date access */
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_get_timedate(struct tm *tm, int offset)
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t ti;
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct tm *ret;
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time(&ti);
5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ti += offset;
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1) {
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = gmtime(&ti);
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = localtime(&ti);
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ti -= rtc_date_offset;
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = gmtime(&ti);
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memcpy(tm, ret, sizeof(struct tm));
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_timedate_diff(struct tm *tm)
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t seconds;
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1)
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktimegm(tm);
6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktime(tm);
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        seconds = mktimegm(tm) + rtc_date_offset;
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return seconds - time(NULL);
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
62823ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint tbflush_requested;
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int exit_requested;
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid start_tracing()
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!tracing) {
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- start tracing --\n");
6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_time = Now();
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 1;
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid stop_tracing()
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (tracing) {
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    end_time = Now();
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    elapsed_usecs += end_time - start_time;
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- stop tracing --\n");
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 0;
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * SIGUSR1 turns tracing on.  SIGUSR2 turns tracing off.
6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigusr_handler(int sig)
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (sig == SIGUSR1)
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_tracing();
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  else
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stop_tracing();
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler to catch control-C so that we can exit cleanly.
6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This is needed when tracing to flush the buffers to disk.
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigint_handler(int sig)
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  exit_requested = 1;
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_TRACE */
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Bluetooth support */
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int nb_hcis;
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cur_hci;
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_table[MAX_NICS];
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_vlan_s {
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s net;
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int id;
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s *next;
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *first_bt_vlan;
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* find or alloc a new bluetooth "VLAN" */
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_scatternet_s *qemu_find_bt_vlan(int id)
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s **pvlan, *vlan;
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan->id == id)
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return &vlan->net;
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan->id = id;
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pvlan = &first_bt_vlan;
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pvlan != NULL)
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pvlan = &(*pvlan)->next;
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pvlan = vlan;
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return &vlan->net;
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -ENOTSUP;
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo null_hci = {
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .cmd_send = null_hci_send,
7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .sco_send = null_hci_send,
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .acl_send = null_hci_send,
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdaddr_set = null_hci_addr_set,
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct HCIInfo *qemu_next_hci(void)
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cur_hci == nb_hcis)
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return hci_table[cur_hci++];
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_init(const char *str)
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp;
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = 0;
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(str, "null"))
7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* null */
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* host[:hciN] */
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_host_hci(str[4] ? str + 5 : "hci0");
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "hci", 3)) {
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* hci[,vlan=n] */
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (str[3]) {
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!strncmp(str + 3, ",vlan=", 6)) {
7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endp)
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = 0;
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vlan = qemu_find_bt_vlan(0);
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan)
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return bt_new_hci(vlan);
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_hci_parse(const char *str)
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct HCIInfo *hci;
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr_t bdaddr;
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_hcis >= MAX_NICS) {
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci = hci_init(str);
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!hci)
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[0] = 0x52;
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[1] = 0x54;
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[2] = 0x00;
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[3] = 0x12;
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[4] = 0x34;
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[5] = 0x56 + nb_hcis;
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci->bdaddr_set(hci, bdaddr.b);
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci_table[nb_hcis++] = hci;
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bt_vhci_add(int vlan_id)
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a VHCI to "
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bt_vhci_init(bt_new_hci(vlan));
8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_device_s *bt_device_add(const char *opt)
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan;
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan_id = 0;
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp = strstr(opt, ",vlan=");
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int len = (endp ? endp - opt : strlen(opt)) + 1;
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[10];
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pstrcpy(devname, MIN(sizeof(devname), len), opt);
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (endp) {
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vlan_id = strtol(endp + 6, &endp, 0);
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (*endp) {
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_find_bt_vlan(vlan_id);
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a slave device to "
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(devname, "keyboard"))
8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_keyboard_init(vlan);
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_parse(const char *opt)
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *endp, *p;
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan;
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(opt, "hci", &endp)) {
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp)
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strstart(endp, ",vlan=", 0))
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    opt = endp + 1;
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return bt_hci_parse(opt);
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "vhci", &endp)) {
8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp) {
8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strstart(endp, ",vlan=", &p)) {
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = strtol(p, (char **) &endp, 0);
8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*endp) {
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        return 1;
8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    return 1;
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = 0;
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bt_vhci_add(vlan);
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "device:", &endp))
8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return !bt_device_add(endp);
8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* QEMU Block devices */
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HD_ALIAS "index=%d,media=disk"
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define CDROM_ALIAS "index=2,media=cdrom"
8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define FD_ALIAS "index=%d,if=floppy"
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define PFLASH_ALIAS "if=pflash"
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MTD_ALIAS "if=mtd"
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define SD_ALIAS "index=0,if=sd"
8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
883cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int drive_init_func(QemuOpts *opts, void *opaque)
884cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{
885cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int *use_scsi = opaque;
886cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int fatal_error = 0;
887cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
888cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
889cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        if (fatal_error)
890cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            return 1;
891cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
892cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
893cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner}
894cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
895cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int drive_enable_snapshot(QemuOpts *opts, void *opaque)
896cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{
897cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (NULL == qemu_opt_get(opts, "snapshot")) {
898cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        qemu_opt_set(opts, "snapshot", "on");
899cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
900cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
901cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner}
902cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
903cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef MAX_DRIVES
9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_opt_get_free_idx(void)
9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_opt[index].used) {
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_opt[index].used = 1;
9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_get_free_idx(void)
9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_table[index].used) {
9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[index].used = 1;
9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9307ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehatint drive_add(const char *file, const char *fmt, ...)
9317ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat{
9327ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_list ap;
9337ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    int index = drive_opt_get_free_idx();
9347ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat
9357ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    if (nb_drives_opt >= MAX_DRIVES || index == -1) {
9367ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        fprintf(stderr, "qemu: too many drives\n");
9377ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        return -1;
9387ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    }
9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9407ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    drives_opt[index].file = file;
9417ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_start(ap, fmt);
9427ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    vsnprintf(drives_opt[index].opt,
9437ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat              sizeof(drives_opt[0].opt), fmt, ap);
9447ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_end(ap);
94592568958dd42bf35667cc6451b5edd7f7d1f73a1David 'Digit' Turner
9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt++;
9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return index;
9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_remove(int index)
9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_opt[index].used = 0;
9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt--;
9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_index(BlockInterfaceType type, int bus, int unit)
9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek interface, bus and unit */
9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].type == type &&
9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].bus == bus &&
9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].unit == unit &&
9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].used)
9675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return index;
9685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
9705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_max_bus(BlockInterfaceType type)
9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_bus;
9755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
9765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_bus = -1;
9785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++) {
9795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if(drives_table[index].type == type &&
9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           drives_table[index].bus > max_bus)
9815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_bus = drives_table[index].bus;
9825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return max_bus;
9845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *drive_get_serial(BlockDriverState *bdrv)
9875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
9895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
9915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
9925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].serial;
9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return "\0";
9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
9985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
10025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
10035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].onerror;
10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return BLOCK_ERR_STOP_ENOSPC;
10065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bdrv_format_print(void *opaque, const char *name)
10095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, " %s", name);
10115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_uninit(BlockDriverState *bdrv)
10145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
10165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_DRIVES; i++)
10185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[i].bdrv == bdrv) {
10195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].bdrv = NULL;
10205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].used = 0;
10215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drive_remove(drives_table[i].drive_opt_idx);
10225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_drives--;
10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_init(struct drive_opt *arg, int snapshot, void *opaque)
10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[128];
10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char file[1024];
10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[128];
10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char serial[21];
10335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *mediastr = "";
10345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockInterfaceType type;
10355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    enum { MEDIA_DISK, MEDIA_CDROM } media;
10365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_id, unit_id;
10375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
10385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriverState *bdrv;
10395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriver *drv = NULL;
10405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine = opaque;
10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_devs;
10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cache;
10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bdrv_flags, onerror;
10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int drives_table_idx;
10465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *str = arg->opt;
10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static const char * const params[] = { "bus", "unit", "if", "index",
10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cyls", "heads", "secs", "trans",
10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "media", "snapshot", "file",
10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cache", "format", "serial", "werror",
10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           NULL };
10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (check_params(buf, sizeof(buf), params, str) < 0) {
10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         buf, str);
10565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         return -1;
10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    file[0] = 0;
10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_id = 0;
10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unit_id = -1;
10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    index = -1;
10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cache = 3;
10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (machine->use_scsi) {
10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_SCSI;
10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_SCSI_DEVS;
10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "scsi");
10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_IDE;
10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_IDE_DEVS;
10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "ide");
10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    media = MEDIA_DISK;
10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* extract parameters */
10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "bus", str)) {
10815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bus_id = strtol(buf, NULL, 0);
10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (bus_id < 0) {
10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "unit", str)) {
10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        unit_id = strtol(buf, NULL, 0);
10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (unit_id < 0) {
10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "if", str)) {
10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), buf);
10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ide")) {
10995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_IDE;
11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_IDE_DEVS;
11015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "scsi")) {
11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SCSI;
11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_SCSI_DEVS;
11045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "floppy")) {
11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_FLOPPY;
11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "pflash")) {
11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_PFLASH;
11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "mtd")) {
11115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_MTD;
11125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "sd")) {
11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SD;
11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "virtio")) {
11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            type = IF_VIRTIO;
11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "xen")) {
11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_XEN;
11215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
11225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "index", str)) {
11295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index = strtol(buf, NULL, 0);
11305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (index < 0) {
11315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid index\n", str);
11325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cyls", str)) {
11375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cyls = strtol(buf, NULL, 0);
11385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "heads", str)) {
11415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        heads = strtol(buf, NULL, 0);
11425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "secs", str)) {
11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        secs = strtol(buf, NULL, 0);
11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cyls || heads || secs) {
11495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cyls < 1 || cyls > 16383) {
11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (heads < 1 || heads > 16) {
11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
11555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (secs < 1 || secs > 63) {
11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
11595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "trans", str)) {
11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cyls) {
11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' trans must be used with cyls,heads and secs\n",
11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    str);
11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "none"))
11715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_NONE;
11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "lba"))
11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_LBA;
11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "auto"))
11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_AUTO;
11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "media", str)) {
11835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "disk")) {
11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_DISK;
11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "cdrom")) {
11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls || secs || heads) {
11875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr,
11885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "qemu: '%s' invalid physical CHS format\n", str);
11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        return -1;
11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_CDROM;
11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
11935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid media\n", str);
11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "on"))
12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 1;
12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "off"))
12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 0;
12035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
12055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
12065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
12075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cache", str)) {
12105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "off") || !strcmp(buf, "none"))
12115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 0;
12125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writethrough"))
12135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 1;
12145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writeback"))
12155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 2;
12165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
12175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           fprintf(stderr, "qemu: invalid cache option\n");
12185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return -1;
12195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "format", str)) {
12235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strcmp(buf, "?") == 0) {
12245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: Supported formats:");
12255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_iterate_format(bdrv_format_print, NULL);
12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "\n");
12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
12285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drv = bdrv_find_format(buf);
12305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drv) {
12315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid format\n", buf);
12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
12335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arg->file == NULL)
12375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        get_param_value(file, sizeof(file), "file", str);
12385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(file, sizeof(file), arg->file);
12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!get_param_value(serial, sizeof(serial), "serial", str))
12425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    memset(serial, 0,  sizeof(serial));
12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    onerror = BLOCK_ERR_STOP_ENOSPC;
12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(serial), "werror", str)) {
12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "werror is no supported by this format\n");
12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ignore"))
12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_IGNORE;
12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "enospc"))
12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ENOSPC;
12545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "stop"))
12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ANY;
12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "report"))
12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_REPORT;
12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compute bus and unit according index */
12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (index != -1) {
12675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bus_id != 0 || unit_id != -1) {
12685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' index cannot be used with bus and unit\n", str);
12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
12715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (max_devs == 0)
12735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
12745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index;
12755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = 0;
12765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
12775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index % max_devs;
12785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = index / max_devs;
12795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* if user doesn't specify a unit_id,
12835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * try to find the first free
12845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
12855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unit_id == -1) {
12875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       unit_id = 0;
12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       while (drive_get_index(type, bus_id, unit_id) != -1) {
12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           unit_id++;
12905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           if (max_devs && unit_id >= max_devs) {
12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               unit_id -= max_devs;
12925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               bus_id++;
12935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           }
12945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* check unit id */
12985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs && unit_id >= max_devs) {
13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
13015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        str, unit_id, max_devs - 1);
13025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
13035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /*
13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * ignore multiple definitions
13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (drive_get_index(type, bus_id, unit_id) != -1)
13105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
13115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init */
13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (type == IF_IDE || type == IF_SCSI)
13155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs)
13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%i%s%i",
13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, bus_id, mediastr, unit_id);
13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%s%i",
13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, mediastr, unit_id);
13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv = bdrv_new(buf);
13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table_idx = drive_get_free_idx();
13245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bdrv = bdrv;
13255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].type = type;
13265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bus = bus_id;
13275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].unit = unit_id;
13285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].onerror = onerror;
13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
13315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives++;
13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(type) {
13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_IDE:
13355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SCSI:
13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_XEN:
13375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(media) {
13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_DISK:
13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls != 0) {
13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_translation_hint(bdrv, translation);
13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
13445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_CDROM:
13455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
13465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
13475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SD:
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FIXME: This isn't really a floppy, but it's a reasonable
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           approximation.  */
13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_FLOPPY:
13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
13545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_PFLASH:
13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_MTD:
13575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_VIRTIO:
13585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
13595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_COUNT:
1360c34e8dccc303243ff996aadcf3d7e407bb74e536David 'Digit' Turner    case IF_NONE:
13615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
13625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!file[0])
13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_flags = 0;
13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (snapshot) {
13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_SNAPSHOT;
13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cache = 2; /* always use write-back with snapshot */
13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cache == 0) /* no caching */
13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_NOCACHE;
13725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 2) /* write-back */
13735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_WB;
13745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 3) /* not specified */
13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_DEF;
13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: could not open disk image %s\n",
13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        file);
13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
13805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_key_required(bdrv))
13825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0;
13835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return drives_table_idx;
13845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1385cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif /* MAX_DRIVES */
13865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void numa_add(const char *optarg)
13885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char option[128];
13905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endptr;
13915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned long long value, endvalue;
13925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nodenr;
13935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optarg = get_opt_name(option, 128, optarg, ',') + 1;
13955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(option, "node")) {
13965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "nodeid", optarg) == 0) {
13975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = nb_numa_nodes;
13985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
13995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = strtoull(option, NULL, 10);
14005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "mem", optarg) == 0) {
14035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = 0;
14045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
14055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 0);
14065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch (*endptr) {
14075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 0: case 'M': case 'm':
14085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 20;
14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
14105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 'G': case 'g':
14115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 30;
14125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
14135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
14145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = value;
14155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "cpus", optarg) == 0) {
14175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = 0;
14185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
14195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 10);
14205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (value >= 64) {
14215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = 63;
14225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
14235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
14245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endptr == '-') {
14255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    endvalue = strtoull(endptr+1, &endptr, 10);
14265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (endvalue >= 63) {
14275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        endvalue = 62;
14285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr,
14295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            "only 63 CPUs in NUMA mode supported.\n");
14305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
14315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = (1 << (endvalue + 1)) - (1 << value);
14325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
14335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = 1 << value;
14345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
14355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
14365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = value;
14375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_numa_nodes++;
14395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
14415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
14445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* USB devices */
14455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *used_usb_ports;
14475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *free_usb_ports;
14485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ??? Maybe change this to register a hub to keep track of the topology.  */
14505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_usb_port(USBPort *port, void *opaque, int index,
14515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            usb_attachfn attach)
14525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->opaque = opaque;
14545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->index = index;
14555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->attach = attach;
14565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
14575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
14585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_add_dev(USBDevice *dev)
14615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
14635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Find a USB port to add the device to.  */
14655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = free_usb_ports;
14665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port->next) {
14675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        USBDevice *hub;
14685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Create a new hub and chain it on.  */
14705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        free_usb_ports = NULL;
14715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port->next = used_usb_ports;
14725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        used_usb_ports = port;
14735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hub = usb_hub_init(VM_USB_HUB_SIZE);
14755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_attach(port, hub);
14765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = free_usb_ports;
14775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port->next;
14805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = used_usb_ports;
14815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    used_usb_ports = port;
14825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, dev);
14835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
14845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14863266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#if 0
14875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void usb_msd_password_cb(void *opaque, int err)
14885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev = opaque;
14905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!err)
14925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_device_add_dev(dev);
14935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
14945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev->handle_destroy(dev);
14955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14963266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#endif
14975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_add(const char *devname, int is_hotplug)
14995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
15015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
15025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!free_usb_ports)
15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p)) {
15075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_host_device_open(p);
15085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "mouse")) {
15095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_mouse_init();
15105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "tablet")) {
15115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_tablet_init();
15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "keyboard")) {
15135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_keyboard_init();
15145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "disk:", &p)) {
15155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
15165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        BlockDriverState *bs;
15175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_msd_init(p);
15195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
15205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
15215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
15225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bs = usb_msd_get_bdrv(dev);
15235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bdrv_key_required(bs)) {
15245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            autostart = 0;
15255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (is_hotplug) {
15265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
15275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            dev);
15285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
15295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
15305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "wacom-tablet")) {
15325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_wacom_init();
15335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "serial:", &p)) {
15345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_serial_init(p);
15355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_BRLAPI
15365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "braille")) {
15375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_baum_init();
15385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "net:", &p)) {
15405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int nic = nb_nics;
15415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (net_client_init("nic", p) < 0)
15435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
15445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nd_table[nic].model = "usb";
15455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_net_init(&nd_table[nic]);
15465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
15475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_bt_init(devname[2] ? hci_init(p) :
15485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        bt_new_hci(qemu_find_bt_vlan(0)));
15495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
15515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!dev)
15545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_add_dev(dev);
15575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_del_addr(int bus_num, int addr)
15605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
15625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort **lastp;
15635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
15645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
15665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bus_num != 0)
15695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    lastp = &used_usb_ports;
15725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = used_usb_ports;
15735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (port && port->dev->addr != addr) {
15745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        lastp = &port->next;
15755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = port->next;
15765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port)
15795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev = port->dev;
15825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *lastp = port->next;
15835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, NULL);
15845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev->handle_destroy(dev);
15855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
15865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
15875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
15885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_del(const char *devname)
15915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_num, addr;
15935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
15945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p))
15965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return usb_host_device_close(p);
15975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
15995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
16005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = strchr(devname, '.');
16025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p)
16035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
16045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_num = strtoul(devname, NULL, 0);
16055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    addr = strtoul(p + 1, NULL, 0);
16065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_del_addr(bus_num, addr);
16085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_add(Monitor *mon, const char *devname)
16115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_add(devname, 1);
16135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_del(Monitor *mon, const char *devname)
16165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_del(devname);
16185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid usb_info(Monitor *mon)
16215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
16235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
16245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *speed_str;
16255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!usb_enabled) {
16275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "USB support not enabled\n");
16285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
16295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (port = used_usb_ports; port; port = port->next) {
16325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = port->dev;
16335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
16345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
16355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(dev->speed) {
16365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_LOW:
16375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "1.5";
16385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
16395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_FULL:
16405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "12";
16415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
16425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_HIGH:
16435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "480";
16445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
16455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
16465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "?";
16475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
16485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "  Device %d.%d, Speed %s Mb/s, Product %s\n",
16505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       0, dev->addr, speed_str, dev->devname);
16515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
16555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* PCMCIA/Cardbus */
16565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct pcmcia_socket_entry_s {
16585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PCMCIASocket *socket;
16595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *next;
16605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *pcmcia_sockets = 0;
16615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_register(PCMCIASocket *socket)
16635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry;
16655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
16675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->socket = socket;
16685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->next = pcmcia_sockets;
16695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pcmcia_sockets = entry;
16705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_unregister(PCMCIASocket *socket)
16735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry, **ptr;
16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ptr = &pcmcia_sockets;
16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (entry->socket == socket) {
16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *ptr = entry->next;
16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(entry);
16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_info(Monitor *mon)
16855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *iter;
16875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!pcmcia_sockets)
16895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No PCMCIA sockets\n");
16905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (iter = pcmcia_sockets; iter; iter = iter->next)
16925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
16935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       iter->socket->attached ? iter->socket->card_string :
16945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       "Empty");
16955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
16985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* machine registration */
16995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *first_machine = NULL;
17015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUMachine *current_machine = NULL;
17025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_register_machine(QEMUMachine *m)
17045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine **pm;
17065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pm = &first_machine;
17075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pm != NULL)
17085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pm = &(*pm)->next;
17095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->next = NULL;
17105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pm = m;
17115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
17125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_machine(const char *name)
17155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
17175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
17195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(m->name, name))
17205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
17215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
17235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_default_machine(void)
17265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
17285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
17305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (m->is_default) {
17315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
17325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
17335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
17355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
17385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* main execution loop */
17395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gui_update(void *opaque)
17415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
17435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds = opaque;
17445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl = ds->listeners;
17455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_refresh(ds);
17475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
17495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->gui_timer_interval &&
17505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dcl->gui_timer_interval < interval)
17515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            interval = dcl->gui_timer_interval;
17525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
17535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17545973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
17555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void nographic_update(void *opaque)
17585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
17605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17615973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner    qemu_mod_timer(nographic_timer, interval + qemu_get_clock_ms(rt_clock));
17625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct vm_change_state_entry {
17655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateHandler *cb;
17665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
1767a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_ENTRY (vm_change_state_entry) entries;
17685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
17695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1770a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turnerstatic QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
17715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerVMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
17735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                     void *opaque)
17745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
17765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e = qemu_mallocz(sizeof (*e));
17785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->cb = cb;
17805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->opaque = opaque;
1781a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
17825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return e;
17835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
17865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1787a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_REMOVE (e, entries);
17885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free (e);
17895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
179123ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnervoid vm_state_notify(int running, int reason)
17925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
17945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
17965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        e->cb(e->opaque, running, reason);
17975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_start(void)
18015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vm_running) {
18035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_enable_ticks();
18045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_running = 1;
18055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_state_notify(1, 0);
18066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        //qemu_rearm_alarm_timer(alarm_timer);
18075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        resume_all_vcpus();
18085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* reset/shutdown handler */
18125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUResetEntry {
18145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetHandler *func;
18155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
18165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int order;
18175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct QEMUResetEntry *next;
18185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUResetEntry;
18195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUResetEntry *first_reset_entry;
18215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int reset_requested;
1822088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turnerstatic int shutdown_requested, shutdown_signal = -1;
1823088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turnerstatic pid_t shutdown_pid;
18245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int powerdown_requested;
182523ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turnerint debug_requested;
18265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vmstop_requested;
18275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_shutdown_requested(void)
18295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = shutdown_requested;
18315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 0;
18325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
18335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_reset_requested(void)
18365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = reset_requested;
18385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    reset_requested = 0;
18395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
18405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_powerdown_requested(void)
18435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = powerdown_requested;
18455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 0;
18465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
18475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_debug_requested(void)
18505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = debug_requested;
18525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    debug_requested = 0;
18535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
18545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_vmstop_requested(void)
18575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = vmstop_requested;
18595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = 0;
18605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
18615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
18645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry **pre, *re;
18665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pre = &first_reset_entry;
18685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pre != NULL && (*pre)->order >= order) {
18695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pre = &(*pre)->next;
18705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re = qemu_mallocz(sizeof(QEMUResetEntry));
18725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->func = func;
18735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->opaque = opaque;
18745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->order = order;
18755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->next = NULL;
18765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pre = re;
18775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset(void)
18805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry *re;
18825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* reset all devices */
18845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(re = first_reset_entry; re != NULL; re = re->next) {
18855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        re->func(re->opaque);
18865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset_request(void)
18905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (no_reboot) {
18925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        shutdown_requested = 1;
18935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
18945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        reset_requested = 1;
18955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
18975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1899088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turnervoid qemu_system_killed(int signal, pid_t pid)
1900088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner{
1901088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner    shutdown_signal = signal;
1902088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner    shutdown_pid = pid;
1903088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner    qemu_system_shutdown_request();
1904088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner}
1905088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner
19065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_shutdown_request(void)
19075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 1;
19095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
19105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_powerdown_request(void)
19135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 1;
19155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
19165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
19195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_system_vmstop_request(int reason)
19205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = reason;
19225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
19235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
19255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid main_loop_wait(int timeout)
19275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set rfds, wfds, xfds;
19295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, nfds;
19305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct timeval tv;
19315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_update_timeout(&timeout);
19335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
193423ca2ae2bf303236eb6b1e0beb126ec05c6c23bfDavid 'Digit' Turner    os_host_main_loop_wait(&timeout);
19355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19368354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner
19378354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner    tv.tv_sec = timeout / 1000;
19388354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner    tv.tv_usec = (timeout % 1000) * 1000;
19398354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner
19405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* poll any events */
19418354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner
19425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: separate device handlers from system ones */
19435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nfds = -1;
19445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&rfds);
19455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&wfds);
19465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&xfds);
19478354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner    qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
19485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
19495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
19505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19518354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner
19525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock_iothread();
19535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
19545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock_iothread();
19558354d2d35fe4463816dcc52a96fa354940fdd38fDavid 'Digit' Turner    qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
19565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
19575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
19585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&rfds);
19595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&wfds);
19605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&xfds);
19615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
19625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_poll(&rfds, &wfds, &xfds);
19635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    charpipe_poll();
19655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_run_all_timers();
1967a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
19685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Check bottom-halves last in case any of the earlier events triggered
19695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       them.  */
19705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_poll();
19715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vm_can_run(void)
19755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (powerdown_requested)
19775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
19785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reset_requested)
19795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
19805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (shutdown_requested)
19815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
19825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (debug_requested)
19835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
19845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
19855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void main_loop(void)
19885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r;
19905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
19925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_system_ready = 1;
19935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_broadcast(&qemu_system_cond);
19945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
19955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1996a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX
1997a381ef07088ce479610129e37bfef42538f397daJun Nakajima    if (hax_enabled())
1998a381ef07088ce479610129e37bfef42538f397daJun Nakajima        hax_sync_vcpus();
1999a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif
2000a381ef07088ce479610129e37bfef42538f397daJun Nakajima
20015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (;;) {
20025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        do {
20035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
20045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            int64_t ti;
20055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
20065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
20075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_cpu_exec();
20085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
20095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
20105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ti = profile_getclock();
20115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
20125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            main_loop_wait(qemu_calculate_timeout());
20135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
20145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dev_time += profile_getclock() - ti;
20155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2016d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
2017d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings            if (rotate_logs_requested) {
2018d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                FILE* new_dns_log_fd = rotate_qemu_log(get_slirp_dns_log_fd(),
2019d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                                                        dns_log_filename);
2020d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                FILE* new_drop_log_fd = rotate_qemu_log(get_slirp_drop_log_fd(),
2021d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                                                         drop_log_filename);
2022d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                slirp_dns_log_fd(new_dns_log_fd);
2023d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                slirp_drop_log_fd(new_drop_log_fd);
2024d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                reset_rotate_qemu_logs_request();
2025d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings            }
2026d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
20275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } while (vm_can_run());
20285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_debug_requested())
20305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(EXCP_DEBUG);
20315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_shutdown_requested()) {
20325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (no_shutdown) {
20335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vm_stop(0);
20345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 0;
203524204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock            } else {
203624204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                if (savevm_on_exit != NULL) {
2037db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                  /* Prior to saving VM to the snapshot file, save HW config
2038db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                   * settings for that VM, so we can match them when VM gets
2039db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                   * loaded from the snapshot. */
2040db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine                  snaphost_save_config(savevm_on_exit);
204124204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                  do_savevm(cur_mon, savevm_on_exit);
204224204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                }
20435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
204424204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock            }
20455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_reset_requested()) {
20475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pause_all_vcpus();
20485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_reset();
20495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            resume_all_vcpus();
20505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_powerdown_requested())
20525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_powerdown();
20535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((r = qemu_vmstop_requested()))
20545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(r);
20555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pause_all_vcpus();
20575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20597fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinevoid version(void)
20605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
20625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_help(int exitcode)
20655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    version();
20675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("usage: %s [options] [disk_image]\n"
20685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
20695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
20705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
20715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
20725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           opt_help
20735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text) stringify(text) "\n"
2074088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner#include "qemu-options.def"
20755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
20765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
20775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
20785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
20795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "During emulation, the following keys are useful:\n"
20805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-f      toggle full screen\n"
20815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-n      switch to virtual console 'n'\n"
20825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt        toggle mouse and keyboard grab\n"
20835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
20845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "When using -nographic, press 'ctrl-a h' to get some help.\n"
20855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           ,
20865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "qemu",
20875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_RAM_SIZE,
20885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
20895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_SCRIPT,
20905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_DOWN_SCRIPT,
20915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
20925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_GDBSTUB_PORT,
20935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "/tmp/qemu.log");
20947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    QEMU_EXIT(exitcode);
20955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HAS_ARG 0x0001
20985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum {
21005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
21015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    opt_enum,
21025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
2103088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner#include "qemu-options.def"
21045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
21055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
21065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
21075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
21085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUOption {
21105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *name;
21115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
21125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUOption;
21145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const QEMUOption qemu_options[] = {
21165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { "h", 0, QEMU_OPTION_h },
21175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
21185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { option, opt_arg, opt_enum },
21195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
2120088edf82b3d34409ed9d9fd09ec1f7e9b933304fDavid 'Digit' Turner#include "qemu-options.def"
21215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
21225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
21235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
21245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL, 0, 0 },
21255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
21265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void select_vgahw (const char *p)
21285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *opts;
21305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cirrus_vga_enabled = 0;
21325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    std_vga_enabled = 0;
21335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmsvga_enabled = 0;
21345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    xenfb_enabled = 0;
21355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(p, "std", &opts)) {
21365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        std_vga_enabled = 1;
21375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "cirrus", &opts)) {
21385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cirrus_vga_enabled = 1;
21395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "vmware", &opts)) {
21405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vmsvga_enabled = 1;
21415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "xenfb", &opts)) {
21425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        xenfb_enabled = 1;
21435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strstart(p, "none", &opts)) {
21445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    invalid_vga:
21457746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("Unknown vga type: %s", p);
21465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*opts) {
21485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *nextopt;
21495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strstart(opts, ",retrace=", &nextopt)) {
21515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            opts = nextopt;
21525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(opts, "dumb", &nextopt))
21535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_DUMB;
21545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else if (strstart(opts, "precise", &nextopt))
21555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_PRECISE;
21565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else goto invalid_vga;
21575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else goto invalid_vga;
21585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        opts = nextopt;
21595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_NET_CLIENTS 32
21635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
21655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Look for support files in the same directory as the executable.  */
21665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
21675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p;
21695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[MAX_PATH];
21705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DWORD len;
21715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
21735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (len == 0) {
21745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
21755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf[len] = 0;
21785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = buf + len - 1;
21795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (p != buf && *p != '\\')
21805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p--;
21815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *p = 0;
21825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(buf, R_OK) == 0) {
21835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_strdup(buf);
21845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
21865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* !_WIN32 */
21885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
218924d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner/* Similarly, return the location of the executable */
21905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
21915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p = NULL;
21935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[PATH_MAX];
21945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__)
21965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
21975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
21985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
21995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
22005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
22015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
22025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(__FreeBSD__)
22055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
22065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
22075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
22085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
22095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
22105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
22115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
22145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If we don't have any way of figuring out the actual executable
22155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       location then try argv[0].  */
22165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p) {
221724d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        p = realpath(argv0, buf);
22185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!p) {
22195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return NULL;
22205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
222324d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    return qemu_strdup(dirname(buf));
222424d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner}
222524d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner#endif
222602c6385fd50f926d0f0801dfe60480cd90d8df81Bruce Beare
222724d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turnerstatic char*
222824d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turnerqemu_find_file_with_subdir(const char* data_dir, const char* subdir, const char* name)
222924d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner{
223024d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    int   len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
223124d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    char* buf = qemu_mallocz(len);
223202c6385fd50f926d0f0801dfe60480cd90d8df81Bruce Beare
223324d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
223424d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    VERBOSE_PRINT(init,"    trying to find: %s\n", buf);
223524d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    if (access(buf, R_OK)) {
223624d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        qemu_free(buf);
223724d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        return NULL;
22385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
223924d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    return buf;
22405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *qemu_find_file(int type, const char *name)
22435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *subdir;
22455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *buf;
22465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If name contains path separators then try it as a straight path.  */
22485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((strchr(name, '/') || strchr(name, '\\'))
22495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && access(name, R_OK) == 0) {
22505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return strdup(name);
22515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (type) {
22535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_BIOS:
22545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "";
22555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
22565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_KEYMAP:
22575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "keymaps/";
22585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
22595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
22605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
22615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
226224d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    buf = qemu_find_file_with_subdir(data_dir, subdir, name);
226324d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner#ifdef CONFIG_ANDROID
226424d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner    if (type == QEMU_FILE_TYPE_BIOS) {
226524d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        /* This case corresponds to the emulator being used as part of an
226624d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner         * SDK installation. NOTE: data_dir is really $bindir. */
226724d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        if (buf == NULL)
226824d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner            buf = qemu_find_file_with_subdir(data_dir, "lib/pc-bios/", name);
226924d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        /* This case corresponds to platform builds. */
227024d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        if (buf == NULL)
227124d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner            buf = qemu_find_file_with_subdir(data_dir, "../usr/share/pc-bios/", name);
227224d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        /* Finally, try this for standalone builds under external/qemu */
227324d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner        if (buf == NULL)
227424d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner            buf = qemu_find_file_with_subdir(data_dir, "../../../prebuilt/common/pc-bios/", name);
22755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
227624d2752ad601b4ab48d72b52f602e129dd4761d7David 'Digit' Turner#endif
22775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return buf;
22785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinestatic int
22817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkineadd_dns_server( const char*  server_name )
22827fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine{
22837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    SockAddress   addr;
22847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
22857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
22867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stdout,
22877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: can't resolve DNS server name '%s'\n",
22887fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                server_name );
22897fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
22907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
22917fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
22927fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    fprintf(stderr,
22937fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
22947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
22957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if ( slirp_add_dns_server( &addr ) < 0 ) {
22967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stderr,
22977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
22987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
22997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
23007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    return 0;
23017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine}
23027fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
23037339b55944e97077e4f74c4be34cd956ae44198brich cannings/* Parses an integer
23047339b55944e97077e4f74c4be34cd956ae44198brich cannings * Pararm:
23057339b55944e97077e4f74c4be34cd956ae44198brich cannings *  str      String containing a number to be parsed.
23067339b55944e97077e4f74c4be34cd956ae44198brich cannings *  result   Passes the parsed integer in this argument
23077339b55944e97077e4f74c4be34cd956ae44198brich cannings *  returns  0 if ok, -1 if failed
23087339b55944e97077e4f74c4be34cd956ae44198brich cannings */
23097339b55944e97077e4f74c4be34cd956ae44198brich canningsint
23107339b55944e97077e4f74c4be34cd956ae44198brich canningsparse_int(const char *str, int *result)
23117339b55944e97077e4f74c4be34cd956ae44198brich cannings{
23127339b55944e97077e4f74c4be34cd956ae44198brich cannings    char* r;
23137339b55944e97077e4f74c4be34cd956ae44198brich cannings    *result = strtol(str, &r, 0);
23147339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (r == NULL || *r != '\0')
23157339b55944e97077e4f74c4be34cd956ae44198brich cannings      return -1;
23167339b55944e97077e4f74c4be34cd956ae44198brich cannings
23177339b55944e97077e4f74c4be34cd956ae44198brich cannings    return 0;
23187339b55944e97077e4f74c4be34cd956ae44198brich cannings}
23197339b55944e97077e4f74c4be34cd956ae44198brich cannings
2320d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings#ifndef _WIN32
2321d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings/*
2322d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings * Initializes the SIGUSR1 signal handler to clear Qemu logs.
2323d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings */
2324d952f28e527175cc3df9ebd91e739e34df2194c9rich canningsvoid init_qemu_clear_logs_sig() {
2325d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  struct sigaction act;
2326d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  sigfillset(&act.sa_mask);
2327d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  act.sa_flags = 0;
2328d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  act.sa_handler = rotate_qemu_logs_handler;
2329d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  if (sigaction(SIGUSR1, &act, NULL) == -1) {
2330d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
2331d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    exit(-1);
2332d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings  }
2333d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings}
2334d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings#endif
2335d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
2336d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
23377339b55944e97077e4f74c4be34cd956ae44198brich cannings
23387339b55944e97077e4f74c4be34cd956ae44198brich cannings/* parses a null-terminated string specifying a network port (e.g., "80") or
23397339b55944e97077e4f74c4be34cd956ae44198brich cannings * port range (e.g., "[6666-7000]"). In case of a single port, lport and hport
23407339b55944e97077e4f74c4be34cd956ae44198brich cannings * are the same. Returns 0 on success, -1 on error. */
23417339b55944e97077e4f74c4be34cd956ae44198brich cannings
23427339b55944e97077e4f74c4be34cd956ae44198brich canningsint parse_port_range(const char *str, unsigned short *lport,
23437339b55944e97077e4f74c4be34cd956ae44198brich cannings                     unsigned short *hport) {
23447339b55944e97077e4f74c4be34cd956ae44198brich cannings
23457339b55944e97077e4f74c4be34cd956ae44198brich cannings  unsigned int low = 0, high = 0;
23467339b55944e97077e4f74c4be34cd956ae44198brich cannings  char *p, *arg = strdup(str);
23477339b55944e97077e4f74c4be34cd956ae44198brich cannings
23487339b55944e97077e4f74c4be34cd956ae44198brich cannings  if ((*arg == '[') && ((p = strrchr(arg, ']')) != NULL)) {
23497339b55944e97077e4f74c4be34cd956ae44198brich cannings    p = arg + 1;   /* skip '[' */
23507339b55944e97077e4f74c4be34cd956ae44198brich cannings    low  = atoi(strtok(p, "-"));
23517339b55944e97077e4f74c4be34cd956ae44198brich cannings    high = atoi(strtok(NULL, "-"));
23527339b55944e97077e4f74c4be34cd956ae44198brich cannings    if ((low > 0) && (high > 0) && (low < high) && (high < 65535)) {
23537339b55944e97077e4f74c4be34cd956ae44198brich cannings      *lport = low;
23547339b55944e97077e4f74c4be34cd956ae44198brich cannings      *hport = high;
23557339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
23567339b55944e97077e4f74c4be34cd956ae44198brich cannings  }
23577339b55944e97077e4f74c4be34cd956ae44198brich cannings  else {
23587339b55944e97077e4f74c4be34cd956ae44198brich cannings    low = atoi(arg);
23597339b55944e97077e4f74c4be34cd956ae44198brich cannings    if ((0 < low) && (low < 65535)) {
23607339b55944e97077e4f74c4be34cd956ae44198brich cannings      *lport = low;
23617339b55944e97077e4f74c4be34cd956ae44198brich cannings      *hport = low;
23627339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
23637339b55944e97077e4f74c4be34cd956ae44198brich cannings  }
23647339b55944e97077e4f74c4be34cd956ae44198brich cannings  free(arg);
23657339b55944e97077e4f74c4be34cd956ae44198brich cannings  if (low != 0)
23667339b55944e97077e4f74c4be34cd956ae44198brich cannings    return 0;
23677339b55944e97077e4f74c4be34cd956ae44198brich cannings  return -1;
23687339b55944e97077e4f74c4be34cd956ae44198brich cannings}
23697339b55944e97077e4f74c4be34cd956ae44198brich cannings
23707339b55944e97077e4f74c4be34cd956ae44198brich cannings/*
23717339b55944e97077e4f74c4be34cd956ae44198brich cannings * Implements the generic port forwarding option
23727339b55944e97077e4f74c4be34cd956ae44198brich cannings */
23737339b55944e97077e4f74c4be34cd956ae44198brich canningsvoid
23747339b55944e97077e4f74c4be34cd956ae44198brich canningsnet_slirp_forward(const char *optarg)
23757339b55944e97077e4f74c4be34cd956ae44198brich cannings{
23767339b55944e97077e4f74c4be34cd956ae44198brich cannings    /*
23777339b55944e97077e4f74c4be34cd956ae44198brich cannings     * we expect the following format:
23787339b55944e97077e4f74c4be34cd956ae44198brich cannings     * dst_net:dst_mask:dst_port:redirect_ip:redirect_port OR
23797339b55944e97077e4f74c4be34cd956ae44198brich cannings     * dst_net:dst_mask:[dp_range_start-dp_range_end]:redirect_ip:redirect_port
23807339b55944e97077e4f74c4be34cd956ae44198brich cannings     */
23817339b55944e97077e4f74c4be34cd956ae44198brich cannings    char *argument = strdup(optarg), *p = argument;
23827339b55944e97077e4f74c4be34cd956ae44198brich cannings    char *dst_net, *dst_mask, *dst_port;
23837339b55944e97077e4f74c4be34cd956ae44198brich cannings    char *redirect_ip, *redirect_port;
23847339b55944e97077e4f74c4be34cd956ae44198brich cannings    uint32_t dnet, dmask, rip;
2385b557e9f989598460eb950cb3942a79f805a2a5bbVladimir Chtchetkine    unsigned short dlport = 0, dhport = 0, rport;
23867339b55944e97077e4f74c4be34cd956ae44198brich cannings
23877339b55944e97077e4f74c4be34cd956ae44198brich cannings
23887339b55944e97077e4f74c4be34cd956ae44198brich cannings    dst_net = strtok(p, ":");
23897339b55944e97077e4f74c4be34cd956ae44198brich cannings    dst_mask = strtok(NULL, ":");
23907339b55944e97077e4f74c4be34cd956ae44198brich cannings    dst_port = strtok(NULL, ":");
23917339b55944e97077e4f74c4be34cd956ae44198brich cannings    redirect_ip = strtok(NULL, ":");
23927339b55944e97077e4f74c4be34cd956ae44198brich cannings    redirect_port = strtok(NULL, ":");
23937339b55944e97077e4f74c4be34cd956ae44198brich cannings
23947339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (dst_net == NULL || dst_mask == NULL || dst_port == NULL ||
23957339b55944e97077e4f74c4be34cd956ae44198brich cannings        redirect_ip == NULL || redirect_port == NULL) {
23967339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr,
23977339b55944e97077e4f74c4be34cd956ae44198brich cannings                "Invalid argument for -net-forward, we expect "
23987339b55944e97077e4f74c4be34cd956ae44198brich cannings                "dst_net:dst_mask:dst_port:redirect_ip:redirect_port or "
23997339b55944e97077e4f74c4be34cd956ae44198brich cannings                "dst_net:dst_mask:[dp_range_start-dp_range_end]"
24007339b55944e97077e4f74c4be34cd956ae44198brich cannings                ":redirect_ip:redirect_port: %s\n",
24017339b55944e97077e4f74c4be34cd956ae44198brich cannings                optarg);
24027339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24037339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24047339b55944e97077e4f74c4be34cd956ae44198brich cannings
24057339b55944e97077e4f74c4be34cd956ae44198brich cannings    /* inet_strtoip converts dotted address to host byte order */
24067339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (inet_strtoip(dst_net, &dnet) == -1) {
24077339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr, "Invalid destination IP net: %s\n", dst_net);
24087339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24097339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24107339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (inet_strtoip(dst_mask, &dmask) == -1) {
24117339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr, "Invalid destination IP mask: %s\n", dst_mask);
24127339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24137339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24147339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (inet_strtoip(redirect_ip, &rip) == -1) {
24157339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr, "Invalid redirect IP address: %s\n", redirect_ip);
24167339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24177339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24187339b55944e97077e4f74c4be34cd956ae44198brich cannings
24197339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (parse_port_range(dst_port, &dlport, &dhport) == -1) {
24207339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr, "Invalid destination port or port range\n");
24217339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24227339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24237339b55944e97077e4f74c4be34cd956ae44198brich cannings
24247339b55944e97077e4f74c4be34cd956ae44198brich cannings    rport = atoi(redirect_port);
24257339b55944e97077e4f74c4be34cd956ae44198brich cannings    if (!rport) {
24267339b55944e97077e4f74c4be34cd956ae44198brich cannings        fprintf(stderr, "Invalid redirect port: %s\n", redirect_port);
24277339b55944e97077e4f74c4be34cd956ae44198brich cannings        exit(1);
24287339b55944e97077e4f74c4be34cd956ae44198brich cannings    }
24297339b55944e97077e4f74c4be34cd956ae44198brich cannings
24307339b55944e97077e4f74c4be34cd956ae44198brich cannings    dnet &= dmask;
24317339b55944e97077e4f74c4be34cd956ae44198brich cannings
24327339b55944e97077e4f74c4be34cd956ae44198brich cannings    slirp_add_net_forward(dnet, dmask, dlport, dhport,
24337339b55944e97077e4f74c4be34cd956ae44198brich cannings                          rip, rport);
24347339b55944e97077e4f74c4be34cd956ae44198brich cannings
24357339b55944e97077e4f74c4be34cd956ae44198brich cannings    free(argument);
24367339b55944e97077e4f74c4be34cd956ae44198brich cannings}
24377339b55944e97077e4f74c4be34cd956ae44198brich cannings
24387339b55944e97077e4f74c4be34cd956ae44198brich cannings
24397339b55944e97077e4f74c4be34cd956ae44198brich cannings/* Parses an -allow-tcp or -allow-udp argument and inserts a corresponding
24407339b55944e97077e4f74c4be34cd956ae44198brich cannings * entry in the allows list */
24417339b55944e97077e4f74c4be34cd956ae44198brich canningsvoid
24427339b55944e97077e4f74c4be34cd956ae44198brich canningsslirp_allow(const char *optarg, u_int8_t proto)
24437339b55944e97077e4f74c4be34cd956ae44198brich cannings{
24447339b55944e97077e4f74c4be34cd956ae44198brich cannings  /*
24457339b55944e97077e4f74c4be34cd956ae44198brich cannings   * we expect the following format:
24467339b55944e97077e4f74c4be34cd956ae44198brich cannings   * dst_ip:dst_port OR dst_ip:[dst_lport-dst_hport]
24477339b55944e97077e4f74c4be34cd956ae44198brich cannings   */
24487339b55944e97077e4f74c4be34cd956ae44198brich cannings  char *argument = strdup(optarg), *p = argument;
24497339b55944e97077e4f74c4be34cd956ae44198brich cannings  char *dst_ip_str, *dst_port_str;
24507339b55944e97077e4f74c4be34cd956ae44198brich cannings  uint32_t dst_ip;
2451b557e9f989598460eb950cb3942a79f805a2a5bbVladimir Chtchetkine  unsigned short dst_lport = 0, dst_hport = 0;
24527339b55944e97077e4f74c4be34cd956ae44198brich cannings
24537339b55944e97077e4f74c4be34cd956ae44198brich cannings  dst_ip_str = strtok(p, ":");
24547339b55944e97077e4f74c4be34cd956ae44198brich cannings  dst_port_str = strtok(NULL, ":");
24557339b55944e97077e4f74c4be34cd956ae44198brich cannings
24567339b55944e97077e4f74c4be34cd956ae44198brich cannings  if (dst_ip_str == NULL || dst_port_str == NULL) {
24577339b55944e97077e4f74c4be34cd956ae44198brich cannings    fprintf(stderr,
24587339b55944e97077e4f74c4be34cd956ae44198brich cannings            "Invalid argument %s for -allow. We expect "
24597339b55944e97077e4f74c4be34cd956ae44198brich cannings            "dst_ip:dst_port or dst_ip:[dst_lport-dst_hport]\n",
24607339b55944e97077e4f74c4be34cd956ae44198brich cannings            optarg);
24617339b55944e97077e4f74c4be34cd956ae44198brich cannings    exit(1);
24627339b55944e97077e4f74c4be34cd956ae44198brich cannings  }
24637339b55944e97077e4f74c4be34cd956ae44198brich cannings
24647339b55944e97077e4f74c4be34cd956ae44198brich cannings  if (inet_strtoip(dst_ip_str, &dst_ip) == -1) {
24657339b55944e97077e4f74c4be34cd956ae44198brich cannings    fprintf(stderr, "Invalid destination IP address: %s\n", dst_ip_str);
24667339b55944e97077e4f74c4be34cd956ae44198brich cannings    exit(1);
24677339b55944e97077e4f74c4be34cd956ae44198brich cannings  }
24687339b55944e97077e4f74c4be34cd956ae44198brich cannings  if (parse_port_range(dst_port_str, &dst_lport, &dst_hport) == -1) {
24697339b55944e97077e4f74c4be34cd956ae44198brich cannings    fprintf(stderr, "Invalid destination port or port range\n");
24707339b55944e97077e4f74c4be34cd956ae44198brich cannings    exit(1);
24717339b55944e97077e4f74c4be34cd956ae44198brich cannings  }
24727339b55944e97077e4f74c4be34cd956ae44198brich cannings
24737339b55944e97077e4f74c4be34cd956ae44198brich cannings  slirp_add_allow(dst_ip, dst_lport, dst_hport, proto);
24747339b55944e97077e4f74c4be34cd956ae44198brich cannings
24757339b55944e97077e4f74c4be34cd956ae44198brich cannings  free(argument);
24767339b55944e97077e4f74c4be34cd956ae44198brich cannings}
24777339b55944e97077e4f74c4be34cd956ae44198brich cannings
2478062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner/* Add a serial device at a given location in the emulated hardware table.
2479062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner * On failure, this function aborts the program with an error message.
2480062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner */
2481062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstatic void
2482062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerserial_hds_add_at(int  index, const char* devname)
2483062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner{
2484062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    char label[32];
2485062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2486062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (!devname || !strcmp(devname,"none"))
2487062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        return;
2488062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2489062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (index >= MAX_SERIAL_PORTS) {
2490062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        PANIC("qemu: invalid serial index for %s (%d >= %d)",
2491062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner              devname, index, MAX_SERIAL_PORTS);
2492062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
2493062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (serial_hds[index] != NULL) {
2494062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        PANIC("qemu: invalid serial index for %s (%d: already taken!)",
2495062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner              devname, index);
2496062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
2497062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    snprintf(label, sizeof(label), "serial%d", index);
2498062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    serial_hds[index] = qemu_chr_open(label, devname, NULL);
2499062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (!serial_hds[index]) {
2500062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        PANIC("qemu: could not open serial device '%s'", devname);
2501062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
2502062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner}
2503062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2504062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2505062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner/* Find a free slot in the emulated serial device table, and register
2506062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner * it. Return the allocated table index.
2507062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner */
2508062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerstatic int
2509062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turnerserial_hds_add(const char* devname)
2510062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner{
2511062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    int  index;
2512062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2513062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    /* Find first free slot */
2514062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    for (index = 0; index < MAX_SERIAL_PORTS; index++) {
2515062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        if (serial_hds[index] == NULL) {
2516062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner            serial_hds_add_at(index, devname);
2517062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner            return index;
2518062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        }
2519062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    }
2520062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
2521062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    PANIC("qemu: too many serial devices registered (%d)", index);
2522062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    return -1;  /* shouldn't happen */
2523062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner}
2524062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
25255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint main(int argc, char **argv, char **envp)
25265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *gdbstub_dev = NULL;
25285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t boot_devices_bitmap = 0;
25295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
25305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int snapshot, linux_boot, net_boot;
25316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    const char *icount_option = NULL;
25325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *initrd_filename;
25335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *kernel_filename, *kernel_cmdline;
25345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *boot_devices = "";
25355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds;
25365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl;
25375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
2538cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    QemuOpts *hda_opts = NULL;
25395f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    QemuOpts *hdb_opts = NULL;
25405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *net_clients[MAX_NET_CLIENTS];
25415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_net_clients;
25425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *bt_opts[MAX_BT_CMDLINE];
25435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_bt_opts;
25445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int optind;
25455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *r, *optarg;
25465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *monitor_hd = NULL;
25475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *monitor_device;
25485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *serial_devices[MAX_SERIAL_PORTS];
25495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int serial_device_index;
25505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *parallel_devices[MAX_PARALLEL_PORTS];
25515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int parallel_device_index;
25525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
25535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int virtio_console_index;
25545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *loadvm = NULL;
25555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine;
25565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *cpu_model;
25575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *usb_devices[MAX_USB_CMDLINE];
25585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int usb_devices_index;
25595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int tb_size;
25605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *pid_file = NULL;
25615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *incoming = NULL;
25625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
25635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int show_vnc_port = 0;
2564074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    IniFile*  hw_ini = NULL;
25655f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner    STRALLOC_DEFINE(kernel_params);
25665f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner    STRALLOC_DEFINE(kernel_config);
25677fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    int    dns_count = 0;
25685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25697746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    /* Initialize sockets before anything else, so we can properly report
25707746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine     * initialization failures back to the UI. */
25717746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#ifdef _WIN32
25727746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    socket_init();
25737746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#endif
25747746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
2575a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    init_clocks();
2576a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
25775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cache_utils_init(envp);
25785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2579a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INIT (&vm_change_state_head);
2580c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    os_setup_early_signal_handling();
25815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_MACHINE);
25835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine = find_default_machine();
25845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_model = NULL;
25855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    initrd_filename = NULL;
25865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_size = 0;
25875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snapshot = 0;
25885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_filename = NULL;
25895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_cmdline = "";
25905f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner
25915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
25925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
25935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_device = "vc:80Cx24C";
25945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_devices[0] = "vc:80Cx24C";
25965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_SERIAL_PORTS; i++)
25975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        serial_devices[i] = NULL;
25985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_device_index = 0;
25995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_devices[0] = "vc:80Cx24C";
26015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
26025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        parallel_devices[i] = NULL;
26035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_device_index = 0;
26045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
26065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        virtio_consoles[i] = NULL;
26075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    virtio_console_index = 0;
26085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_NODES; i++) {
26105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_mem[i] = 0;
26115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_cpumask[i] = 0;
26125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_devices_index = 0;
26155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_net_clients = 0;
26175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_bt_opts = 0;
2618cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#ifdef MAX_DRIVES
26195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives = 0;
26205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt = 0;
2621cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif
26225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_numa_nodes = 0;
26235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_nics = 0;
26255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tb_size = 0;
26275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    autostart= 1;
26285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_watchdogs();
26305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2631b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Initialize boot properties. */
2632b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    boot_property_init_service();
2633ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner    android_hw_control_init();
2634d4d688e926097faba7fd3717d1c0d3f296bdb526David 'Digit' Turner    android_net_pipes_init();
2635b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
263636597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#ifdef CONFIG_KVM
263736597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner    /* By default, force auto-detection for kvm */
263836597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner    kvm_allowed = -1;
263936597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#endif
264036597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner
26415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optind = 1;
26425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
26435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (optind >= argc)
26445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
26455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        r = argv[optind];
26465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (r[0] != '-') {
2647cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner            hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
26485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
26495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const QEMUOption *popt;
26505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            optind++;
26525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Treat --foo the same as -foo.  */
26535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (r[1] == '-')
26545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                r++;
26555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            popt = qemu_options;
26565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(;;) {
26575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!popt->name) {
26587746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("%s: invalid option -- '%s'",
26597746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                      argv[0], r);
26605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
26615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strcmp(popt->name, r + 1))
26625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
26635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                popt++;
26645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
26655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (popt->flags & HAS_ARG) {
26665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (optind >= argc) {
26677746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("%s: option '%s' requires an argument",
26687746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                      argv[0], r);
26695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
26705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = argv[optind++];
26715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
26725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = NULL;
26735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
26745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch(popt->index) {
26765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_M:
26775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine = find_machine(optarg);
26785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!machine) {
26795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    QEMUMachine *m;
26805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    printf("Supported machines are:\n");
26815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for(m = first_machine; m != NULL; m = m->next) {
26825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("%-10s %s%s\n",
26835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->name, m->desc,
26845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->is_default ? " (default)" : "");
26855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
26867746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    if (*optarg != '?') {
26877746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("Invalid machine parameter: %s",
26887746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                          optarg);
26897746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    } else {
26907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        QEMU_EXIT(0);
26917746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    }
26925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
26935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
26945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cpu:
26955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* hw initialization will check this */
26965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*optarg == '?') {
26975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: implement xxx_cpu_list for targets that still miss it */
26985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(cpu_list)
26995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_list(stdout, &fprintf);
27005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27017746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    QEMU_EXIT(0);
27025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
27035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_model = optarg;
27045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
27055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_initrd:
27075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                initrd_filename = optarg;
27085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hda:
27105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (cyls == 0)
2711cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                    hda_opts = drive_add(optarg, HD_ALIAS, 0);
27125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else
2713cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                    hda_opts = drive_add(optarg, HD_ALIAS
27145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     ",cyls=%d,heads=%d,secs=%d%s",
27155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             0, cyls, heads, secs,
27165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_LBA ?
27175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=lba" :
27185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_NONE ?
27195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=none" : "");
27205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 break;
27215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdb:
27225f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                hdb_opts = drive_add(optarg, HD_ALIAS, 1);
27235f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                break;
27245f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
27255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdc:
27265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdd:
27275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
27285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_drive:
27305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(NULL, "%s", optarg);
27315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        break;
27325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mtdblock:
27335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, MTD_ALIAS);
27345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sd:
27365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, SD_ALIAS);
27375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pflash:
27395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, PFLASH_ALIAS);
27405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_snapshot:
27425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snapshot = 1;
27435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdachs:
27455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
27465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
27475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
27485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cyls = strtol(p, (char **)&p, 0);
27495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (cyls < 1 || cyls > 16383)
27505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
27515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
27525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
27535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
27545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    heads = strtol(p, (char **)&p, 0);
27555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (heads < 1 || heads > 16)
27565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
27575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
27585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
27595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
27605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    secs = strtol(p, (char **)&p, 0);
27615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (secs < 1 || secs > 63)
27625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
27635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == ',') {
27645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
27655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (!strcmp(p, "none"))
27665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_NONE;
27675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "lba"))
27685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_LBA;
27695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "auto"))
27705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_AUTO;
27715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else
27725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto chs_fail;
27735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p != '\0') {
27745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    chs_fail:
27757746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("qemu: invalid physical CHS format");
27765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
2777cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner		    if (hda_opts != NULL) {
2778cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        char num[16];
2779cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        snprintf(num, sizeof(num), "%d", cyls);
2780cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        qemu_opt_set(hda_opts, "cyls", num);
2781cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        snprintf(num, sizeof(num), "%d", heads);
2782cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        qemu_opt_set(hda_opts, "heads", num);
2783cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        snprintf(num, sizeof(num), "%d", secs);
2784cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        qemu_opt_set(hda_opts, "secs", num);
2785cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        if (translation == BIOS_ATA_TRANSLATION_LBA)
2786cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                            qemu_opt_set(hda_opts, "trans", "lba");
2787cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                        if (translation == BIOS_ATA_TRANSLATION_NONE)
2788cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                            qemu_opt_set(hda_opts, "trans", "none");
2789cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                    }
27905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
27915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_numa:
27935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_numa_nodes >= MAX_NODES) {
27947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many NUMA nodes");
27955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
27965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                numa_add(optarg);
27975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
27985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nographic:
27995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_NOGRAPHIC;
28005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_CURSES
28025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_curses:
28035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_CURSES;
28045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
28065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_portrait:
28075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                graphic_rotate = 1;
28085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_kernel:
28105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_filename = optarg;
28115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_append:
28135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_cmdline = optarg;
28145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cdrom:
28165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, CDROM_ALIAS);
28175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_boot:
28195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                boot_devices = optarg;
28205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* We just do some generic consistency checks */
28215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
28225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    /* Could easily be extended to 64 devices if needed */
28235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
2824d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
28255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    boot_devices_bitmap = 0;
28265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for (p = boot_devices; *p != '\0'; p++) {
28275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        /* Allowed boot devices are:
28285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * a b     : floppy disk drives
28295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * c ... f : IDE disk drives
28305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * g ... m : machine implementation dependant drives
28315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * n ... p : network devices
28325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * It's up to each machine implementation to check
28335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * if the given boot devices match the actual hardware
28345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * implementation and firmware features.
28355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         */
28365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (*p < 'a' || *p > 'q') {
28377746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                            PANIC("Invalid boot device '%c'", *p);
28385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
28395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
28407746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                            PANIC(
28417746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                    "Boot device '%c' was given twice",*p);
28425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
28435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        boot_devices_bitmap |= 1 << (*p - 'a');
28445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
28455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
28465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fda:
28485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fdb:
28495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
28505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
28525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_fd_bootchk:
28535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fd_bootchk = 0;
28545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
28565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_net:
28575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_net_clients >= MAX_NET_CLIENTS) {
28587746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many network clients");
28595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
28605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_clients[nb_net_clients] = optarg;
28615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_net_clients++;
28625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
28645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tftp:
28655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		tftp_prefix = optarg;
28665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bootp:
28685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bootp_filename = optarg;
28695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_redir:
28715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_slirp_redir(NULL, optarg, NULL);
28725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
28745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bt:
28755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_bt_opts >= MAX_BT_CMDLINE) {
28767746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many bluetooth options");
28775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
28785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bt_opts[nb_bt_opts++] = optarg;
28795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO
28815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_audio_help:
28825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                AUD_help ();
28837746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                QEMU_EXIT(0);
28845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_soundhw:
28865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_soundhw (optarg);
28875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
28895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_h:
28905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_help(0);
28915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_version:
28935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                version();
28947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                QEMU_EXIT(0);
28955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
28965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_m: {
28975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                uint64_t value;
28985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                char *ptr;
28995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = strtoul(optarg, &ptr, 10);
29015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                switch (*ptr) {
29025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 0: case 'M': case 'm':
29035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 20;
29045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
29055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 'G': case 'g':
29065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 30;
29075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
29085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                default:
29097746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: invalid ram size: %s", optarg);
29105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
29115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* On 32-bit hosts, QEMU is limited by virtual address space */
29135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value > (2047 << 20)
29145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_KQEMU
29155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    && HOST_LONG_BITS == 32
29165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
29175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    ) {
29187746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: at most 2047 MB RAM can be simulated");
29195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
29205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value != (uint64_t)(ram_addr_t)value) {
29217746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: ram size too large");
29225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
29235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ram_size = value;
29245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
29265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_d:
29275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
29285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int mask;
29295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const CPULogItem *item;
29305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    mask = cpu_str_to_log_mask(optarg);
29325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!mask) {
29335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Log items (comma separated):\n");
29347746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        for(item = cpu_log_items; item->mask != 0; item++) {
29357746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                            printf("%-10s %s\n", item->name, item->help);
29367746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        }
29377746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("Invalid parameter -d=%s", optarg);
29385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
29395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_set_log(mask);
29405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
29415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_s:
29435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
29445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_gdb:
29465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = optarg;
29475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_L:
29495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                data_dir = optarg;
29505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bios:
29525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bios_name = optarg;
29535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_singlestep:
29555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                singlestep = 1;
29565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_S:
29585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                autostart = 0;
29595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
29615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_k:
29625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		keyboard_layout = optarg;
29635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
29645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
29655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_localtime:
29665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_utc = 0;
29675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_vga:
29695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_vgahw (optarg);
29705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_PPC) || defined(TARGET_SPARC)
29725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_g:
29735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
29745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
29755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int w, h, depth;
29765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
29775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    w = strtol(p, (char **)&p, 10);
29785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (w <= 0) {
29795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_error:
29807746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("qemu: invalid resolution or depth");
29815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
29825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != 'x')
29835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
29845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
29855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    h = strtol(p, (char **)&p, 10);
29865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (h <= 0)
29875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
29885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == 'x') {
29895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
29905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = strtol(p, (char **)&p, 10);
29915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (depth != 8 && depth != 15 && depth != 16 &&
29925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            depth != 24 && depth != 32)
29935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto graphic_error;
29945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p == '\0') {
29955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = graphic_depth;
29965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
29975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
29985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
29995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_width = w;
30015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_height = h;
30025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_depth = depth;
30035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
30065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_echr:
30075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
30085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    char *r;
30095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    term_escape_char = strtol(optarg, &r, 0);
30105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (r == optarg)
30115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Bad argument to echr\n");
30125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
30135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_monitor:
30155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = optarg;
30165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_serial:
30185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (serial_device_index >= MAX_SERIAL_PORTS) {
30197746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many serial ports");
30205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[serial_device_index] = optarg;
30225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_device_index++;
30235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog:
30255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                i = select_watchdog(optarg);
30267746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                if (i > 0) {
30277746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    if (i == 1) {
30287746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("Invalid watchdog parameter: %s",
30297746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                          optarg);
30307746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    } else {
30317746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        QEMU_EXIT(0);
30327746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    }
30337746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                }
30345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog_action:
30365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (select_watchdog_action(optarg) == -1) {
30377746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Unknown -watchdog-action parameter");
30385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_virtiocon:
30415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
30427746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many virtio consoles");
30435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_consoles[virtio_console_index] = optarg;
30455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_console_index++;
30465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_parallel:
30485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
30497746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("qemu: too many parallel ports");
30505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_devices[parallel_device_index] = optarg;
30525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_device_index++;
30535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
305424204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock            case QEMU_OPTION_loadvm:
305524204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                loadvm = optarg;
305624204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                break;
305724204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock            case QEMU_OPTION_savevm_on_exit:
305824204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                savevm_on_exit = optarg;
305924204cc964cf7d56b1a20c12ece08eecab1093faTim Baverstock                break;
30605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_full_screen:
30615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                full_screen = 1;
30625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
30645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_frame:
30655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_frame = 1;
30665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_alt_grab:
30685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                alt_grab = 1;
30695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_quit:
30715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_quit = 1;
30725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sdl:
30745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_SDL;
30755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
30775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pidfile:
30785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pid_file = optarg;
30795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
30815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_win2k_hack:
30825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                win2k_install_hack = 1;
30835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_rtc_td_hack:
30855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_td_hack = 1;
30865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
3087334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#ifndef CONFIG_ANDROID
30885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_acpitable:
30895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(acpi_table_add(optarg) < 0) {
30907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Wrong acpi table provided");
30915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
30925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
3093334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#endif
30945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smbios:
3095ae3098a3bce898cf958a6c3334f3d62282b12d2aDavid 'Digit' Turner                do_smbios_option(optarg);
30965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
30975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
30985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KVM
30995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_enable_kvm:
31005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kvm_allowed = 1;
31015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
310236597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner            case QEMU_OPTION_disable_kvm:
310336597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner                kvm_allowed = 0;
310436597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner                break;
310536597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#endif /* CONFIG_KVM */
31065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usb:
31075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
31085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usbdevice:
31105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
31115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (usb_devices_index >= MAX_USB_CMDLINE) {
31127746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Too many USB devices");
31135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
31145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices[usb_devices_index] = optarg;
31155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices_index++;
31165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smp:
31185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                smp_cpus = atoi(optarg);
31195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (smp_cpus < 1) {
31207746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Invalid number of CPUs");
31215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
31225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_vnc:
31245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_VNC;
31255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		vnc_display = optarg;
31265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
31275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
31285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_acpi:
31295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                acpi_enabled = 0;
31305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_hpet:
31325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_hpet = 1;
31335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_virtio_balloon:
31355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_virtio_balloon = 1;
31365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_reboot:
31395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_reboot = 1;
31405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_shutdown:
31425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 1;
31435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_show_cursor:
31455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cursor_hide = 0;
31465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_uuid:
31485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
31497746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Fail to parse UUID string. Wrong format.");
31505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
31515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_option_rom:
31535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (nb_option_roms >= MAX_OPTION_ROMS) {
31547746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine		    PANIC("Too many option ROMs");
31555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
31565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		option_rom[nb_option_roms] = optarg;
31575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		nb_option_roms++;
31585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
31595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ARM) || defined(TARGET_M68K)
31605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_semihosting:
31615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                semihosting_enabled = 1;
31625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_name:
31655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_name = optarg;
31665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
31685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_prom_env:
31695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_prom_envs >= MAX_PROM_ENVS) {
31707746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Too many prom variables");
31715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
31725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                prom_envs[nb_prom_envs] = optarg;
31735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_prom_envs++;
31745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
31775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_old_param:
31785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                old_param = 1;
31795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_clock:
31825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                configure_alarms(optarg);
31835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
31845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_startdate:
31855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
31865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    struct tm tm;
3187dc46820125f5eaa0191193f5b71afba5f4915607David 'Digit' Turner                    time_t rtc_start_date = 0;
31885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!strcmp(optarg, "now")) {
31895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = -1;
31905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
31915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
31925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_year,
31935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mon,
31945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mday,
31955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_hour,
31965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_min,
31975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_sec) == 6) {
31985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            /* OK */
31995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else if (sscanf(optarg, "%d-%d-%d",
32005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_year,
32015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mon,
32025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mday) == 3) {
32035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_hour = 0;
32045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_min = 0;
32055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_sec = 0;
32065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else {
32075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto date_fail;
32085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
32095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_year -= 1900;
32105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_mon--;
32115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_start_date = mktimegm(&tm);
32125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (rtc_start_date == -1) {
32135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        date_fail:
32147746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                            PANIC("Invalid date format. Valid format are:\n"
32157746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
32165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
32175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = time(NULL) - rtc_start_date;
32185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
32195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
32205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
32217339b55944e97077e4f74c4be34cd956ae44198brich cannings
32227339b55944e97077e4f74c4be34cd956ae44198brich cannings            /* -------------------------------------------------------*/
32237339b55944e97077e4f74c4be34cd956ae44198brich cannings            /* User mode network stack restrictions */
32247339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_drop_udp:
32257339b55944e97077e4f74c4be34cd956ae44198brich cannings                slirp_drop_udp();
32267339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32277339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_drop_tcp:
32287339b55944e97077e4f74c4be34cd956ae44198brich cannings                slirp_drop_tcp();
32297339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32307339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_allow_tcp:
32317339b55944e97077e4f74c4be34cd956ae44198brich cannings                slirp_allow(optarg, IPPROTO_TCP);
32327339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32337339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_allow_udp:
32347339b55944e97077e4f74c4be34cd956ae44198brich cannings                slirp_allow(optarg, IPPROTO_UDP);
32357339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32367339b55944e97077e4f74c4be34cd956ae44198brich cannings             case QEMU_OPTION_drop_log:
32377339b55944e97077e4f74c4be34cd956ae44198brich cannings                {
32387339b55944e97077e4f74c4be34cd956ae44198brich cannings                    FILE* drop_log_fd;
3239d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                    drop_log_filename = optarg;
3240d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                    drop_log_fd = fopen(optarg, "w+");
32417339b55944e97077e4f74c4be34cd956ae44198brich cannings
32427339b55944e97077e4f74c4be34cd956ae44198brich cannings                    if (!drop_log_fd) {
32437339b55944e97077e4f74c4be34cd956ae44198brich cannings                        fprintf(stderr, "Cannot open drop log: %s\n", optarg);
32447339b55944e97077e4f74c4be34cd956ae44198brich cannings                        exit(1);
32457339b55944e97077e4f74c4be34cd956ae44198brich cannings                    }
32467339b55944e97077e4f74c4be34cd956ae44198brich cannings
32477339b55944e97077e4f74c4be34cd956ae44198brich cannings                    slirp_drop_log_fd(drop_log_fd);
32487339b55944e97077e4f74c4be34cd956ae44198brich cannings                }
32497339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32507339b55944e97077e4f74c4be34cd956ae44198brich cannings
32517339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_dns_log:
32527339b55944e97077e4f74c4be34cd956ae44198brich cannings                {
32537339b55944e97077e4f74c4be34cd956ae44198brich cannings                    FILE* dns_log_fd;
3254d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                    dns_log_filename = optarg;
3255d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings                    dns_log_fd = fopen(optarg, "wb+");
32567339b55944e97077e4f74c4be34cd956ae44198brich cannings
32577339b55944e97077e4f74c4be34cd956ae44198brich cannings                    if (dns_log_fd == NULL) {
32587339b55944e97077e4f74c4be34cd956ae44198brich cannings                        fprintf(stderr, "Cannot open dns log: %s\n", optarg);
32597339b55944e97077e4f74c4be34cd956ae44198brich cannings                        exit(1);
32607339b55944e97077e4f74c4be34cd956ae44198brich cannings                    }
32617339b55944e97077e4f74c4be34cd956ae44198brich cannings
32627339b55944e97077e4f74c4be34cd956ae44198brich cannings                    slirp_dns_log_fd(dns_log_fd);
32637339b55944e97077e4f74c4be34cd956ae44198brich cannings                }
32647339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32657339b55944e97077e4f74c4be34cd956ae44198brich cannings
32667339b55944e97077e4f74c4be34cd956ae44198brich cannings
32677339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_max_dns_conns:
32687339b55944e97077e4f74c4be34cd956ae44198brich cannings                {
32697339b55944e97077e4f74c4be34cd956ae44198brich cannings                    int max_dns_conns = 0;
32707339b55944e97077e4f74c4be34cd956ae44198brich cannings                    if (parse_int(optarg, &max_dns_conns)) {
32717339b55944e97077e4f74c4be34cd956ae44198brich cannings                      fprintf(stderr,
32727339b55944e97077e4f74c4be34cd956ae44198brich cannings                              "qemu: syntax: -max-dns-conns max_connections\n");
32737339b55944e97077e4f74c4be34cd956ae44198brich cannings                      exit(1);
32747339b55944e97077e4f74c4be34cd956ae44198brich cannings                    }
32757339b55944e97077e4f74c4be34cd956ae44198brich cannings                    if (max_dns_conns <= 0 ||  max_dns_conns == LONG_MAX) {
32767339b55944e97077e4f74c4be34cd956ae44198brich cannings                      fprintf(stderr,
32777339b55944e97077e4f74c4be34cd956ae44198brich cannings                              "Invalid arg for max dns connections: %s\n",
32787339b55944e97077e4f74c4be34cd956ae44198brich cannings                              optarg);
32797339b55944e97077e4f74c4be34cd956ae44198brich cannings                      exit(1);
32807339b55944e97077e4f74c4be34cd956ae44198brich cannings                    }
32817339b55944e97077e4f74c4be34cd956ae44198brich cannings                    slirp_set_max_dns_conns(max_dns_conns);
32827339b55944e97077e4f74c4be34cd956ae44198brich cannings                }
32837339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32847339b55944e97077e4f74c4be34cd956ae44198brich cannings
32857339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_net_forward:
32867339b55944e97077e4f74c4be34cd956ae44198brich cannings                net_slirp_forward(optarg);
32877339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
32887339b55944e97077e4f74c4be34cd956ae44198brich cannings            case QEMU_OPTION_net_forward_tcp2sink:
32897339b55944e97077e4f74c4be34cd956ae44198brich cannings                {
32907339b55944e97077e4f74c4be34cd956ae44198brich cannings                    SockAddress saddr;
32917339b55944e97077e4f74c4be34cd956ae44198brich cannings
32927339b55944e97077e4f74c4be34cd956ae44198brich cannings                    if (parse_host_port(&saddr, optarg)) {
32937339b55944e97077e4f74c4be34cd956ae44198brich cannings                        fprintf(stderr,
32947339b55944e97077e4f74c4be34cd956ae44198brich cannings                                "Invalid ip/port %s for "
32957339b55944e97077e4f74c4be34cd956ae44198brich cannings                                "-forward-dropped-tcp2sink. "
32967339b55944e97077e4f74c4be34cd956ae44198brich cannings                                "We expect 'sink_ip:sink_port'\n",
32977339b55944e97077e4f74c4be34cd956ae44198brich cannings                                optarg);
32987339b55944e97077e4f74c4be34cd956ae44198brich cannings                        exit(1);
32997339b55944e97077e4f74c4be34cd956ae44198brich cannings                    }
33007339b55944e97077e4f74c4be34cd956ae44198brich cannings                    slirp_forward_dropped_tcp2sink(saddr.u.inet.address,
33017339b55944e97077e4f74c4be34cd956ae44198brich cannings                                                   saddr.u.inet.port);
33027339b55944e97077e4f74c4be34cd956ae44198brich cannings                }
33037339b55944e97077e4f74c4be34cd956ae44198brich cannings                break;
33047339b55944e97077e4f74c4be34cd956ae44198brich cannings            /* -------------------------------------------------------*/
33057339b55944e97077e4f74c4be34cd956ae44198brich cannings
33065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tb_size:
33075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tb_size = strtol(optarg, NULL, 0);
33085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (tb_size < 0)
33095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tb_size = 0;
33105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_icount:
33126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                icount_option = optarg;
33135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_incoming:
33155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                incoming = optarg;
33165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_XEN
33185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_domid:
33195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_domid = atoi(optarg);
33205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_create:
33225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_CREATE;
33235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_attach:
33255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_ATTACH;
33265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mic:
33315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                audio_input_source = (char*)optarg;
33325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
3334a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner            case QEMU_OPTION_trace:
33355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_filename = optarg;
33365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tracing = 1;
33375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
33395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_miss:
33405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_cache_miss = 1;
33415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_addr:
33435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_all_addr = 1;
33445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tracing:
33475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strcmp(optarg, "off") == 0)
33485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 0;
33495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else if (strcmp(optarg, "on") == 0 && trace_filename)
33505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 1;
33515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else {
33527746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    PANIC("Unexpected option to -tracing ('%s')",
33535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            optarg);
33545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
33555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
33575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_load_miss:
33585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_load_miss_penalty = atoi(optarg);
33595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_store_miss:
33615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_store_miss_penalty = atoi(optarg);
33625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
33635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_NAND
33665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nand:
33675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nand_add_dev(optarg);
33685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
3369a381ef07088ce479610129e37bfef42538f397daJun Nakajima
33705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3371a381ef07088ce479610129e37bfef42538f397daJun Nakajima            case QEMU_OPTION_disable_hax:
3372a381ef07088ce479610129e37bfef42538f397daJun Nakajima                hax_disabled = 1;
3373a381ef07088ce479610129e37bfef42538f397daJun Nakajima                break;
3374d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_ports:
3375d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_ports = (char*)optarg;
3376d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
3377d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
3378d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_port:
3379d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_port = (char*)optarg;
3380d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
3381d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
3382d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_report_console:
3383d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_report_console = (char*)optarg;
3384d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
3385d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
3386d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_http_proxy:
3387d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                op_http_proxy = (char*)optarg;
3388d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
338943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
339043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            case QEMU_OPTION_charmap:
339143552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                op_charmap_file = (char*)optarg;
339243552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                break;
3393dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
3394074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine            case QEMU_OPTION_android_hw:
3395074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                android_op_hwini = (char*)optarg;
3396074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                break;
339713f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine
33987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            case QEMU_OPTION_dns_server:
33997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                android_op_dns_server = (char*)optarg;
34007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                break;
34017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
3402b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_radio:
3403b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_radio = (char*)optarg;
3404b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
3405b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3406b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_gps:
3407b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_gps = (char*)optarg;
3408b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
3409b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3410b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio:
3411b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio = (char*)optarg;
3412b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
3413b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3414b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_cpu_delay:
3415b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_cpu_delay = (char*)optarg;
3416b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
3417b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
341813f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine            case QEMU_OPTION_show_kernel:
341913f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine                android_kmsg_init(ANDROID_KMSG_PRINT_MESSAGES);
342013f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine                break;
342113f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine
3422e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
3423e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_nand_limits:
3424e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_nand_limits = (char*)optarg;
3425e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
3426e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
3427e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3428e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netspeed:
3429e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netspeed = (char*)optarg;
3430e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
3431e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3432e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netdelay:
3433e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netdelay = (char*)optarg;
3434e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
3435e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3436e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netfast:
3437e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netfast = 1;
3438e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
3439e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3440318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine            case QEMU_OPTION_tcpdump:
3441318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine                android_op_tcpdump = (char*)optarg;
3442318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine                break;
3443e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3444b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            case QEMU_OPTION_boot_property:
3445b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                boot_property_parse_option((char*)optarg);
3446b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                break;
3447b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
3448b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            case QEMU_OPTION_lcd_density:
3449b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                android_op_lcd_density = (char*)optarg;
3450b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                break;
3451b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
34527746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            case QEMU_OPTION_ui_port:
34537746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                android_op_ui_port = (char*)optarg;
34547746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                break;
34557746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
34567746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            case QEMU_OPTION_ui_settings:
34577746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                android_op_ui_settings = (char*)optarg;
34587746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                break;
34597746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
3460ca29fbbb188a1aab9b69776d5dc6bc3e7f812a0aDavid 'Digit' Turner            case QEMU_OPTION_audio_test_out:
3461ca29fbbb188a1aab9b69776d5dc6bc3e7f812a0aDavid 'Digit' Turner                android_audio_test_start_out();
3462ca29fbbb188a1aab9b69776d5dc6bc3e7f812a0aDavid 'Digit' Turner                break;
3463ca29fbbb188a1aab9b69776d5dc6bc3e7f812a0aDavid 'Digit' Turner
346490c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine            case QEMU_OPTION_android_avdname:
346590c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                android_op_avd_name = (char*)optarg;
346690c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                break;
346790c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine
346890c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine            case QEMU_OPTION_timezone:
346990c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                if (timezone_set((char*)optarg)) {
347090c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                    fprintf(stderr, "emulator: it seems the timezone '%s' is not in zoneinfo format\n",
347190c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                            (char*)optarg);
347290c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                }
347390c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine                break;
347490c6235ce7bdc6f7afbcfe56ea6f2c3d2b128447Vladimir Chtchetkine
3475b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
3476b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine            case QEMU_OPTION_android_memcheck:
3477b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                android_op_memcheck = (char*)optarg;
34787fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                /* This will set ro.kernel.memcheck system property
34797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                 * to memcheck's tracing flags. */
34805f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                stralloc_add_format(kernel_config, " memcheck=%s", android_op_memcheck);
3481b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                break;
3482b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif // CONFIG_MEMCHECK
3483bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
3484bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner            case QEMU_OPTION_snapshot_no_time_update:
3485bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner                android_snapshot_update_time = 0;
3486bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner                break;
3487b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine
3488b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine            case QEMU_OPTION_list_webcam:
3489b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine                android_list_web_cameras();
3490b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine                exit(0);
3491b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine
3492c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner            default:
3493c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner                os_parse_cmd_args(popt->index, optarg);
34945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
34955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
34965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
34975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
349843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    /* Initialize character map. */
349943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (android_charmap_setup(op_charmap_file)) {
350043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        if (op_charmap_file) {
35017746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC(
35027746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    "Unable to initialize character map from file %s.",
350343552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    op_charmap_file);
350443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        } else {
35057746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC(
35067746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                    "Unable to initialize default character map.");
350743552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        }
350843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
350943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
35105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If no data_dir is specified then try to find it relative to the
35115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       executable path.  */
35125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
35135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = find_datadir(argv[0]);
35145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If all else fails use the install patch specified when building.  */
35165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
35175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = CONFIG_QEMU_SHAREDIR;
35185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35202507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    if (!android_op_hwini) {
35212507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        PANIC("Missing -android-hw <file> option!");
35222507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    }
35232507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    hw_ini = iniFile_newFromFile(android_op_hwini);
35242507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    if (hw_ini == NULL) {
35257746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("Could not find %s file.", android_op_hwini);
3526074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    }
3527b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner
3528b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    androidHwConfig_init(android_hw, 0);
3529074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    androidHwConfig_read(android_hw, hw_ini);
3530b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner
3531db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    /* If we're loading VM from a snapshot, make sure that the current HW config
3532db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine     * matches the one with which the VM has been saved. */
3533db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    if (loadvm && *loadvm && !snaphost_match_configs(hw_ini, loadvm)) {
3534db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        exit(0);
3535db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine    }
3536db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine
3537074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    iniFile_free(hw_ini);
35382507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner
35392507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    {
35402507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        int width  = android_hw->hw_lcd_width;
35412507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        int height = android_hw->hw_lcd_height;
35422507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        int depth  = android_hw->hw_lcd_depth;
35432507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner
35442507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        /* A bit of sanity checking */
35452507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        if (width <= 0 || height <= 0    ||
35462507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner            (depth != 16 && depth != 32) ||
35472507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner            (((width|height) & 3) != 0)  )
35482507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        {
35492507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner            PANIC("Invalid display configuration (%d,%d,%d)",
35502507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner                  width, height, depth);
35512507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        }
35522507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        android_display_width  = width;
35532507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        android_display_height = height;
35542507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner        android_display_bpp    = depth;
35552507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    }
3556074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
3557e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
3558e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    /* Init nand stuff. */
3559e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_op_nand_limits) {
3560e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        parse_nand_limits(android_op_nand_limits);
3561e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
3562e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
3563e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
356453eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    /* Initialize AVD name from hardware configuration if needed */
356553eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    if (!android_op_avd_name) {
356653eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner        if (android_hw->avd_name && *android_hw->avd_name) {
356753eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner            android_op_avd_name = android_hw->avd_name;
356853eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner            VERBOSE_PRINT(init,"AVD Name: %s", android_op_avd_name);
356953eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner        }
357053eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    }
357153eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner
357240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /* Initialize system partition image */
357340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    {
357440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char        tmp[PATH_MAX+32];
357540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        const char* sysImage = android_hw->disk_systemPartition_path;
357640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        const char* initImage = android_hw->disk_systemPartition_initPath;
357740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        uint64_t    sysBytes = android_hw->disk_systemPartition_size;
357840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
357940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sysBytes == 0) {
3580c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh            PANIC("Invalid system partition size: %" PRIu64, sysBytes);
358140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
358240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
3583c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh        snprintf(tmp,sizeof(tmp),"system,size=0x%" PRIx64, sysBytes);
358440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
358540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sysImage && *sysImage) {
358640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (filelock_create(sysImage) == NULL) {
358740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                fprintf(stderr,"WARNING: System image already in use, changes will not persist!\n");
358840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* If there is no file= parameters, nand_add_dev will create
358940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                 * a temporary file to back the partition image. */
359040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            } else {
359140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                pstrcat(tmp,sizeof(tmp),",file=");
359240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                pstrcat(tmp,sizeof(tmp),sysImage);
359340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
359440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
359540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (initImage && *initImage) {
359640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (!path_exists(initImage)) {
359740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                PANIC("Invalid initial system image path: %s", initImage);
359840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
359940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            pstrcat(tmp,sizeof(tmp),",initfile=");
360040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            pstrcat(tmp,sizeof(tmp),initImage);
360140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } else {
360240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            PANIC("Missing initial system image path!");
360340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
360440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        nand_add_dev(tmp);
360540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
360640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
3607fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    /* Initialize data partition image */
3608fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    {
3609fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char        tmp[PATH_MAX+32];
3610fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        const char* dataImage = android_hw->disk_dataPartition_path;
3611fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        const char* initImage = android_hw->disk_dataPartition_initPath;
3612fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        uint64_t    dataBytes = android_hw->disk_dataPartition_size;
3613fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
3614fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (dataBytes == 0) {
3615c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh            PANIC("Invalid data partition size: %" PRIu64, dataBytes);
3616fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
3617fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
3618c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh        snprintf(tmp,sizeof(tmp),"userdata,size=0x%" PRIx64, dataBytes);
3619fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
3620fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (dataImage && *dataImage) {
3621fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (filelock_create(dataImage) == NULL) {
3622fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                fprintf(stderr, "WARNING: Data partition already in use. Changes will not persist!\n");
3623fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                /* Note: if there is no file= parameters, nand_add_dev() will
3624fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                 *       create a temporary file to back the partition image. */
3625fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            } else {
3626fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                /* Create the file if needed */
3627fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (!path_exists(dataImage)) {
3628e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                    if (path_empty_file(dataImage) < 0) {
3629e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                        PANIC("Could not create data image file %s: %s", dataImage, strerror(errno));
3630e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                    }
3631fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
3632fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                pstrcat(tmp, sizeof(tmp), ",file=");
3633fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                pstrcat(tmp, sizeof(tmp), dataImage);
3634fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
3635fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
3636fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (initImage && *initImage) {
3637fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            pstrcat(tmp, sizeof(tmp), ",initfile=");
3638fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            pstrcat(tmp, sizeof(tmp), initImage);
3639fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
3640fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        nand_add_dev(tmp);
3641fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
3642fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
364348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /* Init SD-Card stuff. For Android, it is always hda */
364448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /* If the -hda option was used, ignore the Android-provided one */
364548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    if (hda_opts == NULL) {
364648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        const char* sdPath = android_hw->hw_sdCard_path;
364748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (sdPath && *sdPath) {
364848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (!path_exists(sdPath)) {
364948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                fprintf(stderr, "WARNING: SD Card image is missing: %s\n", sdPath);
365048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            } else if (filelock_create(sdPath) == NULL) {
365148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                fprintf(stderr, "WARNING: SD Card image already in use: %s\n", sdPath);
365248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            } else {
365348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Successful locking */
365448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                hda_opts = drive_add(sdPath, HD_ALIAS, 0);
36558fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                /* Set this property of any operation involving the SD Card
36568fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                 * will be x100 slower, due to the corresponding file being
36578fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                 * mounted as O_DIRECT. Note that this is only 'unsafe' in
36588fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                 * the context of an emulator crash. The data is already
36598fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                 * synced properly when the emulator exits (either normally or through ^C).
36608fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                 */
36618fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner                qemu_opt_set(hda_opts, "cache", "unsafe");
366248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
366348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
366448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    }
366548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
36665f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (hdb_opts == NULL) {
36675f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        const char* spath = android_hw->disk_snapStorage_path;
36685f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (spath && *spath) {
36695f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (!path_exists(spath)) {
36705f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                PANIC("Snapshot storage file does not exist: %s", spath);
36715f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            }
36725f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (filelock_create(spath) == NULL) {
36734297b82edb9d528928fb168cb14abd4955f8664bDavid 'Digit' Turner                PANIC("Snapshot storage already in use: %s", spath);
36745f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            }
36755f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            hdb_opts = drive_add(spath, HD_ALIAS, 1);
36768fc3e6effd925b9ebe39268c6ccbf9e8730ef3d4David 'Digit' Turner            /* See comment above to understand why this is needed. */
36779fb360ec4c47d750711c8f1776c180e3802b0aabDavid 'Digit' Turner            qemu_opt_set(hdb_opts, "cache", "unsafe");
36785f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
36795f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
36805f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
3681b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Set the VM's max heap size, passed as a boot property */
3682b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (android_hw->vm_heapSize > 0) {
3683b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        char  tmp[64];
3684b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        snprintf(tmp, sizeof(tmp), "%dm", android_hw->vm_heapSize);
3685b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        boot_property_add("dalvik.vm.heapsize",tmp);
3686b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
3687b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
3688e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    /* Initialize net speed and delays stuff. */
3689e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_parse_network_speed(android_op_netspeed) < 0 ) {
36907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("invalid -netspeed parameter '%s'",
3691e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netspeed);
3692e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
3693e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3694e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
36957746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("invalid -netdelay parameter '%s'",
3696e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netdelay);
3697e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
3698e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3699e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_op_netfast) {
3700e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_download_speed = 0;
3701e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_upload_speed = 0;
3702e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_min_latency = 0;
3703e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_max_latency = 0;
3704e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
3705e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
3706b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Initialize LCD density */
37075377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    if (android_hw->hw_lcd_density) {
37085377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        long density = android_hw->hw_lcd_density;
37095377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        if (density <= 0) {
37105377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            PANIC("Invalid hw.lcd.density value: %ld", density);
3711b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        }
3712b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        hwLcd_setBootProperty(density);
3713b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
3714b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
3715fa0c8e25403290b545bb98735b1ece275c524361Xavier Ducrohet    /* Initialize presence of hardware nav button */
3716fa0c8e25403290b545bb98735b1ece275c524361Xavier Ducrohet    boot_property_add("qemu.hw.mainkeys", android_hw->hw_mainKeys ? "1" : "0");
3717fa0c8e25403290b545bb98735b1ece275c524361Xavier Ducrohet
3718318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    /* Initialize TCP dump */
3719318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    if (android_op_tcpdump) {
3720318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        if (qemu_tcpdump_start(android_op_tcpdump) < 0) {
3721318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine            fprintf(stdout, "could not start packet capture: %s\n", strerror(errno));
3722318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        }
3723318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    }
3724318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
3725b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize modem */
3726b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_radio) {
3727b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("radio", android_op_radio, NULL);
3728b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
37297746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("unsupported character device specification: %s\n"
37307746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        "used -help-char-devices for list of available formats",
3731b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_radio);
3732b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3733b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
3734b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gsmModem != 0 ) {
3735b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
37367746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("could not initialize qemud 'gsm' channel");
3737b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3738b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
3739b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3740b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize GPS */
3741b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_gps) {
3742b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("gps", android_op_gps, NULL);
3743b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
37447746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("unsupported character device specification: %s\n"
37457746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        "used -help-char-devices for list of available formats",
3746b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_gps);
3747b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3748b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
3749b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gps != 0) {
3750b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
37517746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("could not initialize qemud 'gps' channel");
3752b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3753b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
3754b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3755b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize audio. */
3756b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio) {
3757b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 0, android_op_audio ) ) {
37587746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
3759b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio);
3760b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3761f816a75ca5b357563a4ecf996e95b24ffabd0b54David 'Digit' Turner        setenv("QEMU_AUDIO_DRV", android_op_audio, 1);
3762b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
3763b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
37645b48149747c214e9951fd8ce0926c45d6926fc3dDavid 'Digit' Turner    /* Initialize OpenGLES emulation */
3765d4d688e926097faba7fd3717d1c0d3f296bdb526David 'Digit' Turner    //android_hw_opengles_init();
37665b48149747c214e9951fd8ce0926c45d6926fc3dDavid 'Digit' Turner
3767ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine    /* Initialize fake camera */
37687485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (strcmp(android_hw->hw_camera_back, "emulated") &&
37697485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        strcmp(android_hw->hw_camera_front, "emulated")) {
37707485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Fake camera is not used for camera emulation. */
37717485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        boot_property_add("qemu.sf.fake_camera", "none");
3772ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine    } else {
37737485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Fake camera is used for at least one camera emulation. */
37747485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        if (!strcmp(android_hw->hw_camera_back, "emulated") &&
37757485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            !strcmp(android_hw->hw_camera_front, "emulated")) {
37767485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            /* Fake camera is used for both, front and back camera emulation. */
37777485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            boot_property_add("qemu.sf.fake_camera", "both");
37787485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        } else if (!strcmp(android_hw->hw_camera_back, "emulated")) {
37797485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            boot_property_add("qemu.sf.fake_camera", "back");
37807485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        } else {
37817485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            boot_property_add("qemu.sf.fake_camera", "front");
37827485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        }
3783ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine    }
3784ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine
3785b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine    /* Initialize camera emulation. */
3786b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine    android_camera_service_init();
3787b8dcaffaf7dcb0c795d2776abf3bb75196f8527cVladimir Chtchetkine
3788b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_cpu_delay) {
3789b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        char*   end;
3790b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        long    delay = strtol(android_op_cpu_delay, &end, 0);
3791b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (end == NULL || *end || delay < 0 || delay > 1000 ) {
37927746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("option -cpu-delay must be an integer between 0 and 1000" );
3793b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
3794b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (delay > 0)
3795b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            delay = (1000-delay);
3796b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
3797b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        qemu_cpu_delay = (int) delay;
3798b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
3799b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
38007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (android_op_dns_server) {
38017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        char*  x = strchr(android_op_dns_server, ',');
38027fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = 0;
38037fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (x == NULL)
38047fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
38057fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            if ( add_dns_server( android_op_dns_server ) == 0 )
38067fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                dns_count = 1;
38077fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
38087fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        else
38097fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
38107fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            x = android_op_dns_server;
38117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            while (*x) {
38127fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                char*  y = strchr(x, ',');
38137fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
38147fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y != NULL) {
38157fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    *y = 0;
38167fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y++;
38177fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                } else {
38187fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y = x + strlen(x);
38197fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
38207fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
38217fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y > x && add_dns_server( x ) == 0) {
38227fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    dns_count += 1;
38237fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
38247fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                x = y;
38257fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            }
38267fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
38277fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (dns_count == 0)
38287fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            fprintf( stdout, "### WARNING: will use system default DNS server\n" );
38297fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
38307fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
38317fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count == 0)
38327fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = slirp_get_system_dns_servers();
38337fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count) {
38345f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        stralloc_add_format(kernel_config, " ndns=%d", dns_count);
38357fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
38367fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
3837b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
3838b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (android_op_memcheck) {
3839b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        memcheck_init(android_op_memcheck);
3840b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
3841b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
3842b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
3843c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /* Initialize cache partition, if any */
3844c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    if (android_hw->disk_cachePartition != 0) {
3845c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        char        tmp[PATH_MAX+32];
3846c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        const char* partPath = android_hw->disk_cachePartition_path;
3847e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner        uint64_t    partSize = android_hw->disk_cachePartition_size;
3848c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
3849c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh        snprintf(tmp,sizeof(tmp),"cache,size=0x%" PRIx64, partSize);
3850e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner
3851e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner        if (partPath && *partPath && strcmp(partPath, "<temp>") != 0) {
3852e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner            if (filelock_create(partPath) == NULL) {
3853e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                fprintf(stderr, "WARNING: Cache partition already in use. Changes will not persist!\n");
3854e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                /* Note: if there is no file= parameters, nand_add_dev() will
3855e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                 *       create a temporary file to back the partition image. */
3856e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner            } else {
3857e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                /* Create the file if needed */
3858e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                if (!path_exists(partPath)) {
3859e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                    if (path_empty_file(partPath) < 0) {
3860e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                        PANIC("Could not create cache image file %s: %s", partPath, strerror(errno));
3861e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                    }
3862e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                }
3863e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                pstrcat(tmp, sizeof(tmp), ",file=");
3864e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner                pstrcat(tmp, sizeof(tmp), partPath);
3865e8ab08c1ee27349cb81cd5e8849a01a85da16775David 'Digit' Turner            }
3866c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
3867c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        nand_add_dev(tmp);
3868c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    }
3869c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
3870cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    /* qemu.gles will be read by the OpenGLES emulation libraries.
3871cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    * If set to 0, the software GLES renderer will be used as a fallback.
3872cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    * If the parameter is undefined, this means the system image runs
3873cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    * inside an emulator that doesn't support GPU emulation at all.
3874cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    */
3875cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    {
3876cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        int  gles_emul = 0;
3877cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner
3878cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        if (android_hw->hw_gpu_enabled) {
3879cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner            if (android_initOpenglesEmulation() == 0) {
3880cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner                gles_emul = 1;
38811a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine                /* Set framebuffer change notification callback when starting
38821a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine                 * GLES emulation. Currently only multi-touch emulation is
38831a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine                 * interested in FB changes (to transmit them to the device), so
38841a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine                 * the callback is set within MT emulation.*/
38857105d422d800a624b4257798e0d81ec2045491d8Jesse Hall                android_startOpenglesRenderer(android_hw->hw_lcd_width, android_hw->hw_lcd_height,
38861a820e90d8848c6b0ac7c78b5a2e8b28c9738a3aVladimir Chtchetkine                                              multitouch_opengles_fb_update, NULL);
3887cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner            } else {
3888cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner                dwarning("Could not initialize OpenglES emulation, using software renderer.");
3889cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner            }
3890cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        }
3891cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        if (gles_emul) {
3892cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner            stralloc_add_str(kernel_params, " qemu.gles=1");
3893cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        } else {
3894cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner            stralloc_add_str(kernel_params, " qemu.gles=0");
3895cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner        }
3896cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner    }
3897cb88e79ecbd16dea5f2201fd12320db5945db83eDavid 'Digit' Turner
3898062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    /* We always force qemu=1 when running inside QEMU */
3899062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    stralloc_add_str(kernel_params, " qemu=1");
3900062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
3901062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    /* We always initialize the first serial port for the android-kmsg
3902062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner     * character device (used to send kernel messages) */
3903062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    serial_hds_add_at(0, "android-kmsg");
3904062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    stralloc_add_str(kernel_params, " console=ttyS0");
3905062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
3906062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    /* We always initialize the second serial port for the android-qemud
3907062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner     * character device as well */
3908062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    serial_hds_add_at(1, "android-qemud");
3909062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    stralloc_add_str(kernel_params, " android.qemud=ttyS1");
3910062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
3911c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
3912c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner        os_pidfile_error();
3913c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner        exit(1);
3914c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    }
3915c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner
391636597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#if defined(CONFIG_KVM)
391736597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner    if (kvm_allowed < 0) {
391836597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner        kvm_allowed = kvm_check_allowed();
391936597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner    }
392036597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner#endif
392136597756e589622ee6c6628efb47c1b130d5ee85David 'Digit' Turner
39225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
39235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_allowed && kqemu_allowed) {
39247746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC(
39257746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                "You can not enable both KVM and kqemu at the same time");
39265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
39285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
39305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > machine->max_cpus) {
39317746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
39327746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                "supported by machine `%s' (%d)", smp_cpus,  machine->name,
39335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine->max_cpus);
39345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC) {
39375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (serial_device_index == 0)
39385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           serial_devices[0] = "stdio";
39395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (parallel_device_index == 0)
39405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           parallel_devices[0] = "null";
39415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strncmp(monitor_device, "vc", 2) == 0)
39425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           monitor_device = "stdio";
39435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
39465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > 1)
39475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_allowed = 0;
39485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
39495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_init_main_loop()) {
39507746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("qemu_init_main_loop failed");
39515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39520b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
39530b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    if (kernel_filename == NULL) {
39540b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        kernel_filename = android_hw->kernel_path;
39550b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    }
39560b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    if (initrd_filename == NULL) {
39570b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        initrd_filename = android_hw->disk_ramdisk_path;
39580b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    }
39590b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
39605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    linux_boot = (kernel_filename != NULL);
39615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
39625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && *kernel_cmdline != '\0') {
39647746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("-append only allowed with -kernel option");
39655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && initrd_filename != NULL) {
39687746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("-initrd only allowed with -kernel option");
39695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* boot to floppy or the default cd if no hard disk defined yet */
39725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!boot_devices[0]) {
39735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        boot_devices = "cad";
39745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
3975c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    os_set_line_buffering();
39765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (init_timer_alarm() < 0) {
39787746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("could not initialize alarm timer");
39795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    configure_icount(icount_option);
39815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init network clients */
39835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_net_clients == 0) {
39845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if no clients, we use a default config */
39855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "nic";
39865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
39875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "user";
39885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
39895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0;i < nb_net_clients; i++) {
39927746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        if (net_client_parse(net_clients[i]) < 0) {
39937746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("Unable to parse net clients");
39947746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        }
39955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_client_check();
39975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
39995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: this should be moved in the PC machine instantiation code */
40005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (net_boot != 0) {
40015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int netroms = 0;
40025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (i = 0; i < nb_nics && i < 4; i++) {
40035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    const char *model = nd_table[i].model;
40045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    char buf[1024];
40055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char *filename;
40065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (net_boot & (1 << i)) {
40075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (model == NULL)
40085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    model = "ne2k_pci";
40095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
40105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
40115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename && get_image_size(filename) > 0) {
40125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (nb_option_roms >= MAX_OPTION_ROMS) {
40137746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                        PANIC("Too many option ROMs");
40145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
40155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    option_rom[nb_option_roms] = qemu_strdup(buf);
40165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    nb_option_roms++;
40175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    netroms++;
40185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
40195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename) {
40205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    qemu_free(filename);
40215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
40225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
40235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
40245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (netroms == 0) {
40257746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine	    PANIC("No valid PXE rom found for network device");
40265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
40275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
40295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the bluetooth world */
40315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < nb_bt_opts; i++)
40327746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        if (bt_parse(bt_opts[i])) {
40337746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("Unable to parse bluetooth options");
40347746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        }
40355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the memory */
40375377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    if (ram_size == 0) {
40385377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        ram_size = android_hw->hw_ramSize * 1024LL * 1024;
40395377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        if (ram_size == 0) {
40405377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
40415377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        }
40425377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    }
40435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
40455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
40465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       guest ram allocation.  It needs to go away.  */
40475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kqemu_allowed) {
40485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
40495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
40505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!kqemu_phys_ram_base) {
40517746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("Could not allocate physical memory");
40525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
40535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
40555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4056d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings#ifndef _WIN32
4057d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings    init_qemu_clear_logs_sig();
4058d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings#endif
4059d952f28e527175cc3df9ebd91e739e34df2194c9rich cannings
40605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the dynamic translator */
40615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_exec_init_all(tb_size * 1024 * 1024);
40625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_init();
40645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create the cdrom drive, even if no disk is there */
4066cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#if 0
40675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
40685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, CDROM_ALIAS);
40695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create at least one floppy */
40715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
40735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, FD_ALIAS, 0);
40745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create one sd slot, even if no card is in it */
40755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4076cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (1) {
40775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, SD_ALIAS);
4078cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    }
4079cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner#endif
40805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* open the virtual block devices */
4082cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (snapshot)
4083cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0);
4084cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, &machine->use_scsi, 1) != 0)
4085cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner        exit(1);
40865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
40885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
40895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* must be after terminal init, SDL library changes signal handlers */
4091c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    os_setup_signal_handling();
40925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Maintain compatibility with multiple stdio monitors */
40945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(monitor_device,"stdio")) {
40955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
40965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const char *devname = serial_devices[i];
40975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (devname && !strcmp(devname,"mon:stdio")) {
40985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
40995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else if (devname && !strcmp(devname,"stdio")) {
41015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
41025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[i] = "mon:stdio";
41035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_numa_nodes > 0) {
41095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int i;
41105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (nb_numa_nodes > smp_cpus) {
41125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_numa_nodes = smp_cpus;
41135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* If no memory size if given for any node, assume the default case
41165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * and distribute the available memory equally across all nodes
41175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
41185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
41195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_mem[i] != 0)
41205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
41235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint64_t usedmem = 0;
41245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* On Linux, the each node's border has to be 8MB aligned,
41265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             * the final node gets the rest.
41275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             */
41285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < nb_numa_nodes - 1; i++) {
41295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
41305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usedmem += node_mem[i];
41315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[i] = ram_size - usedmem;
41335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
41365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] != 0)
41375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* assigning the VCPUs round-robin is easier to implement, guest OSes
41405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * must cope with this anyway, because there are BIOSes out there in
41415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * real machines which also use this scheme.
41425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
41435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
41445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < smp_cpus; i++) {
41455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_cpumask[i % nb_numa_nodes] |= 1 << i;
41465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
41515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
41525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_init(smp_cpus);
41545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
41557746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("failed to initialize KVM");
41565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4159a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX
4160a381ef07088ce479610129e37bfef42538f397daJun Nakajima    if (!hax_disabled)
4161a381ef07088ce479610129e37bfef42538f397daJun Nakajima    {
4162a381ef07088ce479610129e37bfef42538f397daJun Nakajima        int ret;
4163a381ef07088ce479610129e37bfef42538f397daJun Nakajima
41644a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong        hax_set_ramsize(ram_size);
4165a381ef07088ce479610129e37bfef42538f397daJun Nakajima        ret = hax_init(smp_cpus);
4166a381ef07088ce479610129e37bfef42538f397daJun Nakajima        fprintf(stderr, "HAX is %s and emulator runs in %s mode\n",
4167a381ef07088ce479610129e37bfef42538f397daJun Nakajima            !ret ? "working" :"not working", !ret ? "fast virt" : "emulation");
4168a381ef07088ce479610129e37bfef42538f397daJun Nakajima    }
4169a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif
4170a381ef07088ce479610129e37bfef42538f397daJun Nakajima
41715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device) {
41725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
41735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!monitor_hd) {
41747746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("qemu: could not open monitor device '%s'",
41757746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                              monitor_device);
41765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
4180062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        serial_hds_add(serial_devices[i]);
41815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
41845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
41855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
41865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
41875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "parallel%d", i);
41885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            parallel_hds[i] = qemu_chr_open(label, devname, NULL);
41895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!parallel_hds[i]) {
41907746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                PANIC("qemu: could not open parallel device '%s'",
41915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
41925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
41975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
41985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
41995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
42005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "virtcon%d", i);
42015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
42025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!virtcon_hds[i]) {
42037746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine                PANIC("qemu: could not open virtio console '%s'",
42045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
42055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
42065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
42075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_DEVICE);
42105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
42135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (trace_filename) {
42145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        trace_init(trace_filename);
42155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
42165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
42185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42192d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    /* Check the CPU Architecture value */
42202d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#if defined(TARGET_ARM)
42212d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (strcmp(android_hw->hw_cpu_arch,"arm") != 0) {
42222d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        fprintf(stderr, "-- Invalid CPU architecture: %s, expected 'arm'\n",
42232d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner                android_hw->hw_cpu_arch);
42242d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        exit(1);
42252d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
422633f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#elif defined(TARGET_I386)
42272d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (strcmp(android_hw->hw_cpu_arch,"x86") != 0) {
42282d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        fprintf(stderr, "-- Invalid CPU architecture: %s, expected 'x86'\n",
42292d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner                android_hw->hw_cpu_arch);
42302d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        exit(1);
42312d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
42322d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner#endif
42332d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
42342d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    /* Grab CPU model if provided in hardware.ini */
42352d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    if (    !cpu_model
42362d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner         && android_hw->hw_cpu_model
42372d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner         && android_hw->hw_cpu_model[0] != '\0')
42382d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    {
42392d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner        cpu_model = android_hw->hw_cpu_model;
42402d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner    }
42412d238fd9871687b1557f15b8878a6cf3e9634b57David 'Digit' Turner
42427fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Combine kernel command line passed from the UI with parameters
42435f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     * collected during initialization.
42445f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     *
42455f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     * The order is the following:
42465f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     * - parameters from the hw configuration (kernel.parameters)
42475f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     * - additionnal parameters from options (e.g. -memcheck)
42485f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     * - the -append parameters.
42495f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner     */
42505f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner    {
42515f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        const char* kernel_parameters;
42525f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner
42530b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (android_hw->kernel_parameters) {
425462c7ae56be1ada62e89221352a0fa3e412929ffaDavid 'Digit' Turner            stralloc_add_c(kernel_params, ' ');
42550b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            stralloc_add_str(kernel_params, android_hw->kernel_parameters);
42560b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
42570b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
42585f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        /* If not empty, kernel_config always contains a leading space */
42595f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        stralloc_append(kernel_params, kernel_config);
42605f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner
42615f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        if (*kernel_cmdline) {
42625f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner            stralloc_add_c(kernel_params, ' ');
42635f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner            stralloc_add_str(kernel_params, kernel_cmdline);
42647fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
42657fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
4266062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        /* Remove any leading/trailing spaces */
4267062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        stralloc_strip(kernel_params);
4268062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
42695f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        kernel_parameters = stralloc_cstr(kernel_params);
42705f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        VERBOSE_PRINT(init, "Kernel parameters: %s", kernel_parameters);
42715f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner
42725f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        machine->init(ram_size,
42735f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                      boot_devices,
42745f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                      kernel_filename,
42755f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                      kernel_parameters,
42765f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                      initrd_filename,
42775f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner                      cpu_model);
42785f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner
42798dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine        /* Initialize multi-touch emulation. */
4280863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine        if (androidHwConfig_isScreenMultiTouch(android_hw)) {
42818dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine            mts_port_create(NULL);
42828dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine        }
42838dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine
42845f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        stralloc_reset(kernel_params);
42855f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner        stralloc_reset(kernel_config);
42865f82411f73a9913588d8cef751db870b4239a6a4David 'Digit' Turner    }
42875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu) {
42895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
42905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] & (1 << env->cpu_index)) {
42915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->numa_node = i;
42925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
42935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
42945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    current_machine = machine;
42975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Set KVM's vcpu state to qemu's initial CPUState. */
42995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
43005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
43015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_sync_vcpus();
43035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
43047746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("failed to initialize vcpus");
43055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4308a381ef07088ce479610129e37bfef42538f397daJun Nakajima#ifdef CONFIG_HAX
4309a381ef07088ce479610129e37bfef42538f397daJun Nakajima    if (hax_enabled())
4310a381ef07088ce479610129e37bfef42538f397daJun Nakajima        hax_sync_vcpus();
4311a381ef07088ce479610129e37bfef42538f397daJun Nakajima#endif
4312a381ef07088ce479610129e37bfef42538f397daJun Nakajima
43135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init USB devices */
43145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (usb_enabled) {
43155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(i = 0; i < usb_devices_index; i++) {
43165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (usb_device_add(usb_devices[i], 0) < 0) {
43175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Warning: could not add USB device %s\n",
43185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        usb_devices[i]);
43195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
43205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4323cf755ea6f4b850a6afd12ef8308da8def7ba8941Vladimir Chtchetkine    /* just use the first displaystate for the moment */
432494702b0dc4a9729b234c6f0265a9e43c72ef79adDavid 'Digit' Turner    ds = get_displaystate();
432594702b0dc4a9729b234c6f0265a9e43c72ef79adDavid 'Digit' Turner
43262507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    /* Initialize display from the command line parameters. */
43272507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    android_display_reset(ds,
43282507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner                          android_display_width,
43292507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner                          android_display_height,
43302507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner                          android_display_bpp);
4331dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
43325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_DEFAULT) {
43335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
43345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_SDL;
43355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
43365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_VNC;
43375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display = "localhost:0,to=99";
43385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        show_vnc_port = 1;
43395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
4341d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
43425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (display_type) {
43445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_NOGRAPHIC:
43455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
43465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_CURSES)
43475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_CURSES:
43485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        curses_display_init(ds, full_screen);
43495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
43505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4351eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
43525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
43535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sdl_display_init(ds, full_screen, no_frame);
43545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
43555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(CONFIG_COCOA)
43565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
43575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cocoa_display_init(ds, full_screen);
43585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
435972d83df9865cf8f5393a41fc3f6e283ab6aaa81bVladimir Chtchetkine#elif defined(CONFIG_STANDALONE_CORE)
436072d83df9865cf8f5393a41fc3f6e283ab6aaa81bVladimir Chtchetkine    case DT_SDL:
4361e95660aadc669784406d5f5a867988b8ecc2ed0dVladimir Chtchetkine        coredisplay_init(ds);
436272d83df9865cf8f5393a41fc3f6e283ab6aaa81bVladimir Chtchetkine        break;
43635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_VNC:
43655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display_init(ds);
43667746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        if (vnc_display_open(ds, vnc_display) < 0) {
43677746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine            PANIC("Unable to initialize VNC display");
43687746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        }
43695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (show_vnc_port) {
43715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
43725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
43745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
43755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
43765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_resize(ds);
43785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dcl = ds->listeners;
43805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
43815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->dpy_refresh != NULL) {
43825973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner            ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
43835973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner            qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
43845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
43865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
43895973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner        nographic_timer = qemu_new_timer_ms(rt_clock, nographic_update, NULL);
43905973c775c853e26f684de58ad28c267281aaffd6David 'Digit' Turner        qemu_mod_timer(nographic_timer, qemu_get_clock_ms(rt_clock));
43915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
439394702b0dc4a9729b234c6f0265a9e43c72ef79adDavid 'Digit' Turner    text_consoles_set_display(ds);
43945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_chr_initial_reset();
43955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device && monitor_hd)
43975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
43985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
44005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = serial_devices[i];
44015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
44025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
44035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
44045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
44085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
44095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
44105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
44115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
44125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
44165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
44175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (virtcon_hds[i] && devname) {
44185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
44195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
44205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
44247746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine        PANIC("qemu: could not open gdbserver on device '%s'",
44255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev);
44265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* call android-specific setup function */
44295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_setup();
44305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44315758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine#if !defined(CONFIG_STANDALONE_CORE)
44325758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine    // For the standalone emulator (UI+core in one executable) we need to
44335758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine    // set the window title here.
44345758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine    android_emulator_set_base_port(android_base_port);
44355758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine#endif
44365758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine
4437871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije    if (loadvm)
4438871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije        do_loadvm(cur_mon, loadvm);
4439871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije
44405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (incoming) {
44415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0; /* fixme how to deal with -daemonize */
44425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_start_incoming_migration(incoming);
44435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (autostart)
44465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_start();
44475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4448c1ac40a3f493bebe160a441faf36cc9b28b9f205David 'Digit' Turner    os_setup_post();
44495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44507746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#ifdef CONFIG_ANDROID
44517746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    // This will notify the UI that the core is successfuly initialized
44527746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine    android_core_init_completed();
44537746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine#endif  // CONFIG_ANDROID
44547746af04f1c7a44253ce49cf7cf1914757faaafeVladimir Chtchetkine
44555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    main_loop();
44565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    quit_timers();
44575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_cleanup();
44585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_teardown();
44595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
44605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4461eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
4462eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkinevoid
4463eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineandroid_emulation_teardown(void)
4464eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine{
4465eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine    android_charmap_done();
4466eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine}
4467