vl-android.c revision d06599430ac907d1a89bbfda4bf3621f909aac8e
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"
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block.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-qemud.h"
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "android/hw-kmsg.h"
56eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#include "android/charmap.h"
57074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#include "android/globals.h"
58b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine#include "android/utils/bufprint.h"
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "targphys.h"
60318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine#include "tcpdump.h"
615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
63b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#include "memcheck/memcheck.h"
64b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
65b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <unistd.h>
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <fcntl.h>
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <signal.h>
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <time.h>
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <errno.h>
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/time.h>
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <zlib.h>
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
742c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner/* Needed early for CONFIG_BSD etc. */
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config-host.h"
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libgen.h>
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <pwd.h>
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/times.h>
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/wait.h>
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <termios.h>
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/mman.h>
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ioctl.h>
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/resource.h>
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/socket.h>
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__NetBSD__)
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if_tap.h>
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/if_tun.h>
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <arpa/inet.h>
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <dirent.h>
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netdb.h>
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/select.h>
992c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_BSD
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__FreeBSD__) || defined(__DragonFly__)
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libutil.h>
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <freebsd/stdlib.h>
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <pty.h>
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/rtc.h>
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* For the benefit of older linux systems which don't supply it,
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   we use a local copy of hpet.h. */
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #include <linux/hpet.h> */
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hpet.h"
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/ppdev.h>
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/parport.h>
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __sun__
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ethernet.h>
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/sockio.h>
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/arp.h>
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in_systm.h>
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip.h>
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip_icmp.h> // must come after ip.h
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/udp.h>
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/tcp.h>
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <syslog.h>
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <stropts.h>
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__OpenBSD__)
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_VDE)
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libvdeplug.h>
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <windows.h>
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/timeb.h>
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <mmsystem.h>
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define getopt_long_only getopt_long
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define memalign(align, size) malloc(size)
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_COCOA
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_COCOA */
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/hw.h"
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/boards.h"
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/usb.h"
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pcmcia.h"
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pc.h"
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/audiodev.h"
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/isa.h"
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/baum.h"
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/bt.h"
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/watchdog.h"
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/smbios.h"
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/xen.h"
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "bt-host.h"
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "net.h"
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "console.h"
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "sysemu.h"
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "gdbstub.h"
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-timer.h"
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-char.h"
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "cache-utils.h"
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block.h"
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "dma.h"
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio/audio.h"
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "migration.h"
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "kvm.h"
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "balloon.h"
190b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine#include "android/hw-lcd.h"
191b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine#include "android/boot-properties.h"
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
193eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
194eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine/* Verbose value used by the standalone emulator core (without UI) */
195eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineunsigned long   android_verbose;
196eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
197eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
19843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "disas.h"
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "exec-all.h"
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "trace.h"
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "dcache.h"
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu_socket.h"
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "libslirp.h"
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_UNUSED_IOPORT
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_IOPORT
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_NET
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_SLIRP
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_IOPORT
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  define LOG_IOPORT(...) do { } while (0)
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFAULT_RAM_SIZE 128
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of USB devices that can be specified on the commandline.  */
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_USB_CMDLINE 8
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of bluetooth switches on the commandline.  */
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_BT_CMDLINE 10
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: use a two level table to limit memory usage */
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const char *data_dir;
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *bios_name = NULL;
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *ioport_opaque[MAX_IOPORTS];
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   to store the VM snapshots */
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDriveInfo drives_table[MAX_DRIVES+1];
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives;
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic DisplayState *display_state;
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayType display_type = DT_DEFAULT;
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char* keyboard_layout = NULL;
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t ticks_per_sec;
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t ram_size;
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_nics;
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerNICInfo nd_table[MAX_NICS];
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vm_running;
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int autostart;
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_utc = 1;
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_date_offset = -1; /* -1 means no change */
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cirrus_vga_enabled = 1;
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint std_vga_enabled = 0;
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vmsvga_enabled = 0;
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint xenfb_enabled = 0;
265a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' TurnerQEMUClock *rtc_clock;
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_SPARC
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_width = 1024;
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_height = 768;
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_depth = 8;
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_width = 800;
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_height = 600;
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_depth = 15;
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int full_screen = 0;
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int no_frame = 0;
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_quit = 0;
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *serial_hds[MAX_SERIAL_PORTS];
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint win2k_install_hack = 0;
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint rtc_td_hack = 0;
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_enabled = 0;
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint singlestep = 0;
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint smp_cpus = 1;
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *vnc_display;
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint acpi_enabled = 1;
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_hpet = 0;
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_virtio_balloon = 0;
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint fd_bootchk = 1;
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_reboot = 0;
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_shutdown = 0;
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cursor_hide = 1;
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_rotate = 0;
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint daemonize = 0;
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerWatchdogTimerModel *watchdog = NULL;
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint watchdog_action = WDT_RESET;
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *option_rom[MAX_OPTION_ROMS];
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_option_roms;
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint semihosting_enabled = 0;
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint old_param = 0;
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *qemu_name;
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint alt_grab = 0;
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned int nb_prom_envs = 0;
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *prom_envs[MAX_PROM_ENVS];
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives_opt;
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct drive_opt drives_opt[MAX_DRIVES];
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_numa_nodes;
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_mem[MAX_NODES];
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_cpumask[MAX_NODES];
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic CPUState *cur_cpu;
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic CPUState *next_cpu;
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int timer_alarm_pending = 1;
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUTimer *nographic_timer;
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint8_t qemu_uuid[16];
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
331b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkineint   qemu_cpu_delay;
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern char* audio_input_source;
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
334d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_ports;
335d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_port;
336d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_report_console;
337d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* op_http_proxy;
33843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine// Path to the file containing specific key character map.
33943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkinechar* op_charmap_file = NULL;
340d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
341dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine/* Framebuffer dimensions, passed with -android-gui option. */
342dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinechar* android_op_gui = NULL;
343dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
344074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine/* Path to hardware initialization file passed with -android-hw option. */
345074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkinechar* android_op_hwini = NULL;
346074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
347b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine/* Memory checker options. */
348b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkinechar* android_op_memcheck = NULL;
349b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
3507fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine/* -dns-server option value. */
3517fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinechar* android_op_dns_server = NULL;
3527fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
35313f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine/* -radio option value. */
354b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_radio = NULL;
355b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
356b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -gps option value. */
357b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_gps = NULL;
358b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
359b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio option value. */
360b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio = NULL;
361b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
362b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio-in option value. */
363b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio_in = NULL;
364b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
365b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio-out option value. */
366b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio_out = NULL;
367b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
368b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -cpu-delay option value. */
369b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_cpu_delay = NULL;
370b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
371e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
372e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -nand-limits option value. */
373e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_nand_limits = NULL;
374e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
375e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
376e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netspeed option value. */
377e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_netspeed = NULL;
378e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
379e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netdelay option value. */
380e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkinechar* android_op_netdelay = NULL;
381e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
382e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine/* -netfast option value. */
383e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkineint android_op_netfast = 0;
384e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
385318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine/* -tcpdump option value. */
386318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkinechar* android_op_tcpdump = NULL;
387318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
388b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine/* -lcd-density option value. */
389b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkinechar* android_op_lcd_density = NULL;
390b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
391dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_width;
392dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_height;
393dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_bpp;
394dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern void  dprint( const char* format, ... );
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* x86 ISA bus support */
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertarget_phys_addr_t isa_mem_base = 0;
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerPicState2 *isa_pic;
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t ioport_read(int index, uint32_t address)
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortReadFunc *default_func[3] = {
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readb,
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readw,
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readl
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortReadFunc *func = ioport_read_table[index][address];
4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return func(ioport_opaque[address], address);
4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void ioport_write(int index, uint32_t address, uint32_t data)
4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortWriteFunc *default_func[3] = {
4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writeb,
4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writew,
4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writel
4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortWriteFunc *func = ioport_write_table[index][address];
4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    func(ioport_opaque[address], address, data);
4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readb(void *opaque, uint32_t address)
4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inb: port=0x%04x\n", address);
4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xff;
4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* default is to make two byte accesses */
4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readw(void *opaque, uint32_t address)
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t data;
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data = ioport_read(0, address);
4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data |= ioport_read(0, address) << 8;
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return data;
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, data & 0xff);
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, (data >> 8) & 0xff);
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readl(void *opaque, uint32_t address)
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inl: port=0x%04x\n", address);
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xffffffff;
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
481dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine/* Parses -android-gui command line option, extracting width, height and bits
482dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * per pixel parameters for the GUI console used in this session of the
483dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * emulator. -android-gui option contains exactly three comma-separated positive
484dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * integer numbers in strict order: width goes first, width goes next, and bits
485dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * per pixel goes third. This routine verifies that format and return 0 if all
486dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * three numbers were extracted, or -1 if string format was incorrect for that
487dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * option. Note that this routine does not verify that extracted values are
488dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * correct!
489dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine */
490dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinestatic int
491dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineparse_androig_gui_option(const char* op, int* width, int* height, int* bpp)
492dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine{
493dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    char val[128];
494dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
495dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "width", op)) {
496dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *width = strtol(val, NULL, 0);
497dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
498dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing width parameter\n");
499dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
500dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
501dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "height", op)) {
502dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *height = strtol(val, NULL, 0);
503dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
504dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing height parameter\n");
505dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
506dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
507dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "bpp", op)) {
508dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *bpp = strtol(val, NULL, 0);
509dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
510dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing bpp parameter\n");
511dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
512dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
513dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
514dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    return 0;
515dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine}
516dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid hw_error(const char *fmt, ...)
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_list ap;
5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_start(ap, fmt);
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: hardware error: ");
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vfprintf(stderr, fmt, ap);
5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "\n");
5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(env = first_cpu; env != NULL; env = env->next_cpu) {
5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_dump_state(env, stderr, fprintf, 0);
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_end(ap);
5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    abort();
5375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
538d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
539a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerstatic void set_proc_name(const char *s)
540a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner{
541a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#if defined(__linux__) && defined(PR_SET_NAME)
542a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    char name[16];
543a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!s)
544a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return;
545a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    name[sizeof(name) - 1] = 0;
546a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    strncpy(name, s, sizeof(name));
547a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    /* Could rewrite argv[0] too, but that's a bit more complicated.
548a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner       This simple way is enough for `top'. */
549a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    prctl(PR_SET_NAME, name);
550d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine#endif
551a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner}
552d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***************/
5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ballooning */
5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUBalloonEvent *qemu_balloon_event;
5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid *qemu_balloon_event_opaque;
5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event = func;
5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event_opaque = opaque;
5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_balloon(ram_addr_t target)
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_balloon_event(qemu_balloon_event_opaque, target);
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t qemu_balloon_status(void)
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_balloon_event(qemu_balloon_event_opaque, 0);
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* keyboard/mouse */
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutKBDEvent*  qemu_put_kbd_event;
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void*             qemu_put_kbd_event_opaque;
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutMouseEntry *qemu_put_mouse_event_head;
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutMouseEntry *qemu_put_mouse_event_current;
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_kbd_event_opaque = opaque;
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_kbd_event = func;
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_opaque = opaque;
5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event = func;
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_absolute = absolute;
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                void *opaque, int absolute,
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                const char *name)
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *s, *cursor;
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!s)
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event = func;
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_opaque = opaque;
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_absolute = absolute;
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_name = qemu_strdup(name);
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->next = NULL;
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return s;
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor->next != NULL)
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor->next = s;
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_current = s;
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return s;
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *prev = NULL, *cursor;
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head || entry == NULL)
6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL && cursor != entry) {
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        prev = cursor;
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cursor == NULL) // does not exist or list empty
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (prev == NULL) { // entry is head
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_head = cursor->next;
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_put_mouse_event_current == entry)
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_put_mouse_event_current = cursor->next;
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(entry->qemu_put_mouse_event_name);
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(entry);
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    prev->next = entry->next;
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_put_mouse_event_current == entry)
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current = prev;
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(entry->qemu_put_mouse_event_name);
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(entry);
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid kbd_put_keycode(int keycode)
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_put_kbd_event) {
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEvent *mouse_event;
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *mouse_event_opaque;
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int width;
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_current) {
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    mouse_event =
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current->qemu_put_mouse_event;
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    mouse_event_opaque =
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (mouse_event) {
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (graphic_rotate) {
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                width = 0x7fff;
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                width = graphic_width - 1;
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            mouse_event(mouse_event_opaque,
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 width - dy, dx, dz, buttons_state);
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            mouse_event(mouse_event_opaque,
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 dx, dy, dz, buttons_state);
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint kbd_mouse_is_absolute(void)
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_current)
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_info_mice(Monitor *mon)
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *cursor;
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index = 0;
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No mouse devices connected\n");
7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_printf(mon, "Mouse devices available:\n");
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL) {
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "%c Mouse #%d: %s\n",
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       (cursor == qemu_put_mouse_event_current ? '*' : ' '),
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       index, cursor->qemu_put_mouse_event_name);
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index++;
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_mouse_set(Monitor *mon, int index)
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *cursor;
7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i = 0;
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No mouse devices connected\n");
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL && index != i) {
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i++;
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cursor != NULL)
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current = cursor;
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "Mouse at given index not found\n");
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* compute with 96 bit intermediate result: (a*b)/c */
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    union {
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t ll;
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct {
75920894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#ifdef HOST_WORDS_BIGENDIAN
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint32_t high, low;
7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint32_t low, high;
7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } l;
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } u, res;
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t rl, rh;
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    u.ll = a;
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rl = (uint64_t)u.l.low * (uint64_t)b;
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rh = (uint64_t)u.l.high * (uint64_t)b;
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rh += (rl >> 32);
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res.l.high = rh / c;
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return res.ll;
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* host time/date access */
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_get_timedate(struct tm *tm, int offset)
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t ti;
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct tm *ret;
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time(&ti);
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ti += offset;
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1) {
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = gmtime(&ti);
7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = localtime(&ti);
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ti -= rtc_date_offset;
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = gmtime(&ti);
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memcpy(tm, ret, sizeof(struct tm));
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_timedate_diff(struct tm *tm)
8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t seconds;
8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1)
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktimegm(tm);
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktime(tm);
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        seconds = mktimegm(tm) + rtc_date_offset;
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return seconds - time(NULL);
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tbflush_requested;
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int exit_requested;
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid start_tracing()
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!tracing) {
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- start tracing --\n");
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_time = Now();
8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 1;
8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid stop_tracing()
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (tracing) {
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    end_time = Now();
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    elapsed_usecs += end_time - start_time;
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- stop tracing --\n");
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 0;
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * SIGUSR1 turns tracing on.  SIGUSR2 turns tracing off.
8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigusr_handler(int sig)
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (sig == SIGUSR1)
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_tracing();
8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  else
8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stop_tracing();
8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler to catch control-C so that we can exit cleanly.
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This is needed when tracing to flush the buffers to disk.
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigint_handler(int sig)
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  exit_requested = 1;
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_TRACE */
8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Bluetooth support */
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int nb_hcis;
8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cur_hci;
8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_table[MAX_NICS];
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_vlan_s {
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s net;
8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int id;
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s *next;
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *first_bt_vlan;
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* find or alloc a new bluetooth "VLAN" */
8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_scatternet_s *qemu_find_bt_vlan(int id)
8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s **pvlan, *vlan;
8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan->id == id)
8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return &vlan->net;
8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan->id = id;
8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pvlan = &first_bt_vlan;
8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pvlan != NULL)
8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pvlan = &(*pvlan)->next;
8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pvlan = vlan;
8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return &vlan->net;
8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -ENOTSUP;
9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo null_hci = {
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .cmd_send = null_hci_send,
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .sco_send = null_hci_send,
9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .acl_send = null_hci_send,
9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdaddr_set = null_hci_addr_set,
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct HCIInfo *qemu_next_hci(void)
9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cur_hci == nb_hcis)
9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return hci_table[cur_hci++];
9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_init(const char *str)
9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp;
9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = 0;
9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(str, "null"))
9295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* null */
9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* host[:hciN] */
9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_host_hci(str[4] ? str + 5 : "hci0");
9345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "hci", 3)) {
9355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* hci[,vlan=n] */
9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (str[3]) {
9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!strncmp(str + 3, ",vlan=", 6)) {
9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endp)
9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = 0;
9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vlan = qemu_find_bt_vlan(0);
9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan)
9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return bt_new_hci(vlan);
9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_hci_parse(const char *str)
9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct HCIInfo *hci;
9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr_t bdaddr;
9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_hcis >= MAX_NICS) {
9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci = hci_init(str);
9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!hci)
9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[0] = 0x52;
9685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[1] = 0x54;
9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[2] = 0x00;
9705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[3] = 0x12;
9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[4] = 0x34;
9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[5] = 0x56 + nb_hcis;
9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci->bdaddr_set(hci, bdaddr.b);
9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci_table[nb_hcis++] = hci;
9765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
9785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bt_vhci_add(int vlan_id)
9815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
9835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a VHCI to "
9865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
9875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bt_vhci_init(bt_new_hci(vlan));
9895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_device_s *bt_device_add(const char *opt)
9925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan;
9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan_id = 0;
9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp = strstr(opt, ",vlan=");
9965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int len = (endp ? endp - opt : strlen(opt)) + 1;
9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[10];
9985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pstrcpy(devname, MIN(sizeof(devname), len), opt);
10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (endp) {
10025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vlan_id = strtol(endp + 6, &endp, 0);
10035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (*endp) {
10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
10055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
10065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_find_bt_vlan(vlan_id);
10105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a slave device to "
10135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
10145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(devname, "keyboard"))
10165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_keyboard_init(vlan);
10175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
10195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
10205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_parse(const char *opt)
10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *endp, *p;
10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan;
10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(opt, "hci", &endp)) {
10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp)
10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strstart(endp, ",vlan=", 0))
10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    opt = endp + 1;
10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return bt_hci_parse(opt);
10345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
10355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "vhci", &endp)) {
10365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
10375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp) {
10385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strstart(endp, ",vlan=", &p)) {
10395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = strtol(p, (char **) &endp, 0);
10405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*endp) {
10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        return 1;
10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
10465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    return 1;
10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = 0;
10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bt_vhci_add(vlan);
10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "device:", &endp))
10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return !bt_device_add(endp);
10565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
10585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* QEMU Block devices */
10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HD_ALIAS "index=%d,media=disk"
10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define CDROM_ALIAS "index=2,media=cdrom"
10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define FD_ALIAS "index=%d,if=floppy"
10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define PFLASH_ALIAS "if=pflash"
10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MTD_ALIAS "if=mtd"
10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define SD_ALIAS "index=0,if=sd"
10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_opt_get_free_idx(void)
10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_opt[index].used) {
10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_opt[index].used = 1;
10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_get_free_idx(void)
10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_table[index].used) {
10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[index].used = 1;
10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10977ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehatint drive_add(const char *file, const char *fmt, ...)
10987ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat{
10997ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_list ap;
11007ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    int index = drive_opt_get_free_idx();
11017ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat
11027ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    if (nb_drives_opt >= MAX_DRIVES || index == -1) {
11037ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        fprintf(stderr, "qemu: too many drives\n");
11047ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        return -1;
11057ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    }
11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11077ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    drives_opt[index].file = file;
11087ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_start(ap, fmt);
11097ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    vsnprintf(drives_opt[index].opt,
11107ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat              sizeof(drives_opt[0].opt), fmt, ap);
11117ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_end(ap);
111292568958dd42bf35667cc6451b5edd7f7d1f73a1David 'Digit' Turner
11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt++;
11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return index;
11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_remove(int index)
11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_opt[index].used = 0;
11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt--;
11215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_index(BlockInterfaceType type, int bus, int unit)
11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek interface, bus and unit */
11285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
11305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].type == type &&
11315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].bus == bus &&
11325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].unit == unit &&
11335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].used)
11345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return index;
11355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
11375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_max_bus(BlockInterfaceType type)
11405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_bus;
11425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
11435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_bus = -1;
11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++) {
11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if(drives_table[index].type == type &&
11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           drives_table[index].bus > max_bus)
11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_bus = drives_table[index].bus;
11495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return max_bus;
11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *drive_get_serial(BlockDriverState *bdrv)
11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
11595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].serial;
11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return "\0";
11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].onerror;
11715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return BLOCK_ERR_STOP_ENOSPC;
11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bdrv_format_print(void *opaque, const char *name)
11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, " %s", name);
11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_uninit(BlockDriverState *bdrv)
11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
11835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_DRIVES; i++)
11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[i].bdrv == bdrv) {
11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].bdrv = NULL;
11875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].used = 0;
11885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drive_remove(drives_table[i].drive_opt_idx);
11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_drives--;
11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_init(struct drive_opt *arg, int snapshot, void *opaque)
11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[128];
11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char file[1024];
11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[128];
11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char serial[21];
12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *mediastr = "";
12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockInterfaceType type;
12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    enum { MEDIA_DISK, MEDIA_CDROM } media;
12035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_id, unit_id;
12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
12055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriverState *bdrv;
12065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriver *drv = NULL;
12075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine = opaque;
12085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_devs;
12095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
12105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cache;
12115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bdrv_flags, onerror;
12125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int drives_table_idx;
12135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *str = arg->opt;
12145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static const char * const params[] = { "bus", "unit", "if", "index",
12155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cyls", "heads", "secs", "trans",
12165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "media", "snapshot", "file",
12175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cache", "format", "serial", "werror",
12185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           NULL };
12195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (check_params(buf, sizeof(buf), params, str) < 0) {
12215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
12225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         buf, str);
12235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         return -1;
12245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    file[0] = 0;
12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
12285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_id = 0;
12295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unit_id = -1;
12305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
12315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    index = -1;
12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cache = 3;
12335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (machine->use_scsi) {
12355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_SCSI;
12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_SCSI_DEVS;
12375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "scsi");
12385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_IDE;
12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_IDE_DEVS;
12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "ide");
12425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    media = MEDIA_DISK;
12445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* extract parameters */
12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "bus", str)) {
12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bus_id = strtol(buf, NULL, 0);
12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (bus_id < 0) {
12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "unit", str)) {
12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        unit_id = strtol(buf, NULL, 0);
12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (unit_id < 0) {
12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "if", str)) {
12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), buf);
12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ide")) {
12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_IDE;
12675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_IDE_DEVS;
12685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "scsi")) {
12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SCSI;
12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_SCSI_DEVS;
12715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "floppy")) {
12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_FLOPPY;
12735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "pflash")) {
12755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_PFLASH;
12765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "mtd")) {
12785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_MTD;
12795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "sd")) {
12815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SD;
12825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "virtio")) {
12845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            type = IF_VIRTIO;
12855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "xen")) {
12875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_XEN;
12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
12905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
12925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
12935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "index", str)) {
12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index = strtol(buf, NULL, 0);
12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (index < 0) {
12985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid index\n", str);
12995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cyls", str)) {
13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cyls = strtol(buf, NULL, 0);
13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "heads", str)) {
13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        heads = strtol(buf, NULL, 0);
13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "secs", str)) {
13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        secs = strtol(buf, NULL, 0);
13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cyls || heads || secs) {
13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cyls < 1 || cyls > 16383) {
13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (heads < 1 || heads > 16) {
13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (secs < 1 || secs > 63) {
13255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
13265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "trans", str)) {
13315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cyls) {
13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' trans must be used with cyls,heads and secs\n",
13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    str);
13355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "none"))
13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_NONE;
13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "lba"))
13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_LBA;
13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "auto"))
13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_AUTO;
13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
13445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
13455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "media", str)) {
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "disk")) {
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_DISK;
13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "cdrom")) {
13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls || secs || heads) {
13545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr,
13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "qemu: '%s' invalid physical CHS format\n", str);
13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        return -1;
13575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
13585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_CDROM;
13595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
13605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid media\n", str);
13615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "on"))
13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 1;
13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "off"))
13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 0;
13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
13725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
13745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cache", str)) {
13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "off") || !strcmp(buf, "none"))
13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 0;
13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writethrough"))
13805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 1;
13815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writeback"))
13825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 2;
13835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
13845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           fprintf(stderr, "qemu: invalid cache option\n");
13855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return -1;
13865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "format", str)) {
13905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strcmp(buf, "?") == 0) {
13915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: Supported formats:");
13925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_iterate_format(bdrv_format_print, NULL);
13935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "\n");
13945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
13955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drv = bdrv_find_format(buf);
13975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drv) {
13985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid format\n", buf);
13995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
14005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arg->file == NULL)
14045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        get_param_value(file, sizeof(file), "file", str);
14055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
14065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(file, sizeof(file), arg->file);
14075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!get_param_value(serial, sizeof(serial), "serial", str))
14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    memset(serial, 0,  sizeof(serial));
14105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    onerror = BLOCK_ERR_STOP_ENOSPC;
14125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(serial), "werror", str)) {
14135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
14145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "werror is no supported by this format\n");
14155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
14165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ignore"))
14185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_IGNORE;
14195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "enospc"))
14205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ENOSPC;
14215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "stop"))
14225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ANY;
14235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "report"))
14245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_REPORT;
14255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
14265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
14275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
14285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compute bus and unit according index */
14325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (index != -1) {
14345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bus_id != 0 || unit_id != -1) {
14355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
14365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' index cannot be used with bus and unit\n", str);
14375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
14385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (max_devs == 0)
14405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
14415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index;
14425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = 0;
14435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
14445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index % max_devs;
14455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = index / max_devs;
14465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* if user doesn't specify a unit_id,
14505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * try to find the first free
14515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
14525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unit_id == -1) {
14545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       unit_id = 0;
14555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       while (drive_get_index(type, bus_id, unit_id) != -1) {
14565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           unit_id++;
14575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           if (max_devs && unit_id >= max_devs) {
14585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               unit_id -= max_devs;
14595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               bus_id++;
14605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           }
14615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
14625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* check unit id */
14655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs && unit_id >= max_devs) {
14675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
14685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        str, unit_id, max_devs - 1);
14695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
14705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /*
14735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * ignore multiple definitions
14745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
14755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (drive_get_index(type, bus_id, unit_id) != -1)
14775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
14785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init */
14805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (type == IF_IDE || type == IF_SCSI)
14825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
14835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs)
14845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%i%s%i",
14855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, bus_id, mediastr, unit_id);
14865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
14875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%s%i",
14885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, mediastr, unit_id);
14895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv = bdrv_new(buf);
14905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table_idx = drive_get_free_idx();
14915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bdrv = bdrv;
14925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].type = type;
14935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bus = bus_id;
14945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].unit = unit_id;
14955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].onerror = onerror;
14965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
14975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
14985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives++;
14995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(type) {
15015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_IDE:
15025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SCSI:
15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_XEN:
15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(media) {
15055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_DISK:
15065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls != 0) {
15075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
15085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_translation_hint(bdrv, translation);
15095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
15105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
15115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_CDROM:
15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
15135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
15145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
15155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
15165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SD:
15175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FIXME: This isn't really a floppy, but it's a reasonable
15185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           approximation.  */
15195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_FLOPPY:
15205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
15215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
15225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_PFLASH:
15235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_MTD:
15245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_VIRTIO:
15255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
15265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_COUNT:
15275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
15285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!file[0])
15305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
15315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_flags = 0;
15325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (snapshot) {
15335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_SNAPSHOT;
15345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cache = 2; /* always use write-back with snapshot */
15355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cache == 0) /* no caching */
15375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_NOCACHE;
15385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 2) /* write-back */
15395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_WB;
15405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 3) /* not specified */
15415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_DEF;
15425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
15435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: could not open disk image %s\n",
15445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        file);
15455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_key_required(bdrv))
15485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0;
15495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return drives_table_idx;
15505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void numa_add(const char *optarg)
15535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char option[128];
15555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endptr;
15565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned long long value, endvalue;
15575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nodenr;
15585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optarg = get_opt_name(option, 128, optarg, ',') + 1;
15605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(option, "node")) {
15615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "nodeid", optarg) == 0) {
15625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = nb_numa_nodes;
15635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
15645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = strtoull(option, NULL, 10);
15655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "mem", optarg) == 0) {
15685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = 0;
15695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
15705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 0);
15715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch (*endptr) {
15725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 0: case 'M': case 'm':
15735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 20;
15745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
15755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 'G': case 'g':
15765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 30;
15775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
15785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
15795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = value;
15805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "cpus", optarg) == 0) {
15825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = 0;
15835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
15845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 10);
15855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (value >= 64) {
15865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = 63;
15875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
15885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
15895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endptr == '-') {
15905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    endvalue = strtoull(endptr+1, &endptr, 10);
15915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (endvalue >= 63) {
15925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        endvalue = 62;
15935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr,
15945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            "only 63 CPUs in NUMA mode supported.\n");
15955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
15965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = (1 << (endvalue + 1)) - (1 << value);
15975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
15985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = 1 << value;
15995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
16005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
16015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = value;
16025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_numa_nodes++;
16045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
16065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
16095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* USB devices */
16105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *used_usb_ports;
16125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *free_usb_ports;
16135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ??? Maybe change this to register a hub to keep track of the topology.  */
16155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_usb_port(USBPort *port, void *opaque, int index,
16165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            usb_attachfn attach)
16175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->opaque = opaque;
16195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->index = index;
16205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->attach = attach;
16215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
16225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
16235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_add_dev(USBDevice *dev)
16265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
16285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Find a USB port to add the device to.  */
16305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = free_usb_ports;
16315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port->next) {
16325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        USBDevice *hub;
16335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Create a new hub and chain it on.  */
16355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        free_usb_ports = NULL;
16365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port->next = used_usb_ports;
16375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        used_usb_ports = port;
16385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hub = usb_hub_init(VM_USB_HUB_SIZE);
16405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_attach(port, hub);
16415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = free_usb_ports;
16425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port->next;
16455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = used_usb_ports;
16465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    used_usb_ports = port;
16475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, dev);
16485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
16495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16513266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#if 0
16525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void usb_msd_password_cb(void *opaque, int err)
16535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev = opaque;
16555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!err)
16575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_device_add_dev(dev);
16585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
16595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev->handle_destroy(dev);
16605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16613266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#endif
16625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_add(const char *devname, int is_hotplug)
16645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
16665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
16675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!free_usb_ports)
16695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
16705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p)) {
16725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_host_device_open(p);
16735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "mouse")) {
16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_mouse_init();
16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "tablet")) {
16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_tablet_init();
16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "keyboard")) {
16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_keyboard_init();
16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "disk:", &p)) {
16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        BlockDriverState *bs;
16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
16835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_msd_init(p);
16845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
16855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
16875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bs = usb_msd_get_bdrv(dev);
16885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bdrv_key_required(bs)) {
16895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            autostart = 0;
16905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (is_hotplug) {
16915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
16925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            dev);
16935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
16945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
16955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "wacom-tablet")) {
16975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_wacom_init();
16985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "serial:", &p)) {
16995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_serial_init(p);
17005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_BRLAPI
17015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "braille")) {
17025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_baum_init();
17035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
17045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "net:", &p)) {
17055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int nic = nb_nics;
17065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (net_client_init("nic", p) < 0)
17085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
17095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nd_table[nic].model = "usb";
17105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_net_init(&nd_table[nic]);
17115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
17125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_bt_init(devname[2] ? hci_init(p) :
17135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        bt_new_hci(qemu_find_bt_vlan(0)));
17145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
17155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
17165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!dev)
17195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_add_dev(dev);
17225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_del_addr(int bus_num, int addr)
17255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
17275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort **lastp;
17285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
17295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
17315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bus_num != 0)
17345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    lastp = &used_usb_ports;
17375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = used_usb_ports;
17385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (port && port->dev->addr != addr) {
17395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        lastp = &port->next;
17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = port->next;
17415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port)
17445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev = port->dev;
17475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *lastp = port->next;
17485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, NULL);
17495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev->handle_destroy(dev);
17505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
17515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
17525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
17535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_del(const char *devname)
17565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_num, addr;
17585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
17595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p))
17615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return usb_host_device_close(p);
17625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
17645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = strchr(devname, '.');
17675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p)
17685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_num = strtoul(devname, NULL, 0);
17705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    addr = strtoul(p + 1, NULL, 0);
17715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_del_addr(bus_num, addr);
17735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_add(Monitor *mon, const char *devname)
17765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_add(devname, 1);
17785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_del(Monitor *mon, const char *devname)
17815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_del(devname);
17835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid usb_info(Monitor *mon)
17865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
17885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
17895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *speed_str;
17905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!usb_enabled) {
17925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "USB support not enabled\n");
17935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
17945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (port = used_usb_ports; port; port = port->next) {
17975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = port->dev;
17985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
17995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
18005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(dev->speed) {
18015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_LOW:
18025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "1.5";
18035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_FULL:
18055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "12";
18065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_HIGH:
18085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "480";
18095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
18115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "?";
18125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
18145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "  Device %d.%d, Speed %s Mb/s, Product %s\n",
18155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       0, dev->addr, speed_str, dev->devname);
18165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
18205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* PCMCIA/Cardbus */
18215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct pcmcia_socket_entry_s {
18235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PCMCIASocket *socket;
18245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *next;
18255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *pcmcia_sockets = 0;
18265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_register(PCMCIASocket *socket)
18285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry;
18305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
18325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->socket = socket;
18335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->next = pcmcia_sockets;
18345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pcmcia_sockets = entry;
18355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_unregister(PCMCIASocket *socket)
18385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry, **ptr;
18405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ptr = &pcmcia_sockets;
18425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
18435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (entry->socket == socket) {
18445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *ptr = entry->next;
18455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(entry);
18465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
18475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_info(Monitor *mon)
18505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *iter;
18525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!pcmcia_sockets)
18545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No PCMCIA sockets\n");
18555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (iter = pcmcia_sockets; iter; iter = iter->next)
18575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
18585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       iter->socket->attached ? iter->socket->card_string :
18595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       "Empty");
18605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
18635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* register display */
18645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct DisplayAllocator default_allocator = {
18665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_create_displaysurface,
18675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_resize_displaysurface,
18685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_free_displaysurface
18695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
18705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid register_displaystate(DisplayState *ds)
18725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState **s;
18745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = &display_state;
18755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*s != NULL)
18765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s = &(*s)->next;
18775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->next = NULL;
18785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *s = ds;
18795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayState *get_displaystate(void)
18825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return display_state;
18845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
18875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(ds->allocator ==  &default_allocator) ds->allocator = da;
18895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ds->allocator;
18905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* dumb display */
18935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dumb_display_init(void)
18955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
18975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->allocator = &default_allocator;
18985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->surface = qemu_create_displaysurface(ds, 640, 480);
18995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_displaystate(ds);
19005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1902dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinestatic void
1903dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineandroid_display_init_from(int width, int height, int rotation, int bpp)
1904dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine{
1905dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
1906dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    ds->allocator = &default_allocator;
1907dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    ds->surface = qemu_create_displaysurface(ds, width, height);
1908dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    register_displaystate(ds);
1909dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine}
1910dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
19115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
19125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* I/O handling */
19135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct IOHandlerRecord {
19155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd;
19165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOCanRWHandler *fd_read_poll;
19175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandler *fd_read;
19185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandler *fd_write;
19195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int deleted;
19205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
19215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* temporary data */
19225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pollfd *ufd;
19235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct IOHandlerRecord *next;
19245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} IOHandlerRecord;
19255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOHandlerRecord *first_io_handler;
19275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: fd_read_poll should be suppressed, but an API change is
19295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   necessary in the character devices to suppress fd_can_read(). */
19305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_set_fd_handler2(int fd,
19315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOCanRWHandler *fd_read_poll,
19325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOHandler *fd_read,
19335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOHandler *fd_write,
19345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         void *opaque)
19355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandlerRecord **pioh, *ioh;
19375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!fd_read && !fd_write) {
19395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pioh = &first_io_handler;
19405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(;;) {
19415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ioh = *pioh;
19425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh == NULL)
19435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd == fd) {
19455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->deleted = 1;
19465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pioh = &ioh->next;
19495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
19505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
19515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
19525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd == fd)
19535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto found;
19545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
19555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
19565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->next = first_io_handler;
19575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        first_io_handler = ioh;
19585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    found:
19595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd = fd;
19605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_read_poll = fd_read_poll;
19615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_read = fd_read;
19625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_write = fd_write;
19635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->opaque = opaque;
19645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->deleted = 0;
19655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
19675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_set_fd_handler(int fd,
19705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        IOHandler *fd_read,
19715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        IOHandler *fd_write,
19725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        void *opaque)
19735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
19755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
19785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
19795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Polling handling */
19805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct PollingEntry {
19825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingFunc *func;
19835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
19845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct PollingEntry *next;
19855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} PollingEntry;
19865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic PollingEntry *first_polling_entry;
19885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_add_polling_cb(PollingFunc *func, void *opaque)
19905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry **ppe, *pe;
19925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe = qemu_mallocz(sizeof(PollingEntry));
19935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe->func = func;
19945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe->opaque = opaque;
19955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
19965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *ppe = pe;
19975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
19985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_polling_cb(PollingFunc *func, void *opaque)
20015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry **ppe, *pe;
20035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
20045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pe = *ppe;
20055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (pe->func == func && pe->opaque == opaque) {
20065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *ppe = pe->next;
20075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(pe);
20085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
20095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
20145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Wait objects support */
20155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct WaitObjects {
20165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int num;
20175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
20185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
20195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
20205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} WaitObjects;
20215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic WaitObjects wait_objects = {0};
20235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
20255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjects *w = &wait_objects;
20275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (w->num >= MAXIMUM_WAIT_OBJECTS)
20295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
20305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->events[w->num] = handle;
20315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->func[w->num] = func;
20325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->opaque[w->num] = opaque;
20335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->num++;
20345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
20355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
20385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i, found;
20405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjects *w = &wait_objects;
20415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    found = 0;
20435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < w->num; i++) {
20445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (w->events[i] == handle)
20455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            found = 1;
20465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (found) {
20475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->events[i] = w->events[i + 1];
20485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->func[i] = w->func[i + 1];
20495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->opaque[i] = w->opaque[i + 1];
20505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (found)
20535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        w->num--;
20545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
20565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
20585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ram save/restore */
20595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
20615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int v;
20635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    v = qemu_get_byte(f);
20655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(v) {
20665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 0:
20675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_get_buffer(f, buf, len) != len)
20685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EIO;
20695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
20705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 1:
20715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        v = qemu_get_byte(f);
20725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(buf, v, len);
20735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
20745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
20755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
20765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_file_has_error(f))
20795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EIO;
20805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
20825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load_v1(QEMUFile *f, void *opaque)
20855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
20875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t i;
20885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_get_be32(f) != last_ram_offset)
20905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
20915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
20925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
20935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret)
20945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return ret;
20955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
20975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define BDRV_HASH_BLOCK_SIZE 1024
21005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define IOBUF_SIZE 4096
21015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_CBLOCK_MAGIC 0xfabe
21025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct RamDecompressState {
21045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    z_stream zstream;
21055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUFile *f;
21065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t buf[IOBUF_SIZE];
21075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} RamDecompressState;
21085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
21105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
21125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(s, 0, sizeof(*s));
21135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->f = f;
21145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = inflateInit(&s->zstream);
21155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret != Z_OK)
21165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
21175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
21185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
21215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, clen;
21235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->zstream.avail_out = len;
21255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->zstream.next_out = buf;
21265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (s->zstream.avail_out > 0) {
21275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (s->zstream.avail_in == 0) {
21285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
21295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
21305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            clen = qemu_get_be16(s->f);
21315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (clen > IOBUF_SIZE)
21325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
21335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_get_buffer(s->f, s->buf, clen);
21345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->zstream.avail_in = clen;
21355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->zstream.next_in = s->buf;
21365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
21375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
21385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret != Z_OK && ret != Z_STREAM_END) {
21395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
21405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
21415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
21435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void ram_decompress_close(RamDecompressState *s)
21465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    inflateEnd(&s->zstream);
21485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_FULL	0x01
21515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_COMPRESS	0x02
21525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_MEM_SIZE	0x04
21535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_PAGE	0x08
21545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_EOS	0x10
21555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int is_dup_page(uint8_t *page, uint8_t ch)
21575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
21595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t *array = (uint32_t *)page;
21605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
21615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
21635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (array[i] != val)
21645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
21655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
21685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_save_block(QEMUFile *f)
21715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static ram_addr_t current_addr = 0;
21735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t saved_addr = current_addr;
21745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr = 0;
21755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int found = 0;
21765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (addr < last_ram_offset) {
21785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
21795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t *p;
21805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_physical_memory_reset_dirty(current_addr,
21825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            current_addr + TARGET_PAGE_SIZE,
21835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            MIGRATION_DIRTY_FLAG);
21845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = qemu_get_ram_ptr(current_addr);
21865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (is_dup_page(p, *p)) {
21885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
21895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_byte(f, *p);
21905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
21915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
21925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
21935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
21945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            found = 1;
21965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
21975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
21985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr += TARGET_PAGE_SIZE;
21995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        current_addr = (saved_addr + addr) % last_ram_offset;
22005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return found;
22035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint64_t bytes_transferred = 0;
22065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic ram_addr_t ram_save_remaining(void)
22085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
22105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t count = 0;
22115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
22135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
22145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            count++;
22155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return count;
22185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_remaining(void)
22215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ram_save_remaining() * TARGET_PAGE_SIZE;
22235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_transferred(void)
22265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return bytes_transferred;
22285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_total(void)
22315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return last_ram_offset;
22335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_save_live(QEMUFile *f, int stage, void *opaque)
22365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
22385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t bytes_transferred_last;
22395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    double bwidth = 0;
22405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t expected_time = 0;
22415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX);
22435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (stage == 1) {
22455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Make sure all dirty bits are set */
22465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
22475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
22485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cpu_physical_memory_set_dirty(addr);
22495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Enable dirty memory tracking */
22525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(1);
22535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
22555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bytes_transferred_last = bytes_transferred;
22586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    bwidth = qemu_get_clock_ns(rt_clock);
22595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_file_rate_limit(f)) {
22615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
22625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = ram_save_block(f);
22645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bytes_transferred += ret * TARGET_PAGE_SIZE;
22655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == 0) /* no more blocks */
22665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
22675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
22705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
22715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* if we haven't transferred anything this round, force expected_time to a
22735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * a very high value, but without crashing */
22745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bwidth == 0)
22755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bwidth = 0.000001;
22765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* try transferring iterative blocks of memory */
22785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (stage == 3) {
22805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* flush all remaining blocks regardless of rate limiting */
22825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (ram_save_block(f) != 0) {
22835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bytes_transferred += TARGET_PAGE_SIZE;
22845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(0);
22865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
22895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
22915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return (stage == 2) && (expected_time <= migrate_max_downtime());
22935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load_dead(QEMUFile *f, void *opaque)
22965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    RamDecompressState s1, *s = &s1;
22985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t buf[10];
22995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t i;
23005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ram_decompress_open(s, f) < 0)
23025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
23035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
23045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ram_decompress_buf(s, buf, 1) < 0) {
23055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Error while reading ram block header\n");
23065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto error;
23075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (buf[0] == 0) {
23095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
23105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                   BDRV_HASH_BLOCK_SIZE) < 0) {
23115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
23125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto error;
23135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
23145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
23155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        error:
23165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf("Error block header\n");
23175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EINVAL;
23185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_decompress_close(s);
23215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
23235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load(QEMUFile *f, void *opaque, int version_id)
23265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
23285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
23295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id == 1)
23315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ram_load_v1(f, opaque);
23325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id == 2) {
23345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_get_be32(f) != last_ram_offset)
23355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EINVAL;
23365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ram_load_dead(f, opaque);
23375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id != 3)
23405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
23415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
23435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr = qemu_get_be64(f);
23445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        flags = addr & ~TARGET_PAGE_MASK;
23465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr &= TARGET_PAGE_MASK;
23475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
23495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (addr != last_ram_offset)
23505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -EINVAL;
23515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_FULL) {
23545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ram_load_dead(f, opaque) < 0)
23555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -EINVAL;
23565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
2357d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
23585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_COMPRESS) {
23595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t ch = qemu_get_byte(f);
23605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
23615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (flags & RAM_SAVE_FLAG_PAGE)
23625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
23635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (!(flags & RAM_SAVE_FLAG_EOS));
23645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
23665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_service_io(void)
23695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
23715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
23745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* bottom halves (can be seen as timers which expire ASAP) */
23755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct QEMUBH {
23775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBHFunc *cb;
23785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
23795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int scheduled;
23805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idle;
23815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int deleted;
23825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *next;
23835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
23845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUBH *first_bh = NULL;
23865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
23885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh;
23905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh = qemu_mallocz(sizeof(QEMUBH));
23915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->cb = cb;
23925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->opaque = opaque;
23935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->next = first_bh;
23945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    first_bh = bh;
23955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return bh;
23965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_bh_poll(void)
23995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh, **bhp;
24015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
24025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = 0;
24045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (bh = first_bh; bh; bh = bh->next) {
24055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!bh->deleted && bh->scheduled) {
24065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->scheduled = 0;
24075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!bh->idle)
24085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ret = 1;
24095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->idle = 0;
24105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->cb(bh->opaque);
24115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* remove deleted bhs */
24155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bhp = &first_bh;
24165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*bhp) {
24175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bh = *bhp;
24185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bh->deleted) {
24195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *bhp = bh->next;
24205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(bh);
24215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
24225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bhp = &bh->next;
24235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
24265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_schedule_idle(QEMUBH *bh)
24295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bh->scheduled)
24315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
24325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 1;
24335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->idle = 1;
24345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_schedule(QEMUBH *bh)
24375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bh->scheduled)
24395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
24405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 1;
24415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->idle = 0;
24425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* stop the currently executing CPU to execute the BH ASAP */
24435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
24445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_cancel(QEMUBH *bh)
24475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 0;
24495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_delete(QEMUBH *bh)
24525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 0;
24545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->deleted = 1;
24555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2457d06599430ac907d1a89bbfda4bf3621f909aac8eDavid Turnervoid qemu_bh_update_timeout(int *timeout)
24585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh;
24605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (bh = first_bh; bh; bh = bh->next) {
24625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!bh->deleted && bh->scheduled) {
24635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (bh->idle) {
24645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* idle bottom halves will be polled at least
24655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 * every 10ms */
24665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *timeout = MIN(10, *timeout);
24675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
24685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* non-idle bottom halves will be executed
24695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 * immediately */
24705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *timeout = 0;
24715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
24725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
24735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
24785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* machine registration */
24795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *first_machine = NULL;
24815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUMachine *current_machine = NULL;
24825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_register_machine(QEMUMachine *m)
24845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine **pm;
24865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pm = &first_machine;
24875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pm != NULL)
24885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pm = &(*pm)->next;
24895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->next = NULL;
24905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pm = m;
24915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
24925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
24935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_machine(const char *name)
24955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
24965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
24975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
24995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(m->name, name))
25005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
25015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
25035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_default_machine(void)
25065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
25085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
25105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (m->is_default) {
25115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
25125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
25135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
25155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
25185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* main execution loop */
25195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gui_update(void *opaque)
25215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
25235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds = opaque;
25245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl = ds->listeners;
25255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_refresh(ds);
25275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
25295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->gui_timer_interval &&
25305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dcl->gui_timer_interval < interval)
25315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            interval = dcl->gui_timer_interval;
25325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
25335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
25355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void nographic_update(void *opaque)
25385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
25405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
25425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct vm_change_state_entry {
25455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateHandler *cb;
25465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
2547a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_ENTRY (vm_change_state_entry) entries;
25485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
25495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2550a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turnerstatic QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
25515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerVMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
25535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                     void *opaque)
25545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
25565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e = qemu_mallocz(sizeof (*e));
25585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->cb = cb;
25605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->opaque = opaque;
2561a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
25625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return e;
25635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
25665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2567a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_REMOVE (e, entries);
25685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free (e);
25695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void vm_state_notify(int running, int reason)
25725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
25745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
25765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        e->cb(e->opaque, running, reason);
25775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void);
25815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void);
25825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_start(void)
25845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vm_running) {
25865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_enable_ticks();
25875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_running = 1;
25885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_state_notify(1, 0);
25896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner        //qemu_rearm_alarm_timer(alarm_timer);
25905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        resume_all_vcpus();
25915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* reset/shutdown handler */
25955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUResetEntry {
25975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetHandler *func;
25985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
25995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int order;
26005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct QEMUResetEntry *next;
26015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUResetEntry;
26025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUResetEntry *first_reset_entry;
26045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int reset_requested;
26055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int shutdown_requested;
26065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int powerdown_requested;
26075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int debug_requested;
26085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vmstop_requested;
26095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_shutdown_requested(void)
26115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = shutdown_requested;
26135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 0;
26145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
26155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_reset_requested(void)
26185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = reset_requested;
26205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    reset_requested = 0;
26215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
26225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_powerdown_requested(void)
26255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = powerdown_requested;
26275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 0;
26285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
26295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_debug_requested(void)
26325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = debug_requested;
26345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    debug_requested = 0;
26355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
26365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_vmstop_requested(void)
26395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = vmstop_requested;
26415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = 0;
26425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
26435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void do_vm_stop(int reason)
26465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (vm_running) {
26485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_disable_ticks();
26495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_running = 0;
26505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pause_all_vcpus();
26515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_state_notify(0, reason);
26525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
26565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry **pre, *re;
26585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pre = &first_reset_entry;
26605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pre != NULL && (*pre)->order >= order) {
26615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pre = &(*pre)->next;
26625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re = qemu_mallocz(sizeof(QEMUResetEntry));
26645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->func = func;
26655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->opaque = opaque;
26665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->order = order;
26675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->next = NULL;
26685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pre = re;
26695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset(void)
26725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry *re;
26745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* reset all devices */
26765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(re = first_reset_entry; re != NULL; re = re->next) {
26775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        re->func(re->opaque);
26785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset_request(void)
26825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (no_reboot) {
26845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        shutdown_requested = 1;
26855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
26865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        reset_requested = 1;
26875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
26895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_shutdown_request(void)
26925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 1;
26945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
26955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_powerdown_request(void)
26985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 1;
27005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
27015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
27045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_system_vmstop_request(int reason)
27055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = reason;
27075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
27085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
27125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int io_thread_fd = -1;
27135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_increment(void)
27155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static const char byte = 0;
27175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (io_thread_fd == -1)
27195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
27205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    write(io_thread_fd, &byte, sizeof(byte));
27225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_read(void *opaque)
27255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd = (unsigned long)opaque;
27275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ssize_t len;
27285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Drain the notify pipe */
27305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
27315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        char buffer[512];
27325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = read(fd, buffer, sizeof(buffer));
27335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while ((len == -1 && errno == EINTR) || len > 0);
27345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_event_init(void)
27375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int err;
27395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fds[2];
27405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = pipe(fds);
27425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err == -1)
27435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -errno;
27445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = fcntl_setfl(fds[0], O_NONBLOCK);
27465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err < 0)
27475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
27485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = fcntl_setfl(fds[1], O_NONBLOCK);
27505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err < 0)
27515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
27525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
27545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         (void *)(unsigned long)fds[0]);
27555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    io_thread_fd = fds[1];
27575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
27585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail:
27605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fds[0]);
27615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fds[1]);
27625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return err;
27635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
27655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerHANDLE qemu_event_handle;
27665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dummy_event_handler(void *opaque)
27685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_event_init(void)
27725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
27745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_event_handle) {
27755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        perror("Failed CreateEvent");
27765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
27785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
27795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
27805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_increment(void)
27835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SetEvent(qemu_event_handle);
27855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_can_run(CPUState *env)
27895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop)
27915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
27925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stopped)
27935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
27945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
27955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
27985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_init_main_loop(void)
27995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_event_init();
28015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_init_vcpu(void *_env)
28045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
28065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
28085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kvm_init_vcpu(env);
28095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
28105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_cpu_self(void *env)
28135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
28155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void)
28185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void)
28225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_cpu_kick(void *env)
28265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
28285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_notify_event(void)
28315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = cpu_single_env;
28335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env) {
28355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_exit(env);
28365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef USE_KQEMU
28375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (env->kqemu_enabled)
28385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            kqemu_cpu_interrupt(env);
28395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
28405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     }
28415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define qemu_mutex_lock_iothread() do { } while (0)
28445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define qemu_mutex_unlock_iothread() do { } while (0)
28455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_stop(int reason)
28475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do_vm_stop(reason);
28495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* CONFIG_IOTHREAD */
28525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-thread.h"
28545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQemuMutex qemu_global_mutex;
28565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuMutex qemu_fair_mutex;
28575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuThread io_thread;
28595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuThread *tcg_cpu_thread;
28615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond *tcg_halt_cond;
28625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_system_ready;
28645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* cpu creation */
28655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_cpu_cond;
28665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* system init */
28675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_system_cond;
28685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_pause_cond;
28695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void block_io_signals(void);
28715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unblock_io_signals(void);
28725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tcg_has_work(void);
28735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_init_main_loop(void)
28755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
28775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = qemu_event_init();
28795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret)
28805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret;
28815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_init(&qemu_pause_cond);
28835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_init(&qemu_fair_mutex);
28845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_init(&qemu_global_mutex);
28855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
28865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unblock_io_signals();
28885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(&io_thread);
28895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
28915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_wait_io_event(CPUState *env)
28945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!tcg_has_work())
28965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
28975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_global_mutex);
28995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /*
29015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * Users of qemu_global_mutex can be starved, having no chance
29025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * to acquire it since this path will get to it first.
29035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * So use another lock to provide fairness.
29045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
29055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_fair_mutex);
29065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_fair_mutex);
29075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
29095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop) {
29105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->stop = 0;
29115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->stopped = 1;
29125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_signal(&qemu_pause_cond);
29135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
29145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env);
29175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *kvm_cpu_thread_fn(void *arg)
29195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = arg;
29215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    block_io_signals();
29235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(env->thread);
29245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* signal CPU creation */
29265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
29275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->created = 1;
29285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_signal(&qemu_cpu_cond);
29295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* and wait for machine initialization */
29315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_system_ready)
29325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
29335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
29355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_can_run(env))
29365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_cpu_exec(env);
29375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_wait_io_event(env);
29385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
29395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
29415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_cpu_exec(void);
29445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *tcg_cpu_thread_fn(void *arg)
29465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = arg;
29485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    block_io_signals();
29505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(env->thread);
29515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* signal CPU creation */
29535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
29545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu)
29555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->created = 1;
29565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_signal(&qemu_cpu_cond);
29575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* and wait for machine initialization */
29595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_system_ready)
29605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
29615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
29635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_cpu_exec();
29645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_wait_io_event(cur_cpu);
29655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
29665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
29685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_cpu_kick(void *_env)
29715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
29735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_broadcast(env->halt_cond);
29745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
29755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(env->thread, SIGUSR1);
29765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_cpu_self(void *env)
29795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return (cpu_single_env != NULL);
29815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void cpu_signal(int sig)
29845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cpu_single_env)
29865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_exit(cpu_single_env);
29875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void block_io_signals(void)
29905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigset_t set;
29925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction sigact;
29935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
29955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR2);
29965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGIO);
29975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGALRM);
29985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_BLOCK, &set, NULL);
29995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
30015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR1);
30025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
30035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&sigact, 0, sizeof(sigact));
30055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigact.sa_handler = cpu_signal;
30065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGUSR1, &sigact, NULL);
30075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unblock_io_signals(void)
30105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigset_t set;
30125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
30145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR2);
30155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGIO);
30165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGALRM);
30175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
30185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
30205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR1);
30215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_BLOCK, &set, NULL);
30225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_signal_lock(unsigned int msecs)
30255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_fair_mutex);
30275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (qemu_mutex_trylock(&qemu_global_mutex)) {
30295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
30305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
30315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
30325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_fair_mutex);
30345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_mutex_lock_iothread(void)
30375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
30395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_lock(&qemu_fair_mutex);
30405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_lock(&qemu_global_mutex);
30415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_unlock(&qemu_fair_mutex);
30425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else
30435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_signal_lock(100);
30445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_mutex_unlock_iothread(void)
30475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_global_mutex);
30495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int all_vcpus_paused(void)
30525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
30545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
30565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!penv->stopped)
30575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
30585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
30595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
30625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void)
30655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
30675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
30695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stop = 1;
30705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(penv->thread, SIGUSR1);
30715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cpu_kick(penv);
30725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
30735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!all_vcpus_paused()) {
30765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
30775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = first_cpu;
30785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (penv) {
30795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_thread_signal(penv->thread, SIGUSR1);
30805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            penv = (CPUState *)penv->next_cpu;
30815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
30825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void)
30865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
30885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
30905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stop = 0;
30915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stopped = 0;
30925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(penv->thread, SIGUSR1);
30935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cpu_kick(penv);
30945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
30955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_init_vcpu(void *_env)
30995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
31015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* share a single thread for all cpus with TCG */
31025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!tcg_cpu_thread) {
31035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->thread = qemu_mallocz(sizeof(QemuThread));
31045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->halt_cond = qemu_mallocz(sizeof(QemuCond));
31055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_init(env->halt_cond);
31065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
31075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (env->created == 0)
31085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
31095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_cpu_thread = env->thread;
31105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_halt_cond = env->halt_cond;
31115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
31125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->thread = tcg_cpu_thread;
31135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->halt_cond = tcg_halt_cond;
31145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void kvm_start_vcpu(CPUState *env)
31185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
31205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kvm_init_vcpu(env);
31215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->thread = qemu_mallocz(sizeof(QemuThread));
31225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->halt_cond = qemu_mallocz(sizeof(QemuCond));
31235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_init(env->halt_cond);
31245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
31255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (env->created == 0)
31265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
31275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_init_vcpu(void *_env)
31315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
31335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
31355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kvm_start_vcpu(env);
31365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
31375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_init_vcpu(env);
31385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_notify_event(void)
31415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_event_increment();
31435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_stop(int reason)
31465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QemuThread me;
31485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(&me);
31495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_thread_equal(&me, &io_thread)) {
31515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_system_vmstop_request(reason);
31525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /*
31535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * FIXME: should not return to device code in case
31545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * vm_stop() has been requested.
31555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
31565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_single_env) {
31575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_exit(cpu_single_env);
31585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_single_env->stop = 1;
31595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
31605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
31615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do_vm_stop(reason);
31635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
31665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
31695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void host_main_loop_wait(int *timeout)
31705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, ret2, i;
31725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry *pe;
31735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: need to suppress polling by better using win32 events */
31765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = 0;
31775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
31785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret |= pe->func(pe->opaque);
31795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret == 0) {
31815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int err;
31825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        WaitObjects *w = &wait_objects;
31835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
31855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
31865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (w->func[ret - WAIT_OBJECT_0])
31875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
31885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Check for additional signaled events */
31905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
31915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* Check if event is signaled */
31935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ret2 = WaitForSingleObject(w->events[i], 0);
31945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(ret2 == WAIT_OBJECT_0) {
31955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (w->func[i])
31965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        w->func[i](w->opaque[i]);
31975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else if (ret2 == WAIT_TIMEOUT) {
31985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
31995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    err = GetLastError();
32005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
32015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
32025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
32035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (ret == WAIT_TIMEOUT) {
32045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
32055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = GetLastError();
32065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
32075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *timeout = 0;
32115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
32135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void host_main_loop_wait(int *timeout)
32145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
32175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid main_loop_wait(int timeout)
32195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandlerRecord *ioh;
32215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set rfds, wfds, xfds;
32225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, nfds;
32235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct timeval tv;
32245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_update_timeout(&timeout);
32265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    host_main_loop_wait(&timeout);
32285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* poll any events */
32305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: separate device handlers from system ones */
32315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nfds = -1;
32325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&rfds);
32335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&wfds);
32345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&xfds);
32355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
32365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->deleted)
32375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
32385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->fd_read &&
32395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            (!ioh->fd_read_poll ||
32405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             ioh->fd_read_poll(ioh->opaque) != 0)) {
32415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_SET(ioh->fd, &rfds);
32425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd > nfds)
32435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nfds = ioh->fd;
32445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->fd_write) {
32465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_SET(ioh->fd, &wfds);
32475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd > nfds)
32485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nfds = ioh->fd;
32495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tv.tv_sec = timeout / 1000;
32535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tv.tv_usec = (timeout % 1000) * 1000;
32545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
32565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
32575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
32585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
32605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock_iothread();
32615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
32625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock_iothread();
32635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret > 0) {
32645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        IOHandlerRecord **pioh;
32655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
32675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
32685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->fd_read(ioh->opaque);
32695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
32705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
32715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->fd_write(ioh->opaque);
32725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
32735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* remove deleted IO handlers */
32765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pioh = &first_io_handler;
32775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	while (*pioh) {
32785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ioh = *pioh;
32795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->deleted) {
32805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *pioh = ioh->next;
32815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_free(ioh);
32825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
32835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pioh = &ioh->next;
32845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
32875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
32885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
32895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&rfds);
32905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&wfds);
32915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&xfds);
32925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_poll(&rfds, &wfds, &xfds);
32945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
32965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    charpipe_poll();
32975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if 0
32995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* rearm timer, if not periodic */
33005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
33015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
33025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_rearm_alarm_timer(alarm_timer);
33035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* vm time timers */
33065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (vm_running) {
33075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
3308a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
33095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_get_clock(vm_clock));
33105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* real time timers */
3313a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
33145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    qemu_get_clock(rt_clock));
33155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3316a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
3317a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                    qemu_get_clock(host_clock));
33186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif
33196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    qemu_run_all_timers();
3320a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
33215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Check bottom-halves last in case any of the earlier events triggered
33225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       them.  */
33235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_poll();
33245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
33265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env)
33285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
33295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
33305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
33315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t ti;
33325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
33355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ti = profile_getclock();
33365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount) {
33385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int64_t count;
33395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int decr;
33405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
33415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u16.low = 0;
33425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = 0;
33435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count = qemu_next_deadline();
33445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count = (count + (1 << icount_time_shift) - 1)
33455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                >> icount_time_shift;
33465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount += count;
33475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        decr = (count > 0xffff) ? 0xffff : count;
33485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count -= decr;
33495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u16.low = decr;
33505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = count;
33515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
3352a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner#ifdef CONFIG_TRACE
3353a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner    if (tbflush_requested) {
3354a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        tbflush_requested = 0;
3355a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        tb_flush(env);
3356a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        return EXCP_INTERRUPT;
3357a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner    }
3358a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner#endif
3359a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner
3360a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner
33615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = cpu_exec(env);
33625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
33635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_time += profile_getclock() - ti;
33645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
33655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount) {
33665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Fold pending instructions back into the
33675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           instruction counter, and clear the interrupt flag.  */
33685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount -= (env->icount_decr.u16.low
33695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        + env->icount_extra);
33705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u32 = 0;
33715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = 0;
33725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
33745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
33755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_cpu_exec(void)
33775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
33785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret = 0;
33795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (next_cpu == NULL)
33815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        next_cpu = first_cpu;
33825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
33835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        CPUState *env = cur_cpu = next_cpu;
33845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!vm_running)
33865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
33875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (timer_alarm_pending) {
33885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            timer_alarm_pending = 0;
33895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
33905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_can_run(env))
33925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = qemu_cpu_exec(env);
33935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == EXCP_DEBUG) {
33945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_set_stop_cpu(env);
33955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            debug_requested = 1;
33965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
33975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_has_work(CPUState *env)
34025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop)
34045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
34055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stopped)
34065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
34075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!env->halted)
34085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
34095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_cpu_has_work(env))
34105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
34115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
34125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tcg_has_work(void)
34155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
34175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu)
34195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_has_work(env))
34205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 1;
34215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
34225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vm_can_run(void)
34265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (powerdown_requested)
34285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
34295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reset_requested)
34305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
34315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (shutdown_requested)
34325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
34335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (debug_requested)
34345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
34355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
34365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void main_loop(void)
34395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r;
34415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
34435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_system_ready = 1;
34445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_broadcast(&qemu_system_cond);
34455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
34465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (;;) {
34485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        do {
34495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
34505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            int64_t ti;
34515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
34525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
34535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_cpu_exec();
34545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
34555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
34565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ti = profile_getclock();
34575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
34585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            main_loop_wait(qemu_calculate_timeout());
34595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
34605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dev_time += profile_getclock() - ti;
34615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
34625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } while (vm_can_run());
34635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_debug_requested())
34655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(EXCP_DEBUG);
34665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_shutdown_requested()) {
34675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (no_shutdown) {
34685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vm_stop(0);
34695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 0;
34705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
34715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
34725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
34735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_reset_requested()) {
34745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pause_all_vcpus();
34755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_reset();
34765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            resume_all_vcpus();
34775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
34785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_powerdown_requested())
34795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_powerdown();
34805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((r = qemu_vmstop_requested()))
34815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(r);
34825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
34835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pause_all_vcpus();
34845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinevoid version(void)
34875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
34895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_help(int exitcode)
34925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    version();
34945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("usage: %s [options] [disk_image]\n"
34955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
34965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
34975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
34985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
34995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           opt_help
35005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text) stringify(text) "\n"
35015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
35025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
35035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
35045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
35055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
35065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "During emulation, the following keys are useful:\n"
35075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-f      toggle full screen\n"
35085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-n      switch to virtual console 'n'\n"
35095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt        toggle mouse and keyboard grab\n"
35105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
35115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "When using -nographic, press 'ctrl-a h' to get some help.\n"
35125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           ,
35135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "qemu",
35145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_RAM_SIZE,
35155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
35165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_SCRIPT,
35175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_DOWN_SCRIPT,
35185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
35195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_GDBSTUB_PORT,
35205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "/tmp/qemu.log");
35215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    exit(exitcode);
35225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HAS_ARG 0x0001
35255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum {
35275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
35285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    opt_enum,
35295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
35305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
35315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
35325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
35335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
35345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
35355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUOption {
35375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *name;
35385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
35395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
35405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUOption;
35415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const QEMUOption qemu_options[] = {
35435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { "h", 0, QEMU_OPTION_h },
35445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
35455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { option, opt_arg, opt_enum },
35465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
35475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
35485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
35495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
35505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
35515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL, 0, 0 },
35525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
35535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO
35555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct soundhw soundhw[] = {
35565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO_CHOICE
35575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_I386) || defined(TARGET_MIPS)
35585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
35595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "pcspk",
35605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "PC speaker",
35615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
35625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
35635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = pcspk_audio_init }
35645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
35655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
35665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SB16
35685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
35695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "sb16",
35705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Creative Sound Blaster 16",
35715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
35725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
35735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = SB16_init }
35745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
35755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
35765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_CS4231A
35785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
35795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "cs4231a",
35805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "CS4231A",
35815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
35825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
35835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = cs4231a_init }
35845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
35855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
35865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_ADLIB
35885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
35895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "adlib",
35905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_YMF262
35915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Yamaha YMF262 (OPL3)",
35925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
35935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Yamaha YM3812 (OPL2)",
35945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
35955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
35965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
35975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = Adlib_init }
35985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
35995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
36005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_GUS
36025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
36035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "gus",
36045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Gravis Ultrasound GF1",
36055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
36065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
36075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = GUS_init }
36085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
36095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
36105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_AC97
36125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
36135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "ac97",
36145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Intel 82801AA AC97 Audio",
36155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
36165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
36175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_pci = ac97_init }
36185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
36195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
36205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_ES1370
36225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
36235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "es1370",
36245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "ENSONIQ AudioPCI ES1370",
36255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
36265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
36275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_pci = es1370_init }
36285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
36295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
36305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* HAS_AUDIO_CHOICE */
36325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL, NULL, 0, 0, { NULL } }
36345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
36355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void select_soundhw (const char *optarg)
36375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct soundhw *c;
36395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (*optarg == '?') {
36415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    show_valid_cards:
36425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        printf ("Valid sound card names (comma separated):\n");
36445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (c = soundhw; c->name; ++c) {
36455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf ("%-11s %s\n", c->name, c->descr);
36465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
36475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        printf ("\n-soundhw all will enable all of the above\n");
36485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit (*optarg != '?');
36495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else {
36515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        size_t l;
36525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *p;
36535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        char *e;
36545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int bad_card = 0;
36555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp (optarg, "all")) {
36575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (c = soundhw; c->name; ++c) {
36585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                c->enabled = 1;
36595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
36605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return;
36615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
36625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = optarg;
36645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (*p) {
36655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            e = strchr (p, ',');
36665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            l = !e ? strlen (p) : (size_t) (e - p);
36675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (c = soundhw; c->name; ++c) {
36695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strncmp (c->name, p, l)) {
36705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    c->enabled = 1;
36715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
36725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
36735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
36745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!c->name) {
36765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (l > 80) {
36775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf (stderr,
36785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             "Unknown sound card name (too big to show)\n");
36795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
36805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else {
36815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
36825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             (int) l, p);
36835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
36845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bad_card = 1;
36855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
36865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p += l + (e != NULL);
36875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
36885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bad_card)
36905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto show_valid_cards;
36915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
36945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void select_vgahw (const char *p)
36965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *opts;
36985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cirrus_vga_enabled = 0;
37005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    std_vga_enabled = 0;
37015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmsvga_enabled = 0;
37025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    xenfb_enabled = 0;
37035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(p, "std", &opts)) {
37045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        std_vga_enabled = 1;
37055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "cirrus", &opts)) {
37065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cirrus_vga_enabled = 1;
37075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "vmware", &opts)) {
37085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vmsvga_enabled = 1;
37095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "xenfb", &opts)) {
37105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        xenfb_enabled = 1;
37115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strstart(p, "none", &opts)) {
37125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    invalid_vga:
37135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Unknown vga type: %s\n", p);
37145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
37155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
37165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*opts) {
37175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *nextopt;
37185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strstart(opts, ",retrace=", &nextopt)) {
37205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            opts = nextopt;
37215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(opts, "dumb", &nextopt))
37225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_DUMB;
37235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else if (strstart(opts, "precise", &nextopt))
37245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_PRECISE;
37255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else goto invalid_vga;
37265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else goto invalid_vga;
37275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        opts = nextopt;
37285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
37295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
37325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BOOL WINAPI qemu_ctrl_handler(DWORD type)
37335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    exit(STATUS_CONTROL_C_EXIT);
37355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return TRUE;
37365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
37385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_uuid_parse(const char *str, uint8_t *uuid)
37405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
37425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(strlen(str) != 36)
37445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
37455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
37475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
37485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
37495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(ret != 16)
37515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
37525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
37545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
37555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
37565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
37585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_NET_CLIENTS 32
37615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
37635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void termsig_handler(int signal)
37655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_system_shutdown_request();
37675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void sigchld_handler(int signal)
37705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    waitpid(-1, NULL, WNOHANG);
37725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void sighandler_setup(void)
37755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction act;
37775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&act, 0, sizeof(act));
37795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = termsig_handler;
37805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGINT,  &act, NULL);
37815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGHUP,  &act, NULL);
37825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGTERM, &act, NULL);
37835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = sigchld_handler;
37855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_flags = SA_NOCLDSTOP;
37865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGCHLD, &act, NULL);
37875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
37905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
37925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Look for support files in the same directory as the executable.  */
37935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
37945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p;
37965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[MAX_PATH];
37975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DWORD len;
37985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
38005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (len == 0) {
38015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
38025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf[len] = 0;
38055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = buf + len - 1;
38065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (p != buf && *p != '\\')
38075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p--;
38085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *p = 0;
38095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(buf, R_OK) == 0) {
38105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_strdup(buf);
38115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
38135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* !_WIN32 */
38155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Find a likely location for support files using the location of the binary.
38175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   For installed binaries this will be "$bindir/../share/qemu".  When
38185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   running from the build tree this will be "$bindir/../pc-bios".  */
38195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define SHARE_SUFFIX "/share/qemu"
38205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define BUILD_SUFFIX "/pc-bios"
38215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
38225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *dir;
38245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p = NULL;
38255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *res;
38265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef PATH_MAX
38275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[PATH_MAX];
38285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    size_t max_len;
38305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__)
38325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
38335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
38345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
38355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
38365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
38375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
38385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
38395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(__FreeBSD__)
38415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
38425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
38435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
38445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
38455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
38465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
38475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
38485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If we don't have any way of figuring out the actual executable
38515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       location then try argv[0].  */
38525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p) {
38535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef PATH_MAX
38545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = buf;
38555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = realpath(argv0, p);
38575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!p) {
38585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return NULL;
38595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
38605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dir = dirname(p);
38625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dir = dirname(dir);
38635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_len = strlen(dir) +
38655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
38665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res = qemu_mallocz(max_len);
38675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
38685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(res, R_OK)) {
38695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
38705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (access(res, R_OK)) {
38715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(res);
38725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            res = NULL;
38735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
38745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef PATH_MAX
38765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free(p);
38775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return res;
38795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef SHARE_SUFFIX
38815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef BUILD_SUFFIX
38825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *qemu_find_file(int type, const char *name)
38855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int len;
38875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *subdir;
38885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *buf;
38895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If name contains path separators then try it as a straight path.  */
38915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((strchr(name, '/') || strchr(name, '\\'))
38925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && access(name, R_OK) == 0) {
38935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return strdup(name);
38945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (type) {
38965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_BIOS:
38975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "";
38985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
38995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_KEYMAP:
39005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "keymaps/";
39015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
39025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
39035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
39045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
39065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf = qemu_mallocz(len);
39075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
39085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(buf, R_OK)) {
39095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(buf);
39105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
39115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return buf;
39135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
39145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39157fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinestatic int
39167fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkineadd_dns_server( const char*  server_name )
39177fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine{
39187fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    SockAddress   addr;
39197fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
39207fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
39217fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stdout,
39227fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: can't resolve DNS server name '%s'\n",
39237fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                server_name );
39247fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
39257fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
39267fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
39277fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    fprintf(stderr,
39287fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
39297fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
39307fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if ( slirp_add_dns_server( &addr ) < 0 ) {
39317fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stderr,
39327fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
39337fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
39347fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
39357fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    return 0;
39367fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine}
39377fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
39387fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine/* Appends a parameter to a string of parameters separated with space.
39397fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine * Pararm:
39407fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  param_str String containing parameters separated with space.
39417fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  param Parameter to append to the string.
39427fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  size - Size (in characters) of the buffer addressed by param_str.
39437fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine */
39447fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinestatic void
39457fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkineappend_param(char* param_str, const char* arg, int size)
39467fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine{
39477fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (*param_str) {
39487fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncat(param_str, " ", size);
39497fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncat(param_str, arg, size);
39507fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    } else {
39517fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncpy(param_str, arg, size);
39527fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        param_str[size - 1] = '\0';
39537fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
39547fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine}
39557fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
39565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint main(int argc, char **argv, char **envp)
39575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
39585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *gdbstub_dev = NULL;
39595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t boot_devices_bitmap = 0;
39605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
39615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int snapshot, linux_boot, net_boot;
39626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    const char *icount_option = NULL;
39635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *initrd_filename;
39645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *kernel_filename, *kernel_cmdline;
39655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *boot_devices = "";
39665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds;
39675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl;
39685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
39695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *net_clients[MAX_NET_CLIENTS];
39705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_net_clients;
39715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *bt_opts[MAX_BT_CMDLINE];
39725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_bt_opts;
39735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int hda_index;
39745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int optind;
39755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *r, *optarg;
39765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *monitor_hd = NULL;
39775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *monitor_device;
39785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *serial_devices[MAX_SERIAL_PORTS];
39795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int serial_device_index;
39805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *parallel_devices[MAX_PARALLEL_PORTS];
39815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int parallel_device_index;
39825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
39835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int virtio_console_index;
39845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *loadvm = NULL;
39855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine;
39865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *cpu_model;
39875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *usb_devices[MAX_USB_CMDLINE];
39885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int usb_devices_index;
39895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
39905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fds[2];
39915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
39925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int tb_size;
39935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *pid_file = NULL;
39945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *incoming = NULL;
39955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
39965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd = 0;
39975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct passwd *pwd = NULL;
39985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *chroot_dir = NULL;
39995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *run_as = NULL;
40005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
40015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
40025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int show_vnc_port = 0;
4003074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
4004074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    IniFile*  hw_ini = NULL;
4005074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
40067fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Container for the kernel initialization parameters collected in this
40077fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * routine. */
40087fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char kernel_cmdline_append[1024];
40097fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Combines kernel initialization parameters passed from the UI with
40107fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * the parameters collected in this routine. */
40117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char kernel_cmdline_full[1024];
40127fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char tmp_str[1024];
40137fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    int    dns_count = 0;
40145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4015a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    init_clocks();
4016a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
40175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cache_utils_init(envp);
40185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4019a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INIT (&vm_change_state_head);
40205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
40215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
40225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct sigaction act;
40235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sigfillset(&act.sa_mask);
40245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        act.sa_flags = 0;
40255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        act.sa_handler = SIG_IGN;
40265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sigaction(SIGPIPE, &act, NULL);
40275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
40295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
40305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Note: cpu_interrupt() is currently not SMP safe, so we force
40315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       QEMU to run on a single CPU */
40325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
40335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        HANDLE h;
40345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        DWORD mask, smask;
40355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int i;
40365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        h = GetCurrentProcess();
40375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (GetProcessAffinityMask(h, &mask, &smask)) {
40385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(i = 0; i < 32; i++) {
40395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (mask & (1 << i))
40405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
40415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
40425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (i != 32) {
40435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                mask = 1 << i;
40445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                SetProcessAffinityMask(h, mask);
40455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
40465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
40475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
40495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_MACHINE);
40515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine = find_default_machine();
40525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_model = NULL;
40535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    initrd_filename = NULL;
40545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_size = 0;
40555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snapshot = 0;
40565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_filename = NULL;
40575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_cmdline = "";
40587fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    kernel_cmdline_append[0] = '\0';
40597fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    kernel_cmdline_full[0] = '\0';
40605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
40615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
40625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_device = "vc:80Cx24C";
40635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_devices[0] = "vc:80Cx24C";
40655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_SERIAL_PORTS; i++)
40665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        serial_devices[i] = NULL;
40675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_device_index = 0;
40685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_devices[0] = "vc:80Cx24C";
40705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
40715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        parallel_devices[i] = NULL;
40725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_device_index = 0;
40735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
40755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        virtio_consoles[i] = NULL;
40765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    virtio_console_index = 0;
40775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_NODES; i++) {
40795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_mem[i] = 0;
40805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_cpumask[i] = 0;
40815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_devices_index = 0;
40845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_net_clients = 0;
40865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_bt_opts = 0;
40875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives = 0;
40885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt = 0;
40895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_numa_nodes = 0;
40905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hda_index = -1;
40915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_nics = 0;
40935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tb_size = 0;
40955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    autostart= 1;
40965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_watchdogs();
40985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4099b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Initialize boot properties. */
4100b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    boot_property_init_service();
4101b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
41025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optind = 1;
41035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
41045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (optind >= argc)
41055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
41065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        r = argv[optind];
41075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (r[0] != '-') {
41085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
41095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
41105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const QEMUOption *popt;
41115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            optind++;
41135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Treat --foo the same as -foo.  */
41145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (r[1] == '-')
41155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                r++;
41165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            popt = qemu_options;
41175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(;;) {
41185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!popt->name) {
41195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "%s: invalid option -- '%s'\n",
41205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            argv[0], r);
41215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
41225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
41235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strcmp(popt->name, r + 1))
41245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
41255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                popt++;
41265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (popt->flags & HAS_ARG) {
41285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (optind >= argc) {
41295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "%s: option '%s' requires an argument\n",
41305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            argv[0], r);
41315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
41325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
41335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = argv[optind++];
41345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
41355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = NULL;
41365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
41375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch(popt->index) {
41395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_M:
41405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine = find_machine(optarg);
41415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!machine) {
41425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    QEMUMachine *m;
41435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    printf("Supported machines are:\n");
41445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for(m = first_machine; m != NULL; m = m->next) {
41455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("%-10s %s%s\n",
41465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->name, m->desc,
41475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->is_default ? " (default)" : "");
41485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
41495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(*optarg != '?');
41505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
41515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cpu:
41535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* hw initialization will check this */
41545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*optarg == '?') {
41555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: implement xxx_cpu_list for targets that still miss it */
41565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(cpu_list)
41575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_list(stdout, &fprintf);
41585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
41595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(0);
41605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
41615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_model = optarg;
41625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
41635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_initrd:
41655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                initrd_filename = optarg;
41665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hda:
41685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (cyls == 0)
41695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    hda_index = drive_add(optarg, HD_ALIAS, 0);
41705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else
41715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    hda_index = drive_add(optarg, HD_ALIAS
41725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     ",cyls=%d,heads=%d,secs=%d%s",
41735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             0, cyls, heads, secs,
41745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_LBA ?
41755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=lba" :
41765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_NONE ?
41775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=none" : "");
41785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 break;
41795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdb:
41805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdc:
41815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdd:
41825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
41835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_drive:
41855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(NULL, "%s", optarg);
41865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        break;
41875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mtdblock:
41885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, MTD_ALIAS);
41895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sd:
41915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, SD_ALIAS);
41925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pflash:
41945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, PFLASH_ALIAS);
41955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_snapshot:
41975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snapshot = 1;
41985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
41995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdachs:
42005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
42015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
42025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
42035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cyls = strtol(p, (char **)&p, 0);
42045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (cyls < 1 || cyls > 16383)
42055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
42065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
42075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
42085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
42095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    heads = strtol(p, (char **)&p, 0);
42105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (heads < 1 || heads > 16)
42115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
42125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
42135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
42145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
42155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    secs = strtol(p, (char **)&p, 0);
42165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (secs < 1 || secs > 63)
42175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
42185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == ',') {
42195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
42205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (!strcmp(p, "none"))
42215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_NONE;
42225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "lba"))
42235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_LBA;
42245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "auto"))
42255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_AUTO;
42265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else
42275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto chs_fail;
42285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p != '\0') {
42295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    chs_fail:
42305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: invalid physical CHS format\n");
42315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
42325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
42335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    if (hda_index != -1)
42345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        snprintf(drives_opt[hda_index].opt,
42355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 sizeof(drives_opt[hda_index].opt),
42365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
42375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 0, cyls, heads, secs,
42385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			         translation == BIOS_ATA_TRANSLATION_LBA ?
42395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     	    ",trans=lba" :
42405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			         translation == BIOS_ATA_TRANSLATION_NONE ?
42415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			             ",trans=none" : "");
42425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
42435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_numa:
42455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_numa_nodes >= MAX_NODES) {
42465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many NUMA nodes\n");
42475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
42485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
42495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                numa_add(optarg);
42505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nographic:
42525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_NOGRAPHIC;
42535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_CURSES
42555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_curses:
42565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_CURSES;
42575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
42595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_portrait:
42605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                graphic_rotate = 1;
42615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_kernel:
42635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_filename = optarg;
42645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_append:
42665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_cmdline = optarg;
42675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cdrom:
42695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, CDROM_ALIAS);
42705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
42715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_boot:
42725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                boot_devices = optarg;
42735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* We just do some generic consistency checks */
42745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
42755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    /* Could easily be extended to 64 devices if needed */
42765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
4277d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
42785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    boot_devices_bitmap = 0;
42795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for (p = boot_devices; *p != '\0'; p++) {
42805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        /* Allowed boot devices are:
42815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * a b     : floppy disk drives
42825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * c ... f : IDE disk drives
42835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * g ... m : machine implementation dependant drives
42845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * n ... p : network devices
42855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * It's up to each machine implementation to check
42865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * if the given boot devices match the actual hardware
42875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * implementation and firmware features.
42885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         */
42895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (*p < 'a' || *p > 'q') {
42905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
42915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
42925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
42935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
42945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr,
42955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                    "Boot device '%c' was given twice\n",*p);
42965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
42975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
42985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        boot_devices_bitmap |= 1 << (*p - 'a');
42995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
43005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fda:
43035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fdb:
43045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
43055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
43075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_fd_bootchk:
43085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fd_bootchk = 0;
43095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_net:
43125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_net_clients >= MAX_NET_CLIENTS) {
43135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many network clients\n");
43145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
43155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_clients[nb_net_clients] = optarg;
43175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_net_clients++;
43185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
43205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tftp:
43215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		tftp_prefix = optarg;
43225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bootp:
43245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bootp_filename = optarg;
43255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0  /* ANDROID disabled */
43275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
43285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smb:
43295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		net_slirp_smb(optarg);
43305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* ANDROID */
43335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_redir:
43345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_slirp_redir(NULL, optarg, NULL);
43355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bt:
43385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_bt_opts >= MAX_BT_CMDLINE) {
43395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many bluetooth options\n");
43405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
43415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bt_opts[nb_bt_opts++] = optarg;
43435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO
43455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_audio_help:
43465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                AUD_help ();
43475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit (0);
43485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_soundhw:
43505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_soundhw (optarg);
43515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_h:
43545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_help(0);
43555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_version:
43575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                version();
43585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(0);
43595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_m: {
43615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                uint64_t value;
43625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                char *ptr;
43635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = strtoul(optarg, &ptr, 10);
43655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                switch (*ptr) {
43665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 0: case 'M': case 'm':
43675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 20;
43685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
43695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 'G': case 'g':
43705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 30;
43715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
43725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                default:
43735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
43745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
43755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* On 32-bit hosts, QEMU is limited by virtual address space */
43785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value > (2047 << 20)
43795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_KQEMU
43805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    && HOST_LONG_BITS == 32
43815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    ) {
43835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
43845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
43855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value != (uint64_t)(ram_addr_t)value) {
43875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: ram size too large\n");
43885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
43895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
43905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ram_size = value;
43915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
43925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
43935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_d:
43945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
43955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int mask;
43965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const CPULogItem *item;
43975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    mask = cpu_str_to_log_mask(optarg);
43995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!mask) {
44005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Log items (comma separated):\n");
44015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for(item = cpu_log_items; item->mask != 0; item++) {
44025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("%-10s %s\n", item->name, item->help);
44035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
44045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
44055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
44065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_set_log(mask);
44075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
44085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_s:
44105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
44115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_gdb:
44135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = optarg;
44145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_L:
44165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                data_dir = optarg;
44175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bios:
44195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bios_name = optarg;
44205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_singlestep:
44225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                singlestep = 1;
44235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_S:
44255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0  /* ANDROID */
44265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Sorry, stopped launch is not supported in the Android emulator\n" );
44275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
44285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
44295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                autostart = 0;
44305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
44325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_k:
44335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		keyboard_layout = optarg;
44345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
44355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
44365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_localtime:
44375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_utc = 0;
44385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_vga:
44405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_vgahw (optarg);
44415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_PPC) || defined(TARGET_SPARC)
44435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_g:
44445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
44455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
44465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int w, h, depth;
44475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
44485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    w = strtol(p, (char **)&p, 10);
44495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (w <= 0) {
44505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_error:
44515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: invalid resolution or depth\n");
44525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
44535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
44545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != 'x')
44555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
44565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
44575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    h = strtol(p, (char **)&p, 10);
44585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (h <= 0)
44595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
44605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == 'x') {
44615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
44625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = strtol(p, (char **)&p, 10);
44635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (depth != 8 && depth != 15 && depth != 16 &&
44645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            depth != 24 && depth != 32)
44655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto graphic_error;
44665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p == '\0') {
44675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = graphic_depth;
44685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
44695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
44705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
44715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_width = w;
44735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_height = h;
44745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_depth = depth;
44755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
44765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
44785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_echr:
44795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
44805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    char *r;
44815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    term_escape_char = strtol(optarg, &r, 0);
44825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (r == optarg)
44835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Bad argument to echr\n");
44845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
44855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
44865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_monitor:
44875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = optarg;
44885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_serial:
44905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (serial_device_index >= MAX_SERIAL_PORTS) {
44915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many serial ports\n");
44925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
44935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
44945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[serial_device_index] = optarg;
44955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_device_index++;
44965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
44975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog:
44985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                i = select_watchdog(optarg);
44995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (i > 0)
45005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit (i == 1 ? 1 : 0);
45015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog_action:
45035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (select_watchdog_action(optarg) == -1) {
45045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Unknown -watchdog-action parameter\n");
45055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_virtiocon:
45095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
45105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many virtio consoles\n");
45115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_consoles[virtio_console_index] = optarg;
45145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_console_index++;
45155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_parallel:
45175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
45185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many parallel ports\n");
45195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_devices[parallel_device_index] = optarg;
45225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_device_index++;
45235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_loadvm:
45255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		loadvm = optarg;
45265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
45275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_full_screen:
45285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                full_screen = 1;
45295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
45315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_frame:
45325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_frame = 1;
45335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_alt_grab:
45355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                alt_grab = 1;
45365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_quit:
45385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_quit = 1;
45395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sdl:
45415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_SDL;
45425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pidfile:
45455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pid_file = optarg;
45465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
45485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_win2k_hack:
45495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                win2k_install_hack = 1;
45505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_rtc_td_hack:
45525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_td_hack = 1;
45535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_acpitable:
45555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(acpi_table_add(optarg) < 0) {
45565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Wrong acpi table provided\n");
45575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smbios:
45615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(smbios_entry_add(optarg) < 0) {
45625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Wrong smbios provided\n");
45635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
45685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_kqemu:
45695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 0;
45705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_kernel_kqemu:
45725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 2;
45735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KVM
45765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_enable_kvm:
45775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kvm_allowed = 1;
45785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
45795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 0;
45805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usb:
45845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
45855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usbdevice:
45875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
45885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (usb_devices_index >= MAX_USB_CMDLINE) {
45895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Too many USB devices\n");
45905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
45915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
45925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices[usb_devices_index] = optarg;
45935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices_index++;
45945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smp:
45965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                smp_cpus = atoi(optarg);
45975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (smp_cpus < 1) {
45985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Invalid number of CPUs\n");
45995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
46005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
46015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_vnc:
46035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_VNC;
46045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		vnc_display = optarg;
46055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
46065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
46075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_acpi:
46085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                acpi_enabled = 0;
46095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_hpet:
46115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_hpet = 1;
46125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_virtio_balloon:
46145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_virtio_balloon = 1;
46155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_reboot:
46185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_reboot = 1;
46195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_shutdown:
46215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 1;
46225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_show_cursor:
46245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cursor_hide = 0;
46255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_uuid:
46275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
46285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Fail to parse UUID string."
46295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            " Wrong format.\n");
46305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
46315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
46325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
46345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_daemonize:
46355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		daemonize = 1;
46365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
46375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_option_rom:
46395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (nb_option_roms >= MAX_OPTION_ROMS) {
46405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    fprintf(stderr, "Too many option ROMs\n");
46415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    exit(1);
46425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
46435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		option_rom[nb_option_roms] = optarg;
46445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		nb_option_roms++;
46455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
46465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ARM) || defined(TARGET_M68K)
46475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_semihosting:
46485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                semihosting_enabled = 1;
46495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_name:
46525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_name = optarg;
46535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
46555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_prom_env:
46565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_prom_envs >= MAX_PROM_ENVS) {
46575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Too many prom variables\n");
46585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
46595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
46605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                prom_envs[nb_prom_envs] = optarg;
46615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_prom_envs++;
46625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
46655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_old_param:
46665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                old_param = 1;
46675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_clock:
46705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                configure_alarms(optarg);
46715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
46725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_startdate:
46735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
46745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    struct tm tm;
46755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    time_t rtc_start_date;
46765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!strcmp(optarg, "now")) {
46775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = -1;
46785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
46795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
46805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_year,
46815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mon,
46825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mday,
46835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_hour,
46845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_min,
46855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_sec) == 6) {
46865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            /* OK */
46875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else if (sscanf(optarg, "%d-%d-%d",
46885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_year,
46895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mon,
46905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mday) == 3) {
46915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_hour = 0;
46925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_min = 0;
46935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_sec = 0;
46945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else {
46955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto date_fail;
46965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
46975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_year -= 1900;
46985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_mon--;
46995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_start_date = mktimegm(&tm);
47005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (rtc_start_date == -1) {
47015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        date_fail:
47025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr, "Invalid date format. Valid format are:\n"
47035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
47045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
47055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
47065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = time(NULL) - rtc_start_date;
47075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
47085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
47095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tb_size:
47115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tb_size = strtol(optarg, NULL, 0);
47125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (tb_size < 0)
47135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tb_size = 0;
47145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_icount:
47166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner                icount_option = optarg;
47175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_incoming:
47195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                incoming = optarg;
47205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
47225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_chroot:
47235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                chroot_dir = optarg;
47245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_runas:
47265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                run_as = optarg;
47275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_XEN
47305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_domid:
47315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_domid = atoi(optarg);
47325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_create:
47345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_CREATE;
47355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_attach:
47375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_ATTACH;
47385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mic:
47435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                audio_input_source = (char*)optarg;
47445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
4746a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner            case QEMU_OPTION_trace:
47475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_filename = optarg;
47485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tracing = 1;
47495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
47515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_miss:
47525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_cache_miss = 1;
47535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_addr:
47555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_all_addr = 1;
47565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tracing:
47595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strcmp(optarg, "off") == 0)
47605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 0;
47615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else if (strcmp(optarg, "on") == 0 && trace_filename)
47625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 1;
47635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else {
47645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Unexpected option to -tracing ('%s')\n",
47655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            optarg);
47665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
47675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
47685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
47705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_load_miss:
47715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_load_miss_penalty = atoi(optarg);
47725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_store_miss:
47745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_store_miss_penalty = atoi(optarg);
47755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_NAND
47795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nand:
47805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nand_add_dev(optarg);
47815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
47825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4783d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_ports:
4784d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_ports = (char*)optarg;
4785d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
4786d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
4787d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_port:
4788d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_port = (char*)optarg;
4789d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
4790d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
4791d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_report_console:
4792d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_report_console = (char*)optarg;
4793d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
4794d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
4795d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_http_proxy:
4796d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                op_http_proxy = (char*)optarg;
4797d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
479843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
479943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            case QEMU_OPTION_charmap:
480043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                op_charmap_file = (char*)optarg;
480143552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                break;
4802dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
4803dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            case QEMU_OPTION_android_gui:
4804dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                android_op_gui = (char*)optarg;
4805dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                break;
4806074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
4807074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine            case QEMU_OPTION_android_hw:
4808074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                android_op_hwini = (char*)optarg;
4809074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                break;
481013f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine
48117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            case QEMU_OPTION_dns_server:
48127fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                android_op_dns_server = (char*)optarg;
48137fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                break;
48147fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
4815b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_radio:
4816b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_radio = (char*)optarg;
4817b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4818b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4819b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_gps:
4820b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_gps = (char*)optarg;
4821b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4822b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4823b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio:
4824b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio = (char*)optarg;
4825b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4826b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4827b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio_in:
4828b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio_in = (char*)optarg;
4829b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4830b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4831b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio_out:
4832b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio_out = (char*)optarg;
4833b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4834b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4835b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_cpu_delay:
4836b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_cpu_delay = (char*)optarg;
4837b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
4838b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
483913f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine            case QEMU_OPTION_show_kernel:
484013f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine                android_kmsg_init(ANDROID_KMSG_PRINT_MESSAGES);
484113f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine                break;
484213f3b6c53817255217f40db289abace42c3c31a6Vladimir Chtchetkine
4843e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
4844e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_nand_limits:
4845e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_nand_limits = (char*)optarg;
4846e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
4847e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
4848e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4849e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netspeed:
4850e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netspeed = (char*)optarg;
4851e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
4852e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4853e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netdelay:
4854e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netdelay = (char*)optarg;
4855e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
4856e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4857e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine            case QEMU_OPTION_netfast:
4858e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netfast = 1;
4859e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                break;
4860e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4861318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine            case QEMU_OPTION_tcpdump:
4862318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine                android_op_tcpdump = (char*)optarg;
4863318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine                break;
4864e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4865b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            case QEMU_OPTION_boot_property:
4866b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                boot_property_parse_option((char*)optarg);
4867b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                break;
4868b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
4869b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            case QEMU_OPTION_lcd_density:
4870b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                android_op_lcd_density = (char*)optarg;
4871b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                break;
4872b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
4873b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
4874b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine            case QEMU_OPTION_android_memcheck:
4875b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                android_op_memcheck = (char*)optarg;
48767fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                snprintf(tmp_str, sizeof(tmp_str), "memcheck=%s",
48777fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                         android_op_memcheck);
48787fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                tmp_str[sizeof(tmp_str) - 1] = '\0';
48797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                /* This will set ro.kernel.memcheck system property
48807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                 * to memcheck's tracing flags. */
48817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
4882b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                break;
4883b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif // CONFIG_MEMCHECK
48845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
48855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
48865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
48875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
488843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    /* Initialize character map. */
488943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (android_charmap_setup(op_charmap_file)) {
489043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        if (op_charmap_file) {
489143552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            fprintf(stderr,
489243552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    "Unable to initialize character map from file %s.\n",
489343552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    op_charmap_file);
489443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        } else {
489543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            fprintf(stderr,
489643552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    "Unable to initialize default character map.\n");
489743552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        }
489843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        exit(1);
489943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
490043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
49015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If no data_dir is specified then try to find it relative to the
49025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       executable path.  */
49035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
49045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = find_datadir(argv[0]);
49055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If all else fails use the install patch specified when building.  */
49075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
49085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = CONFIG_QEMU_SHAREDIR;
49095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4911074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
4912074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    /* Initialize hardware configuration. */
4913074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    if (android_op_hwini) {
4914074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      hw_ini = iniFile_newFromFile(android_op_hwini);
4915074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      if (hw_ini == NULL) {
4916074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine        fprintf(stderr, "Could not find %s file.\n", android_op_hwini);
4917074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine        exit(1);
4918074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      }
4919074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    } else {
4920074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      hw_ini = iniFile_newFromMemory("", 0);
4921074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    }
4922074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
4923074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    androidHwConfig_read(android_hw, hw_ini);
4924074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    iniFile_free(hw_ini);
4925074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
4926074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
4927e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
4928e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    /* Init nand stuff. */
4929e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_op_nand_limits) {
4930e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        parse_nand_limits(android_op_nand_limits);
4931e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
4932e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif  // CONFIG_NAND_LIMITS
4933e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4934b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Set the VM's max heap size, passed as a boot property */
4935b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (android_hw->vm_heapSize > 0) {
4936b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        char  tmp[64];
4937b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        snprintf(tmp, sizeof(tmp), "%dm", android_hw->vm_heapSize);
4938b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        boot_property_add("dalvik.vm.heapsize",tmp);
4939b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
4940b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
4941e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    /* Initialize net speed and delays stuff. */
4942e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_parse_network_speed(android_op_netspeed) < 0 ) {
4943e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        fprintf(stderr, "invalid -netspeed parameter '%s'\n",
4944e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netspeed);
4945e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        exit(1);
4946e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
4947e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4948e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
4949e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        fprintf(stderr, "invalid -netdelay parameter '%s'\n",
4950e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine                android_op_netdelay);
4951e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        exit(1);
4952e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
4953e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4954e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (android_op_netfast) {
4955e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_download_speed = 0;
4956e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_upload_speed = 0;
4957e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_min_latency = 0;
4958e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        qemu_net_max_latency = 0;
4959e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
4960e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
4961b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Initialize LCD density */
4962b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (android_op_lcd_density) {
4963b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        char*   end;
4964b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        long density = strtol(android_op_lcd_density, &end, 0);
4965b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        if (end == NULL || *end || density < 0) {
4966b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            fprintf(stderr, "option -lcd-density must be a positive integer\n" );
4967b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            exit(1);
4968b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        }
4969b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        hwLcd_setBootProperty(density);
4970b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
4971b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
4972318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    /* Initialize TCP dump */
4973318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    if (android_op_tcpdump) {
4974318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        if (qemu_tcpdump_start(android_op_tcpdump) < 0) {
4975318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine            fprintf(stdout, "could not start packet capture: %s\n", strerror(errno));
4976318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        }
4977318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    }
4978318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
4979b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize modem */
4980b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_radio) {
4981b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("radio", android_op_radio, NULL);
4982b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
4983b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "unsupported character device specification: %s\n"
4984b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                            "used -help-char-devices for list of available formats\n",
4985b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_radio);
4986b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
4987b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
4988b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
4989b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gsmModem != 0 ) {
4990b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
4991b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "could not initialize qemud 'gsm' channel");
4992b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
4993b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
4994b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
4995b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4996b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize GPS */
4997b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_gps) {
4998b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("gps", android_op_gps, NULL);
4999b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
5000b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "unsupported character device specification: %s\n"
5001b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                            "used -help-char-devices for list of available formats\n",
5002b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_gps);
5003b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5004b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5005b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
5006b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gps != 0) {
5007b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
5008b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "could not initialize qemud 'gps' channel" );
5009b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5010b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5011b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5012b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5013b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize audio. */
5014b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio) {
5015b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (android_op_audio_in || android_op_audio_out) {
5016b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "you can't use -audio with -audio-in or -audio-out\n" );
5017b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5018b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5019b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 0, android_op_audio ) ) {
5020b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
5021b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio);
5022b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5023b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5024b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_op_audio_out = android_op_audio;
5025b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_op_audio_in  = android_op_audio;
5026b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5027b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 1, android_op_audio ) ) {
5028b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout,
5029b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    "emulator: warning: '%s' is not a valid audio input backend. audio record disabled\n",
5030b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio);
5031b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            android_op_audio_in = "none";
5032b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5033b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5034b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5035b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio_in) {
5036b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        static char  env[64]; /* note: putenv needs a static unique string buffer */
5037b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 1, android_op_audio_in ) ) {
5038b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio input backend. see -help-audio-in\n",
5039b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio_in);
5040b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5041b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5042b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        bufprint( env, env+sizeof(env), "QEMU_AUDIO_IN_DRV=%s", android_op_audio_in );
5043b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        putenv( env );
5044b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5045b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (!android_hw->hw_audioInput) {
5046b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout, "Emulated hardware doesn't have audio input.\n");
5047b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5048b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5049b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio_out) {
5050b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        static char  env[64]; /* note: putenv needs a static unique string buffer */
5051b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 0, android_op_audio_out ) ) {
5052b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
5053b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio_out);
5054b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5055b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5056b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        bufprint( env, env+sizeof(env), "QEMU_AUDIO_OUT_DRV=%s", android_op_audio_out );
5057b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        putenv( env );
5058b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (!android_hw->hw_audioOutput) {
5059b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout, "Emulated hardware doesn't have audio output\n");
5060b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5061b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5062b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5063b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_cpu_delay) {
5064b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        char*   end;
5065b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        long    delay = strtol(android_op_cpu_delay, &end, 0);
5066b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (end == NULL || *end || delay < 0 || delay > 1000 ) {
5067b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "option -cpu-delay must be an integer between 0 and 1000\n" );
5068b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5069b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5070b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (delay > 0)
5071b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            delay = (1000-delay);
5072b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5073b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        qemu_cpu_delay = (int) delay;
5074b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5075b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
50767fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (android_op_dns_server) {
50777fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        char*  x = strchr(android_op_dns_server, ',');
50787fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = 0;
50797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (x == NULL)
50807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
50817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            if ( add_dns_server( android_op_dns_server ) == 0 )
50827fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                dns_count = 1;
50837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
50847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        else
50857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
50867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            x = android_op_dns_server;
50877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            while (*x) {
50887fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                char*  y = strchr(x, ',');
50897fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y != NULL) {
50917fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    *y = 0;
50927fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y++;
50937fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                } else {
50947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y = x + strlen(x);
50957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
50967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y > x && add_dns_server( x ) == 0) {
50987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    dns_count += 1;
50997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
51007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                x = y;
51017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            }
51027fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
51037fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (dns_count == 0)
51047fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            fprintf( stdout, "### WARNING: will use system default DNS server\n" );
51057fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
51067fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
51077fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count == 0)
51087fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = slirp_get_system_dns_servers();
51097fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count) {
51107fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        snprintf(tmp_str, sizeof(tmp_str), "android.ndns=%d", dns_count);
51117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
51127fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
51137fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
5114b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
5115b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (android_op_memcheck) {
5116b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        memcheck_init(android_op_memcheck);
5117b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
5118b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
5119b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
51205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
51215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_allowed && kqemu_allowed) {
51225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr,
51235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "You can not enable both KVM and kqemu at the same time\n");
51245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
51255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
51275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
51295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > machine->max_cpus) {
51305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
51315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
51325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine->max_cpus);
51335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
51345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC) {
51375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (serial_device_index == 0)
51385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           serial_devices[0] = "stdio";
51395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (parallel_device_index == 0)
51405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           parallel_devices[0] = "null";
51415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strncmp(monitor_device, "vc", 2) == 0)
51425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           monitor_device = "stdio";
51435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
51465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
51475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid_t pid;
51485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pipe(fds) == -1)
51505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
51515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid = fork();
51535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pid > 0) {
51545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    uint8_t status;
51555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    ssize_t len;
51565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    close(fds[1]);
51585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	again:
51605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len = read(fds[0], &status, 1);
51615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len == -1 && (errno == EINTR))
51625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto again;
51635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len != 1)
51655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
51665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else if (status == 1) {
51675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Could not acquire pidfile\n");
51685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
51695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
51705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(0);
51715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (pid < 0)
51725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
51735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	setsid();
51755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid = fork();
51775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pid > 0)
51785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(0);
51795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else if (pid < 0)
51805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
51815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	umask(027);
51835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTSTP, SIG_IGN);
51855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTTOU, SIG_IGN);
51865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTTIN, SIG_IGN);
51875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
51905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (daemonize) {
51915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t status = 1;
51925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            write(fds[1], &status, 1);
51935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
51945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Could not acquire pid file\n");
51955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
51965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
51985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
52005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > 1)
52015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_allowed = 0;
52025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
52035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_init_main_loop()) {
52045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu_init_main_loop failed\n");
52055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
52065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    linux_boot = (kernel_filename != NULL);
52085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
52095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && *kernel_cmdline != '\0') {
52115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-append only allowed with -kernel option\n");
52125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
52135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && initrd_filename != NULL) {
52165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-initrd only allowed with -kernel option\n");
52175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
52185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* boot to floppy or the default cd if no hard disk defined yet */
52215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!boot_devices[0]) {
52225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        boot_devices = "cad";
52235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    setvbuf(stdout, NULL, _IOLBF, 0);
52255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (init_timer_alarm() < 0) {
52275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "could not initialize alarm timer\n");
52285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
52295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    configure_icount(icount_option);
52315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
52335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    socket_init();
52345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
52355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init network clients */
52375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_net_clients == 0) {
52385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if no clients, we use a default config */
52395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "nic";
52405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
52415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "user";
52425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
52435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0;i < nb_net_clients; i++) {
52465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (net_client_parse(net_clients[i]) < 0)
52475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
52485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_client_check();
52505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
52525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: this should be moved in the PC machine instantiation code */
52535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (net_boot != 0) {
52545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int netroms = 0;
52555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (i = 0; i < nb_nics && i < 4; i++) {
52565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    const char *model = nd_table[i].model;
52575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    char buf[1024];
52585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char *filename;
52595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (net_boot & (1 << i)) {
52605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (model == NULL)
52615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    model = "ne2k_pci";
52625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
52635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
52645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename && get_image_size(filename) > 0) {
52655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (nb_option_roms >= MAX_OPTION_ROMS) {
52665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "Too many option ROMs\n");
52675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
52685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
52695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    option_rom[nb_option_roms] = qemu_strdup(buf);
52705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    nb_option_roms++;
52715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    netroms++;
52725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename) {
52745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    qemu_free(filename);
52755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
52775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
52785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (netroms == 0) {
52795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "No valid PXE rom found for network device\n");
52805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
52815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
52825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
52835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
52845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the bluetooth world */
52865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < nb_bt_opts; i++)
52875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bt_parse(bt_opts[i]))
52885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
52895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the memory */
52915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ram_size == 0)
52925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
52935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
52955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
52965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       guest ram allocation.  It needs to go away.  */
52975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kqemu_allowed) {
52985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
52995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
53005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!kqemu_phys_ram_base) {
53015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Could not allocate physical memory\n");
53025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
53035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
53055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
53065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the dynamic translator */
53085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_exec_init_all(tb_size * 1024 * 1024);
53095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_init();
53115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create the cdrom drive, even if no disk is there */
53135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
53155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, CDROM_ALIAS);
53165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create at least one floppy */
53185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
53205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, FD_ALIAS, 0);
53215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create one sd slot, even if no card is in it */
53235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
53255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, SD_ALIAS);
53265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* open the virtual block devices */
53285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < nb_drives_opt; i++)
53305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drive_init(&drives_opt[i], snapshot, machine) == -1)
53315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
53325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner    //register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
53345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
53355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
53375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* must be after terminal init, SDL library changes signal handlers */
53385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sighandler_setup();
53395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
53405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Maintain compatibility with multiple stdio monitors */
53425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(monitor_device,"stdio")) {
53435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
53445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const char *devname = serial_devices[i];
53455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (devname && !strcmp(devname,"mon:stdio")) {
53465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
53475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else if (devname && !strcmp(devname,"stdio")) {
53495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
53505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[i] = "mon:stdio";
53515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
53535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
53555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_numa_nodes > 0) {
53575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int i;
53585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (nb_numa_nodes > smp_cpus) {
53605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_numa_nodes = smp_cpus;
53615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* If no memory size if given for any node, assume the default case
53645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * and distribute the available memory equally across all nodes
53655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
53665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
53675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_mem[i] != 0)
53685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
53715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint64_t usedmem = 0;
53725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* On Linux, the each node's border has to be 8MB aligned,
53745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             * the final node gets the rest.
53755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             */
53765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < nb_numa_nodes - 1; i++) {
53775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
53785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usedmem += node_mem[i];
53795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
53805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[i] = ram_size - usedmem;
53815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
53845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] != 0)
53855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* assigning the VCPUs round-robin is easier to implement, guest OSes
53885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * must cope with this anyway, because there are BIOSes out there in
53895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * real machines which also use this scheme.
53905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
53915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
53925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < smp_cpus; i++) {
53935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_cpumask[i % nb_numa_nodes] |= 1 << i;
53945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
53955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
53975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
53985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
53995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
54005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_init(smp_cpus);
54025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
54035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "failed to initialize KVM\n");
54045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
54055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device) {
54095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
54105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!monitor_hd) {
54115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
54125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
54135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
54175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = serial_devices[i];
54185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
54195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
54205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "serial%d", i);
54215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            serial_hds[i] = qemu_chr_open(label, devname, NULL);
54225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!serial_hds[i]) {
54235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open serial device '%s'\n",
54245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
54255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
54265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
54275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
54315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
54325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
54335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
54345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "parallel%d", i);
54355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            parallel_hds[i] = qemu_chr_open(label, devname, NULL);
54365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!parallel_hds[i]) {
54375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
54385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
54395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
54405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
54415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
54455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
54465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
54475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
54485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "virtcon%d", i);
54495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
54505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!virtcon_hds[i]) {
54515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open virtio console '%s'\n",
54525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
54535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
54545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
54555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_DEVICE);
54595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
54625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (trace_filename) {
54635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        trace_init(trace_filename);
54645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
54655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        // We don't need the dcache code until we can get load and store tracing
54665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        // working again.
54675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcache_init(dcache_size, dcache_ways, dcache_line_size,
54685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dcache_replace_policy, dcache_load_miss_penalty,
54695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dcache_store_miss_penalty);
54705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
54725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
54735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54757fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Combine kernel command line passed from the UI with parameters
54767fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * collected during initialization. */
54777fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (*kernel_cmdline) {
54787fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (kernel_cmdline_append[0]) {
54797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            snprintf(kernel_cmdline_full, sizeof(kernel_cmdline_full), "%s %s",
54807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                     kernel_cmdline, kernel_cmdline_append);
54817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        } else {
54827fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            strncpy(kernel_cmdline_full, kernel_cmdline, sizeof(kernel_cmdline_full));
54837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            kernel_cmdline_full[sizeof(kernel_cmdline_full) - 1] = '\0';
54847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
54857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    } else if (kernel_cmdline_append[0]) {
54867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncpy(kernel_cmdline_full, kernel_cmdline_append, sizeof(kernel_cmdline_full));
54877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
54887fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
54895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine->init(ram_size, boot_devices,
54907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                  kernel_filename, kernel_cmdline_full, initrd_filename, cpu_model);
54915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu) {
54945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
54955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] & (1 << env->cpu_index)) {
54965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->numa_node = i;
54975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
54985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
54995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
55005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    current_machine = machine;
55025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Set KVM's vcpu state to qemu's initial CPUState. */
55045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
55055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
55065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_sync_vcpus();
55085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
55095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "failed to initialize vcpus\n");
55105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
55115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
55125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
55135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init USB devices */
55155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (usb_enabled) {
55165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(i = 0; i < usb_devices_index; i++) {
55175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (usb_device_add(usb_devices[i], 0) < 0) {
55185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Warning: could not add USB device %s\n",
55195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        usb_devices[i]);
55205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
55215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
55225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
55235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5524dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (!display_state) {
5525dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        if (android_op_gui) {
5526dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            /* Initialize display from the command line parameters. */
5527dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            if (parse_androig_gui_option(android_op_gui,
5528dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_width,
5529dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_height,
5530dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_bpp)) {
5531dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                exit(1);
5532dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            }
5533dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            android_display_init_from(android_display_width,
5534dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                      android_display_height, 0,
5535dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                      android_display_bpp);
5536dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        } else {
5537dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            dumb_display_init();
5538dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        }
5539dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else if (android_op_gui) {
5540dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        /* Resize display from the command line parameters. */
5541dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        if (parse_androig_gui_option(android_op_gui,
5542dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_width,
5543dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_height,
5544dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_bpp)) {
5545dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            exit(1);
5546dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        }
5547dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        display_state->surface = qemu_resize_displaysurface(display_state,
5548dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                                            android_display_width,
5549dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                                            android_display_height);
5550dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
5551dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
55525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* just use the first displaystate for the moment */
55535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds = display_state;
55545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_DEFAULT) {
55565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
55575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_SDL;
55585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
55595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_VNC;
55605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display = "localhost:0,to=99";
55615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        show_vnc_port = 1;
55625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
55635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5564d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
55655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (display_type) {
55675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_NOGRAPHIC:
55685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_CURSES)
55705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_CURSES:
55715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        curses_display_init(ds, full_screen);
55725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5574eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
55755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
55765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sdl_display_init(ds, full_screen, no_frame);
55775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(CONFIG_COCOA)
55795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
55805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cocoa_display_init(ds, full_screen);
55815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
55835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_VNC:
55845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display_init(ds);
55855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vnc_display_open(ds, vnc_display) < 0)
55865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
55875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (show_vnc_port) {
55895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
55905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
55915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
55935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
55945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
55955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_resize(ds);
55965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dcl = ds->listeners;
55985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
55995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->dpy_refresh != NULL) {
56005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
56015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
56025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
56035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
56045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
56075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
56085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
56095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    text_consoles_set_display(display_state);
56125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_chr_initial_reset();
56135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device && monitor_hd)
56155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
56165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
56185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = serial_devices[i];
56195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
56205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
56215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
56225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
56235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
56265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
56275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
56285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
56295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
56305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
56315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
56345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
56355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (virtcon_hds[i] && devname) {
56365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
56375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
56385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
56395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
56425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
56435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev);
56445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
56455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (loadvm)
56485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        do_loadvm(cur_mon, loadvm);
56495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* call android-specific setup function */
56515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_setup();
56525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (incoming) {
56545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0; /* fixme how to deal with -daemonize */
56555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_start_incoming_migration(incoming);
56565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (autostart)
56595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_start();
56605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
56625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
56635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	uint8_t status = 0;
56645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ssize_t len;
56655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    again1:
56675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	len = write(fds[1], &status, 1);
56685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (len == -1 && (errno == EINTR))
56695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    goto again1;
56705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (len != 1)
56725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
56735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5674a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (chdir("/")) {
5675a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            perror("not able to chdir to /");
5676a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            exit(1);
5677a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        }
56785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	TFR(fd = open("/dev/null", O_RDWR));
56795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (fd == -1)
56805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
56815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (run_as) {
56845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pwd = getpwnam(run_as);
56855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!pwd) {
56865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
56875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
56885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
56895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
56905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
56915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (chroot_dir) {
56925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (chroot(chroot_dir) < 0) {
56935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "chroot failed\n");
56945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
56955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
5696a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (chdir("/")) {
5697a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            perror("not able to chdir to /");
5698a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            exit(1);
5699a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        }
57005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
57015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
57025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (run_as) {
57035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setgid(pwd->pw_gid) < 0) {
57045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
57055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
57065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
57075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setuid(pwd->pw_uid) < 0) {
57085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
57095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
57105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
57115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setuid(0) != -1) {
57125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Dropping privileges failed\n");
57135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
57145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
57155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
57165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
57175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
57185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 0);
57195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 1);
57205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 2);
57215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
57225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        close(fd);
57235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
57245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
57255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
57265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    main_loop();
57275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    quit_timers();
57285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_cleanup();
57295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_teardown();
57305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
57315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5732eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
5733eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkinevoid
5734eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineandroid_emulation_teardown(void)
5735eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine{
5736eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine    android_charmap_done();
5737eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine}
5738