vl-android.c revision b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08c
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"
605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
62b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#include "memcheck/memcheck.h"
63b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
64b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <unistd.h>
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <fcntl.h>
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <signal.h>
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <time.h>
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <errno.h>
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/time.h>
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <zlib.h>
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
732c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner/* Needed early for CONFIG_BSD etc. */
745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "config-host.h"
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libgen.h>
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <pwd.h>
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/times.h>
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/wait.h>
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <termios.h>
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/mman.h>
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ioctl.h>
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/resource.h>
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/socket.h>
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__NetBSD__)
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if_tap.h>
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/if_tun.h>
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <arpa/inet.h>
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <dirent.h>
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netdb.h>
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/select.h>
982c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner#ifdef CONFIG_BSD
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__FreeBSD__) || defined(__DragonFly__)
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libutil.h>
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <freebsd/stdlib.h>
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <pty.h>
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/rtc.h>
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* For the benefit of older linux systems which don't supply it,
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   we use a local copy of hpet.h. */
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #include <linux/hpet.h> */
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hpet.h"
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/ppdev.h>
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <linux/parport.h>
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __sun__
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/stat.h>
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/ethernet.h>
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/sockio.h>
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/arp.h>
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in.h>
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/in_systm.h>
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip.h>
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/ip_icmp.h> // must come after ip.h
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/udp.h>
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <netinet/tcp.h>
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <net/if.h>
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <syslog.h>
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <stropts.h>
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__OpenBSD__)
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <util.h>
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_VDE)
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <libvdeplug.h>
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <windows.h>
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <malloc.h>
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <sys/timeb.h>
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <mmsystem.h>
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define getopt_long_only getopt_long
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define memalign(align, size) malloc(size)
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_COCOA
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_COCOA */
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/hw.h"
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/boards.h"
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/usb.h"
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pcmcia.h"
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/pc.h"
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/audiodev.h"
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/isa.h"
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/baum.h"
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/bt.h"
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/watchdog.h"
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/smbios.h"
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/xen.h"
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "bt-host.h"
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "net.h"
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "console.h"
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "sysemu.h"
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "gdbstub.h"
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-timer.h"
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-char.h"
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "cache-utils.h"
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block.h"
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "dma.h"
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio/audio.h"
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "migration.h"
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "kvm.h"
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "balloon.h"
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
190eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
191eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine/* Verbose value used by the standalone emulator core (without UI) */
192eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineunsigned long   android_verbose;
193eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
194eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
19543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE)
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef main
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define main qemu_main
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "disas.h"
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "exec-all.h"
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "trace.h"
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "dcache.h"
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu_socket.h"
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "libslirp.h"
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_UNUSED_IOPORT
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_IOPORT
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_NET
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_SLIRP
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_IOPORT
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  define LOG_IOPORT(...) do { } while (0)
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFAULT_RAM_SIZE 128
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of USB devices that can be specified on the commandline.  */
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_USB_CMDLINE 8
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Max number of bluetooth switches on the commandline.  */
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_BT_CMDLINE 10
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: use a two level table to limit memory usage */
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const char *data_dir;
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *bios_name = NULL;
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *ioport_opaque[MAX_IOPORTS];
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   to store the VM snapshots */
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDriveInfo drives_table[MAX_DRIVES+1];
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives;
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic DisplayState *display_state;
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayType display_type = DT_DEFAULT;
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char* keyboard_layout = NULL;
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t ticks_per_sec;
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t ram_size;
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_nics;
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerNICInfo nd_table[MAX_NICS];
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vm_running;
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int autostart;
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_utc = 1;
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_date_offset = -1; /* -1 means no change */
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cirrus_vga_enabled = 1;
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint std_vga_enabled = 0;
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint vmsvga_enabled = 0;
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint xenfb_enabled = 0;
262a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' TurnerQEMUClock *rtc_clock;
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_SPARC
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_width = 1024;
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_height = 768;
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_depth = 8;
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_width = 800;
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_height = 600;
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_depth = 15;
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int full_screen = 0;
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int no_frame = 0;
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_quit = 0;
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *serial_hds[MAX_SERIAL_PORTS];
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerCharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint win2k_install_hack = 0;
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint rtc_td_hack = 0;
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_enabled = 0;
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint singlestep = 0;
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint smp_cpus = 1;
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *vnc_display;
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint acpi_enabled = 1;
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_hpet = 0;
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_virtio_balloon = 0;
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint fd_bootchk = 1;
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_reboot = 0;
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint no_shutdown = 0;
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint cursor_hide = 1;
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint graphic_rotate = 0;
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint daemonize = 0;
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerWatchdogTimerModel *watchdog = NULL;
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint watchdog_action = WDT_RESET;
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *option_rom[MAX_OPTION_ROMS];
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_option_roms;
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint semihosting_enabled = 0;
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint old_param = 0;
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *qemu_name;
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint alt_grab = 0;
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerunsigned int nb_prom_envs = 0;
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *prom_envs[MAX_PROM_ENVS];
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_drives_opt;
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct drive_opt drives_opt[MAX_DRIVES];
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint nb_numa_nodes;
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_mem[MAX_NODES];
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t node_cpumask[MAX_NODES];
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic CPUState *cur_cpu;
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic CPUState *next_cpu;
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int timer_alarm_pending = 1;
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Conversion factor from emulated instructions to virtual clock ticks.  */
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int icount_time_shift;
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_ICOUNT_SHIFT 10
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Compensate for varying guest execution speed.  */
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t qemu_icount_bias;
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUTimer *icount_rt_timer;
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUTimer *icount_vm_timer;
3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUTimer *nographic_timer;
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint8_t qemu_uuid[16];
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
336b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkineint   qemu_cpu_delay;
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern char* audio_input_source;
3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
339d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_ports;
340d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_port;
341d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* android_op_report_console;
342d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkineextern char* op_http_proxy;
34343552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine// Path to the file containing specific key character map.
34443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkinechar* op_charmap_file = NULL;
345d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
346dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine/* Framebuffer dimensions, passed with -android-gui option. */
347dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinechar* android_op_gui = NULL;
348dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
349074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine/* Path to hardware initialization file passed with -android-hw option. */
350074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkinechar* android_op_hwini = NULL;
351074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
352b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine/* Memory checker options. */
353b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkinechar* android_op_memcheck = NULL;
354b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
3557fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine/* -dns-server option value. */
3567fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinechar* android_op_dns_server = NULL;
3577fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
358b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_radio = NULL;
359b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
360b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -gps option value. */
361b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_gps = NULL;
362b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
363b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio option value. */
364b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio = NULL;
365b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
366b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio-in option value. */
367b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio_in = NULL;
368b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
369b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -audio-out option value. */
370b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_audio_out = NULL;
371b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
372b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine/* -cpu-delay option value. */
373b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkinechar* android_op_cpu_delay = NULL;
374b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
375dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_width;
376dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_height;
377dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineextern int android_display_bpp;
378dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern void  dprint( const char* format, ... );
3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* x86 ISA bus support */
3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertarget_phys_addr_t isa_mem_base = 0;
3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerPicState2 *isa_pic;
3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t ioport_read(int index, uint32_t address)
3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortReadFunc *default_func[3] = {
3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readb,
3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readw,
3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_readl
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortReadFunc *func = ioport_read_table[index][address];
4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return func(ioport_opaque[address], address);
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void ioport_write(int index, uint32_t address, uint32_t data)
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static IOPortWriteFunc *default_func[3] = {
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writeb,
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writew,
4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default_ioport_writel
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    };
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOPortWriteFunc *func = ioport_write_table[index][address];
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!func)
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        func = default_func[index];
4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    func(ioport_opaque[address], address, data);
4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readb(void *opaque, uint32_t address)
4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inb: port=0x%04x\n", address);
4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xff;
4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* default is to make two byte accesses */
4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readw(void *opaque, uint32_t address)
4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t data;
4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data = ioport_read(0, address);
4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data |= ioport_read(0, address) << 8;
4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return data;
4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, data & 0xff);
4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    address = (address + 1) & (MAX_IOPORTS - 1);
4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioport_write(0, address, (data >> 8) & 0xff);
4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t default_ioport_readl(void *opaque, uint32_t address)
4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused inl: port=0x%04x\n", address);
4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0xffffffff;
4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_UNUSED_IOPORT
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
465dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine/* Parses -android-gui command line option, extracting width, height and bits
466dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * per pixel parameters for the GUI console used in this session of the
467dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * emulator. -android-gui option contains exactly three comma-separated positive
468dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * integer numbers in strict order: width goes first, width goes next, and bits
469dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * per pixel goes third. This routine verifies that format and return 0 if all
470dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * three numbers were extracted, or -1 if string format was incorrect for that
471dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * option. Note that this routine does not verify that extracted values are
472dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine * correct!
473dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine */
474dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinestatic int
475dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineparse_androig_gui_option(const char* op, int* width, int* height, int* bpp)
476dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine{
477dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    char val[128];
478dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
479dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "width", op)) {
480dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *width = strtol(val, NULL, 0);
481dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
482dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing width parameter\n");
483dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
484dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
485dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "height", op)) {
486dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *height = strtol(val, NULL, 0);
487dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
488dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing height parameter\n");
489dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
490dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
491dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (get_param_value(val, 128, "bpp", op)) {
492dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        *bpp = strtol(val, NULL, 0);
493dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else {
494dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        fprintf(stderr, "option -android-gui is missing bpp parameter\n");
495dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        return -1;
496dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
497dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
498dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    return 0;
499dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine}
500dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid hw_error(const char *fmt, ...)
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_list ap;
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_start(ap, fmt);
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: hardware error: ");
5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vfprintf(stderr, fmt, ap);
5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "\n");
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(env = first_cpu; env != NULL; env = env->next_cpu) {
5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_dump_state(env, stderr, fprintf, 0);
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    va_end(ap);
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    abort();
5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
522d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
523a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerstatic void set_proc_name(const char *s)
524a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner{
525a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#if defined(__linux__) && defined(PR_SET_NAME)
526a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    char name[16];
527a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!s)
528a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return;
529a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    name[sizeof(name) - 1] = 0;
530a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    strncpy(name, s, sizeof(name));
531a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    /* Could rewrite argv[0] too, but that's a bit more complicated.
532a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner       This simple way is enough for `top'. */
533a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    prctl(PR_SET_NAME, name);
534d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine#endif
535a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner}
536d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
5375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***************/
5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ballooning */
5395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUBalloonEvent *qemu_balloon_event;
5415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid *qemu_balloon_event_opaque;
5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event = func;
5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_balloon_event_opaque = opaque;
5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_balloon(ram_addr_t target)
5505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_balloon_event(qemu_balloon_event_opaque, target);
5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerram_addr_t qemu_balloon_status(void)
5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_balloon_event)
5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_balloon_event(qemu_balloon_event_opaque, 0);
5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* keyboard/mouse */
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutKBDEvent*  qemu_put_kbd_event;
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void*             qemu_put_kbd_event_opaque;
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutMouseEntry *qemu_put_mouse_event_head;
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUPutMouseEntry *qemu_put_mouse_event_current;
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_kbd_event_opaque = opaque;
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_kbd_event = func;
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_opaque = opaque;
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event = func;
5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_absolute = absolute;
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                void *opaque, int absolute,
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                const char *name)
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *s, *cursor;
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!s)
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event = func;
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_opaque = opaque;
5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_absolute = absolute;
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->qemu_put_mouse_event_name = qemu_strdup(name);
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->next = NULL;
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return s;
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor->next != NULL)
6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor->next = s;
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_mouse_event_current = s;
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return s;
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *prev = NULL, *cursor;
6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head || entry == NULL)
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL && cursor != entry) {
6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        prev = cursor;
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cursor == NULL) // does not exist or list empty
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (prev == NULL) { // entry is head
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_head = cursor->next;
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_put_mouse_event_current == entry)
6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_put_mouse_event_current = cursor->next;
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(entry->qemu_put_mouse_event_name);
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(entry);
6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    prev->next = entry->next;
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_put_mouse_event_current == entry)
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current = prev;
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(entry->qemu_put_mouse_event_name);
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(entry);
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid kbd_put_keycode(int keycode)
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_put_kbd_event) {
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEvent *mouse_event;
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *mouse_event_opaque;
6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int width;
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_current) {
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    mouse_event =
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current->qemu_put_mouse_event;
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    mouse_event_opaque =
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (mouse_event) {
6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (graphic_rotate) {
6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                width = 0x7fff;
6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                width = graphic_width - 1;
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            mouse_event(mouse_event_opaque,
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 width - dy, dx, dz, buttons_state);
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            mouse_event(mouse_event_opaque,
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 dx, dy, dz, buttons_state);
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint kbd_mouse_is_absolute(void)
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_current)
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_info_mice(Monitor *mon)
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *cursor;
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index = 0;
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No mouse devices connected\n");
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_printf(mon, "Mouse devices available:\n");
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL) {
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "%c Mouse #%d: %s\n",
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       (cursor == qemu_put_mouse_event_current ? '*' : ' '),
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       index, cursor->qemu_put_mouse_event_name);
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index++;
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_mouse_set(Monitor *mon, int index)
7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUPutMouseEntry *cursor;
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i = 0;
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_put_mouse_event_head) {
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No mouse devices connected\n");
7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cursor = qemu_put_mouse_event_head;
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (cursor != NULL && index != i) {
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i++;
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cursor = cursor->next;
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cursor != NULL)
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_mouse_event_current = cursor;
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "Mouse at given index not found\n");
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* compute with 96 bit intermediate result: (a*b)/c */
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    union {
7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t ll;
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct {
74320894ae3fa98f82da925fbeb72e616eef509758aDavid 'Digit' Turner#ifdef HOST_WORDS_BIGENDIAN
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint32_t high, low;
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint32_t low, high;
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } l;
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } u, res;
7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t rl, rh;
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    u.ll = a;
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rl = (uint64_t)u.l.low * (uint64_t)b;
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rh = (uint64_t)u.l.high * (uint64_t)b;
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    rh += (rl >> 32);
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res.l.high = rh / c;
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return res.ll;
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
761a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerstatic int64_t get_clock_realtime(void)
762a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner{
763a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    struct timeval tv;
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
765a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    gettimeofday(&tv, NULL);
766a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
767a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner}
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef WIN32
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t clock_freq;
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void init_get_clock(void)
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    LARGE_INTEGER freq;
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = QueryPerformanceFrequency(&freq);
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret == 0) {
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Could not calibrate ticks\n");
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    clock_freq = freq.QuadPart;
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t get_clock(void)
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    LARGE_INTEGER ti;
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QueryPerformanceCounter(&ti);
789a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int use_rt_clock;
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void init_get_clock(void)
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    use_rt_clock = 0;
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
800a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct timespec ts;
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            use_rt_clock = 1;
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t get_clock(void)
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
813a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner	|| defined(__DragonFly__) || defined(__FreeBSD_kernel__)
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_rt_clock) {
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct timespec ts;
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        clock_gettime(CLOCK_MONOTONIC, &ts);
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* XXX: using gettimeofday leads to problems if the date
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           changes, so it should be avoided. */
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct timeval tv;
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gettimeofday(&tv, NULL);
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Return the virtual CPU time, based on the instruction counter.  */
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t cpu_get_icount(void)
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t icount;
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = cpu_single_env;;
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    icount = qemu_icount;
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env) {
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!can_do_io(env))
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Bad clock read\n");
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        icount -= (env->icount_decr.u16.low + env->icount_extra);
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_icount_bias + (icount << icount_time_shift);
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* guest cycle counter */
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
847a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnertypedef struct TimersState {
848a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int64_t cpu_ticks_prev;
849a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int64_t cpu_ticks_offset;
850a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int64_t cpu_clock_offset;
851a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int32_t cpu_ticks_enabled;
852a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int64_t dummy;
853a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner} TimersState;
854a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
855a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' TurnerTimersState timers_state;
8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* return the host CPU cycle counter and handle stop/restart */
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t cpu_get_ticks(void)
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount) {
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return cpu_get_icount();
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
863a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!timers_state.cpu_ticks_enabled) {
864a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return timers_state.cpu_ticks_offset;
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int64_t ticks;
8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ticks = cpu_get_real_ticks();
868a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (timers_state.cpu_ticks_prev > ticks) {
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Note: non increasing ticks may happen if the host uses
8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               software suspend */
871a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
873a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_ticks_prev = ticks;
874a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return ticks + timers_state.cpu_ticks_offset;
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* return the host CPU monotonic timer and handle stop/restart */
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t cpu_get_clock(void)
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t ti;
882a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!timers_state.cpu_ticks_enabled) {
883a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return timers_state.cpu_clock_offset;
8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ti = get_clock();
886a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return ti + timers_state.cpu_clock_offset;
8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* enable cpu_get_ticks() */
8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid cpu_enable_ticks(void)
8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
893a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!timers_state.cpu_ticks_enabled) {
894a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
895a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_clock_offset -= get_clock();
896a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_ticks_enabled = 1;
8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* disable cpu_get_ticks() : the clock is stopped. You must not call
9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   cpu_get_ticks() after that.  */
9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid cpu_disable_ticks(void)
9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
904a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (timers_state.cpu_ticks_enabled) {
905a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_ticks_offset = cpu_get_ticks();
906a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_clock_offset = cpu_get_clock();
907a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        timers_state.cpu_ticks_enabled = 0;
9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* timers */
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
914a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#define QEMU_CLOCK_REALTIME 0
915a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#define QEMU_CLOCK_VIRTUAL  1
916a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#define QEMU_CLOCK_HOST     2
9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct QEMUClock {
9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int type;
9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: add frequency */
9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct QEMUTimer {
9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUClock *clock;
9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t expire_time;
9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimerCB *cb;
9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct QEMUTimer *next;
9295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct qemu_alarm_timer {
9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char const *name;
9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned int flags;
9345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int (*start)(struct qemu_alarm_timer *t);
9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void (*stop)(struct qemu_alarm_timer *t);
9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void (*rearm)(struct qemu_alarm_timer *t);
9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *priv;
9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define ALARM_FLAG_DYNTICKS  0x1
9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define ALARM_FLAG_EXPIRED   0x2
9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return t && (t->flags & ALARM_FLAG_DYNTICKS);
9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!alarm_has_dynticks(t))
9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t->rearm(t);
9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* TODO: MIN_TIMER_REARM_US should be optimized */
9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MIN_TIMER_REARM_US 250
9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct qemu_alarm_timer *alarm_timer;
9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct qemu_alarm_win32 {
9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    MMRESULT timerId;
9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned int period;
9675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} alarm_win32_data = {0, -1};
9685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t);
9705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t);
9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t);
9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t);
9765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t);
9775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
9795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t);
9815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t);
9825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t);
9835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t);
9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t);
9865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t);
9885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t);
9895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* __linux__ */
9915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* _WIN32 */
9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Correlation between real and virtual time is always going to be
9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   fairly approximate, so ignore small variation.
9965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   When the guest is idle real and virtual time will be aligned in
9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   the IO wait loop.  */
998a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void icount_adjust(void)
10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t cur_time;
10035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t cur_icount;
10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t delta;
10055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static int64_t last_delta;
10065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If the VM is not running, then do nothing.  */
10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vm_running)
10085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
10095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cur_time = cpu_get_clock();
10115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cur_icount = qemu_get_clock(vm_clock);
10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    delta = cur_icount - cur_time;
10135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
10145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (delta > 0
10155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && last_delta + ICOUNT_WOBBLE < delta * 2
10165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && icount_time_shift > 0) {
10175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* The guest is getting too far ahead.  Slow time down.  */
10185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        icount_time_shift--;
10195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (delta < 0
10215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && last_delta - ICOUNT_WOBBLE > delta * 2
10225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && icount_time_shift < MAX_ICOUNT_SHIFT) {
10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* The guest is getting too far behind.  Speed time up.  */
10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        icount_time_shift++;
10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    last_delta = delta;
10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void icount_adjust_rt(void * opaque)
10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(icount_rt_timer,
10335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   qemu_get_clock(rt_clock) + 1000);
10345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    icount_adjust();
10355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void icount_adjust_vm(void * opaque)
10385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(icount_vm_timer,
1040a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                   qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    icount_adjust();
10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void init_icount_adjust(void)
10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Have both realtime and virtual time triggers for speed adjustment.
10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       The realtime trigger catches emulated time passing too slowly,
10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       the virtual time trigger catches emulated time passing too fast.
10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       Realtime triggers occur even when idle, so use them less frequently
10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       than VM triggers.  */
10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(icount_rt_timer,
10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                   qemu_get_clock(rt_clock) + 1000);
10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(icount_vm_timer,
1056a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                   qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct qemu_alarm_timer alarm_timers[] = {
10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __linux__
10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     dynticks_stop_timer, dynticks_rearm_timer, NULL},
10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* HPET - if available - is preferred */
10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* ...otherwise try RTC */
10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {"win32", 0, win32_start_timer,
10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     win32_stop_timer, NULL, &alarm_win32_data},
10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {NULL, 0, NULL, NULL, NULL, NULL}
10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void show_available_alarms(void)
10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("Available alarm timers, in order of precedence:\n");
10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; alarm_timers[i].name; i++)
10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        printf("%s\n", alarm_timers[i].name);
10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void configure_alarms(char const *opt)
10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cur = 0;
10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int count = ARRAY_SIZE(alarm_timers) - 1;
10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *arg;
10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *name;
10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct qemu_alarm_timer tmp;
10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(opt, "?")) {
10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        show_available_alarms();
10995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(0);
11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    arg = strdup(opt);
11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Reorder the array */
11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    name = strtok(arg, ",");
11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (name) {
11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < count && alarm_timers[i].name; i++) {
11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!strcmp(alarm_timers[i].name, name))
11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
11105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == count) {
11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Unknown clock %s\n", name);
11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto next;
11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i < cur)
11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Ignore */
11195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto next;
11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Swap */
11225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tmp = alarm_timers[i];
11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        alarm_timers[i] = alarm_timers[cur];
11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        alarm_timers[cur] = tmp;
11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cur++;
11275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnernext:
11285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        name = strtok(NULL, ",");
11295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1131a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    qemu_free(arg);
11325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cur) {
11345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Disable remaining timers */
11355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = cur; i < count; i++)
11365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            alarm_timers[i].name = NULL;
11375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
11385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        show_available_alarms();
11395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
11405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1143a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#define QEMU_NUM_CLOCKS 3
1144a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUClock *rt_clock;
11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUClock *vm_clock;
1147a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' TurnerQEMUClock *host_clock;
11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1149a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerstatic QEMUTimer *active_timers[QEMU_NUM_CLOCKS];
11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUClock *qemu_new_clock(int type)
11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUClock *clock;
11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    clock = qemu_mallocz(sizeof(QEMUClock));
11555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    clock->type = type;
11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return clock;
11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimer *ts;
11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts = qemu_mallocz(sizeof(QEMUTimer));
11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts->clock = clock;
11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts->cb = cb;
11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts->opaque = opaque;
11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ts;
11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_free_timer(QEMUTimer *ts)
11715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(ts);
11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* stop a timer, but do not dealloc it */
11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_timer(QEMUTimer *ts)
11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimer **pt, *t;
11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* NOTE: this code must be signal safe because
11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       qemu_timer_expired() can be called from a signal. */
11825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pt = &active_timers[ts->clock->type];
11835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t = *pt;
11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!t)
11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
11875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (t == ts) {
11885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *pt = t->next;
11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pt = &t->next;
11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* modify the current timer so that it will be fired when current_time
11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   >= expire_time. The corresponding callback will be called. */
11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimer **pt, *t;
12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_del_timer(ts);
12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* add the timer in the sorted list */
12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* NOTE: this code must be signal safe because
12055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       qemu_timer_expired() can be called from a signal. */
12065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pt = &active_timers[ts->clock->type];
12075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
12085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t = *pt;
12095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!t)
12105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
12115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (t->expire_time > expire_time)
12125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
12135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pt = &t->next;
12145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts->expire_time = expire_time;
12165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ts->next = *pt;
12175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pt = ts;
12185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Rearm if necessary  */
12205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (pt == &active_timers[ts->clock->type]) {
12215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
12225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_rearm_alarm_timer(alarm_timer);
12235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
12245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Interrupt execution to force deadline recalculation.  */
12255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (use_icount)
12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_notify_event();
12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_timer_pending(QEMUTimer *ts)
12315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimer *t;
12335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (t == ts)
12355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 1;
12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
12385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1240a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerint qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
12425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!timer_head)
12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
12445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return (timer_head->expire_time <= current_time);
12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUTimer *ts;
12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ts = *ptimer_head;
12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!ts || ts->expire_time > current_time)
12545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* remove timer from the list before calling the callback */
12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        *ptimer_head = ts->next;
12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ts->next = NULL;
12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* run the callback (the timer list can be modified) */
12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ts->cb(ts->opaque);
12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint64_t qemu_get_clock(QEMUClock *clock)
12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(clock->type) {
1267a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_REALTIME:
12685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return get_clock() / 1000000;
12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
1270a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_VIRTUAL:
1271a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (use_icount) {
1272a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            return cpu_get_icount();
1273a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        } else {
1274a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            return cpu_get_clock();
1275a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        }
1276a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_HOST:
1277a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return get_clock_realtime();
1278a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    }
1279a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner}
1280a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
1281a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerint64_t qemu_get_clock_ns(QEMUClock *clock)
1282a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner{
1283a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    switch(clock->type) {
1284a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_REALTIME:
1285a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return get_clock();
1286a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    default:
1287a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_VIRTUAL:
12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (use_icount) {
12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return cpu_get_icount();
12905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return cpu_get_clock();
12925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
1293a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    case QEMU_CLOCK_HOST:
1294a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        return get_clock_realtime();
12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1298a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turnerstatic void init_clocks(void)
12995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    init_get_clock();
1301a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
1302a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
1303a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
1304a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
1305a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    rtc_clock = host_clock;
13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* save a timer */
13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
13105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t expire_time;
13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_timer_pending(ts)) {
13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        expire_time = ts->expire_time;
13155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        expire_time = -1;
13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, expire_time);
13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t expire_time;
13245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    expire_time = qemu_get_be64(f);
13265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (expire_time != -1) {
13275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mod_timer(ts, expire_time);
13285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_del_timer(ts);
13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void timer_save(QEMUFile *f, void *opaque)
13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1335a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#if 0
13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cpu_ticks_enabled) {
13375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hw_error("cannot save state if virtual timers are running");
13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, cpu_ticks_offset);
13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, ticks_per_sec);
13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, cpu_clock_offset);
1342a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#endif
13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int timer_load(QEMUFile *f, void *opaque, int version_id)
13465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1347a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#if 0
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id != 1 && version_id != 2)
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cpu_ticks_enabled) {
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_ticks_offset=qemu_get_be64(f);
13545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ticks_per_sec=qemu_get_be64(f);
13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id == 2) {
13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_clock_offset=qemu_get_be64(f);
13575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1358a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#endif
13595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
13605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_increment(void);
13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                        DWORD_PTR dwUser, DWORD_PTR dw1,
13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                        DWORD_PTR dw2)
13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void host_alarm_handler(int host_signum)
13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
13735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DISP_FREQ 1000
13745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        static int64_t delta_min = INT64_MAX;
13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        static int64_t delta_max, delta_cum, last_clock, delta, ti;
13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        static int count;
13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ti = qemu_get_clock(vm_clock);
13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (last_clock != 0) {
13805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta = ti - last_clock;
13815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (delta < delta_min)
13825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                delta_min = delta;
13835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (delta > delta_max)
13845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                delta_max = delta;
13855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta_cum += delta;
13865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (++count == DISP_FREQ) {
13875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
1388a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                       muldiv64(delta_min, 1000000, get_ticks_per_sec()),
1389a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                       muldiv64(delta_max, 1000000, get_ticks_per_sec()),
1390a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                       muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
1391a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                       (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
13925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                count = 0;
13935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                delta_min = INT64_MAX;
13945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                delta_max = 0;
13955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                delta_cum = 0;
13965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
13975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        last_clock = ti;
13995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
14015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (alarm_has_dynticks(alarm_timer) ||
14025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        (!use_icount &&
1403a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],
14045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               qemu_get_clock(vm_clock))) ||
1405a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],
1406a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                           qemu_get_clock(rt_clock)) ||
1407a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],
1408a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                           qemu_get_clock(host_clock))) {
14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_event_increment();
14105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
14115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
14135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (next_cpu) {
14145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* stop the currently executing cpu because a timer occured */
14155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_exit(next_cpu);
14165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
14185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timer_alarm_pending = 1;
14195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_notify_event();
14205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int64_t qemu_next_deadline(void)
14245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1425a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        /* To avoid problems with overflow limit this to 2^32.  */
1426a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    int64_t delta = INT32_MAX;
14275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1428a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (active_timers[QEMU_CLOCK_VIRTUAL]) {
1429a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
14305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     qemu_get_clock(vm_clock);
1431a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    }
1432a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (active_timers[QEMU_CLOCK_HOST]) {
1433a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
1434a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                 qemu_get_clock(host_clock);
1435a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (hdelta < delta)
1436a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            delta = hdelta;
14375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (delta < 0)
14405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        delta = 0;
14415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return delta;
14435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1445a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner#if defined(__linux__)
14465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint64_t qemu_next_deadline_dyntick(void)
14475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t delta;
14495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t rtdelta;
14505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount)
14525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        delta = INT32_MAX;
14535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
14545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        delta = (qemu_next_deadline() + 999) / 1000;
14555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1456a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (active_timers[QEMU_CLOCK_REALTIME]) {
1457a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -
14585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 qemu_get_clock(rt_clock))*1000;
14595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtdelta < delta)
14605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta = rtdelta;
14615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (delta < MIN_TIMER_REARM_US)
14645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        delta = MIN_TIMER_REARM_US;
14655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return delta;
14675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
14695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
14715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Sets a specific flag */
14735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int fcntl_setfl(int fd, int flag)
14745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
14765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    flags = fcntl(fd, F_GETFL);
14785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (flags == -1)
14795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -errno;
14805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fcntl(fd, F_SETFL, flags | flag) == -1)
14825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -errno;
14835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
14855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__)
14885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RTC_FREQ 1024
14905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void enable_sigio_timer(int fd)
14925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction act;
14945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* timer signal */
14965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigfillset(&act.sa_mask);
14975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_flags = 0;
14985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = host_alarm_handler;
14995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGIO, &act, NULL);
15015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fcntl_setfl(fd, O_ASYNC);
15025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fcntl(fd, F_SETOWN, getpid());
15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t)
15065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct hpet_info info;
15085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r, fd;
15095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd = open("/dev/hpet", O_RDONLY);
15115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fd < 0)
15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Set frequency */
15155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
15165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (r < 0) {
15175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
15185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "error, but for better emulation accuracy type:\n"
15195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
15205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
15215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Check capabilities */
15245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    r = ioctl(fd, HPET_INFO, &info);
15255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (r < 0)
15265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
15275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Enable periodic mode */
15295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    r = ioctl(fd, HPET_EPI, 0);
15305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (info.hi_flags && (r < 0))
15315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
15325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Enable interrupt */
15345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    r = ioctl(fd, HPET_IE_ON, 0);
15355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (r < 0)
15365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
15375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    enable_sigio_timer(fd);
15395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t->priv = (void *)(long)fd;
15405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
15425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail:
15435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fd);
15445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
15455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t)
15485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd = (long)t->priv;
15505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fd);
15525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t)
15555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int rtc_fd;
15575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned long current_rtc_freq = 0;
15585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
15605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_fd < 0)
15615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
15635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (current_rtc_freq != RTC_FREQ &&
15645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
15655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
15665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
15675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
15685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
15695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
15715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fail:
15725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        close(rtc_fd);
15735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
15745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    enable_sigio_timer(rtc_fd);
15775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t->priv = (void *)(long)rtc_fd;
15795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
15815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t)
15845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int rtc_fd = (long)t->priv;
15865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(rtc_fd);
15885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t)
15915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigevent ev;
15935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timer_t host_timer;
15945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction act;
15955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigfillset(&act.sa_mask);
15975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_flags = 0;
15985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = host_alarm_handler;
15995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGALRM, &act, NULL);
16015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1602d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    /*
16035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * Initialize ev struct to 0 to avoid valgrind complaining
16045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * about uninitialized data in timer_create call
16055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
16065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&ev, 0, sizeof(ev));
16075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ev.sigev_value.sival_int = 0;
16085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ev.sigev_notify = SIGEV_SIGNAL;
16095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ev.sigev_signo = SIGALRM;
16105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
16125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        perror("timer_create");
16135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* disable dynticks */
16155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Dynamic Ticks disabled\n");
16165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
16185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    t->priv = (void *)(long)host_timer;
16215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
16235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t)
16265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timer_t host_timer = (timer_t)(long)t->priv;
16285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timer_delete(host_timer);
16305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t)
16335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timer_t host_timer = (timer_t)(long)t->priv;
16355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct itimerspec timeout;
16365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t nearest_delta_us = INT64_MAX;
16375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t current_us;
16385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1639a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!active_timers[QEMU_CLOCK_REALTIME] &&
1640a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        !active_timers[QEMU_CLOCK_VIRTUAL] &&
1641a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        !active_timers[QEMU_CLOCK_HOST])
16425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
16435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nearest_delta_us = qemu_next_deadline_dyntick();
16455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* check whether a timer is already running */
16475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (timer_gettime(host_timer, &timeout)) {
16485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        perror("gettime");
16495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Internal timer error: aborting\n");
16505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
16515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
16535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (current_us && current_us <= nearest_delta_us)
16545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
16555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeout.it_interval.tv_sec = 0;
16575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
16585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;
16595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
16605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
16615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        perror("settime");
16625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Internal timer error: aborting\n");
16635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
16645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
16655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* defined(__linux__) */
16685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t)
16705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction act;
16725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct itimerval itv;
16735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int err;
16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* timer signal */
16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigfillset(&act.sa_mask);
16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_flags = 0;
16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = host_alarm_handler;
16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGALRM, &act, NULL);
16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    itv.it_interval.tv_sec = 0;
16835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* for i386 kernel 2.6 to get 1 ms */
16845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    itv.it_interval.tv_usec = 999;
16855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    itv.it_value.tv_sec = 0;
16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    itv.it_value.tv_usec = 10 * 1000;
16875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = setitimer(ITIMER_REAL, &itv, NULL);
16895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err)
16905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
16915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
16935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
16945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t)
16965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
16975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct itimerval itv;
16985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
16995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&itv, 0, sizeof(itv));
17005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    setitimer(ITIMER_REAL, &itv, NULL);
17015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* !defined(_WIN32) */
17045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
17075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t)
17095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TIMECAPS tc;
17115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct qemu_alarm_win32 *data = t->priv;
17125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    UINT flags;
17135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&tc, 0, sizeof(tc));
17155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeGetDevCaps(&tc, sizeof(tc));
17165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (data->period < tc.wPeriodMin)
17185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data->period = tc.wPeriodMin;
17195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeBeginPeriod(data->period);
17215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    flags = TIME_CALLBACK_FUNCTION;
17235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (alarm_has_dynticks(t))
17245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        flags |= TIME_ONESHOT;
17255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
17265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        flags |= TIME_PERIODIC;
17275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data->timerId = timeSetEvent(1,         // interval (ms)
17295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        data->period,       // resolution
17305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        host_alarm_handler, // function
17315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        (DWORD)t,           // parameter
17325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        flags);
17335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data->timerId) {
1735a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
1736a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                GetLastError());
17375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timeEndPeriod(data->period);
17385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
17395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
17425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t)
17455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct qemu_alarm_win32 *data = t->priv;
17475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeKillEvent(data->timerId);
17495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeEndPeriod(data->period);
17505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t)
17535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct qemu_alarm_win32 *data = t->priv;
17555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1756a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    if (!active_timers[QEMU_CLOCK_REALTIME] &&
1757a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        !active_timers[QEMU_CLOCK_VIRTUAL] &&
1758a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        !active_timers[QEMU_CLOCK_HOST])
17595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
17605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    timeKillEvent(data->timerId);
17625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    data->timerId = timeSetEvent(1,
17645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        data->period,
17655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        host_alarm_handler,
17665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        (DWORD)t,
17675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        TIME_ONESHOT | TIME_PERIODIC);
17685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data->timerId) {
1770a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
1771a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                GetLastError());
17725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timeEndPeriod(data->period);
17745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
17755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
17775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* _WIN32 */
17795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int init_timer_alarm(void)
17815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
17825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct qemu_alarm_timer *t = NULL;
17835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i, err = -1;
17845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; alarm_timers[i].name; i++) {
17865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        t = &alarm_timers[i];
17875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        err = t->start(t);
17895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!err)
17905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
17915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err) {
17945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        err = -ENOENT;
17955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
17965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
17975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    alarm_timer = t;
17995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
18015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail:
18035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return err;
18045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void quit_timers(void)
18075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    alarm_timer->stop(alarm_timer);
18095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    alarm_timer = NULL;
18105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
18135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* host time/date access */
18145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_get_timedate(struct tm *tm, int offset)
18155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t ti;
18175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct tm *ret;
18185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time(&ti);
18205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ti += offset;
18215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1) {
18225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
18235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = gmtime(&ti);
18245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
18255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = localtime(&ti);
18265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
18275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ti -= rtc_date_offset;
18285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = gmtime(&ti);
18295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
18305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memcpy(tm, ret, sizeof(struct tm));
18325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_timedate_diff(struct tm *tm)
18355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    time_t seconds;
18375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (rtc_date_offset == -1)
18395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (rtc_utc)
18405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktimegm(tm);
18415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
18425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            seconds = mktime(tm);
18435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
18445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        seconds = mktimegm(tm) + rtc_date_offset;
18455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return seconds - time(NULL);
18475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
18515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tbflush_requested;
18525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int exit_requested;
18535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid start_tracing()
18555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
18575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
18585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (!tracing) {
18595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- start tracing --\n");
18605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_time = Now();
18615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
18625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 1;
18635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
18645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
18655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid stop_tracing()
18685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (trace_filename == NULL)
18705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
18715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (tracing) {
18725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    end_time = Now();
18735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    elapsed_usecs += end_time - start_time;
18745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr,"-- stop tracing --\n");
18755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  }
18765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tracing = 0;
18775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  tbflush_requested = 1;
18785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
18795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
18825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler for the SIGUSR1 and SIGUSR2 signals.
18835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * SIGUSR1 turns tracing on.  SIGUSR2 turns tracing off.
18845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
18855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigusr_handler(int sig)
18865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (sig == SIGUSR1)
18885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    start_tracing();
18895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  else
18905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stop_tracing();
18915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
18925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
18935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is the handler to catch control-C so that we can exit cleanly.
18955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This is needed when tracing to flush the buffers to disk.
18965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
18975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid sigint_handler(int sig)
18985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
18995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  exit_requested = 1;
19005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  qemu_notify_event();
19015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* CONFIG_TRACE */
19035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
19065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Bluetooth support */
19075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int nb_hcis;
19085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cur_hci;
19095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_table[MAX_NICS];
19105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_vlan_s {
19125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s net;
19135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int id;
19145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s *next;
19155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *first_bt_vlan;
19165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* find or alloc a new bluetooth "VLAN" */
19185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_scatternet_s *qemu_find_bt_vlan(int id)
19195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_vlan_s **pvlan, *vlan;
19215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (vlan = first_bt_vlan; vlan != NULL; vlan = vlan->next) {
19225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan->id == id)
19235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return &vlan->net;
19245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
19265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan->id = id;
19275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pvlan = &first_bt_vlan;
19285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pvlan != NULL)
19295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pvlan = &(*pvlan)->next;
19305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pvlan = vlan;
19315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return &vlan->net;
19325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void null_hci_send(struct HCIInfo *hci, const uint8_t *data, int len)
19355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int null_hci_addr_set(struct HCIInfo *hci, const uint8_t *bd_addr)
19395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -ENOTSUP;
19415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo null_hci = {
19445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .cmd_send = null_hci_send,
19455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .sco_send = null_hci_send,
19465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .acl_send = null_hci_send,
19475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdaddr_set = null_hci_addr_set,
19485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
19495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct HCIInfo *qemu_next_hci(void)
19515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cur_hci == nb_hcis)
19535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
19545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return hci_table[cur_hci++];
19565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct HCIInfo *hci_init(const char *str)
19595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp;
19615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = 0;
19625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(str, "null"))
19645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* null */
19655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return &null_hci;
19665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "host", 4) && (str[4] == '\0' || str[4] == ':'))
19675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* host[:hciN] */
19685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_host_hci(str[4] ? str + 5 : "hci0");
19695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!strncmp(str, "hci", 3)) {
19705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* hci[,vlan=n] */
19715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (str[3]) {
19725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!strncmp(str + 3, ",vlan=", 6)) {
19735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = qemu_find_bt_vlan(strtol(str + 9, &endp, 0));
19745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endp)
19755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = 0;
19765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
19785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vlan = qemu_find_bt_vlan(0);
19795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vlan)
19805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return bt_new_hci(vlan);
19815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
19845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
19865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_hci_parse(const char *str)
19895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct HCIInfo *hci;
19915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr_t bdaddr;
19925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_hcis >= MAX_NICS) {
19945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: Too many bluetooth HCIs (max %i).\n", MAX_NICS);
19955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
19965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
19975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci = hci_init(str);
19995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!hci)
20005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
20015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[0] = 0x52;
20035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[1] = 0x54;
20045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[2] = 0x00;
20055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[3] = 0x12;
20065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[4] = 0x34;
20075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdaddr.b[5] = 0x56 + nb_hcis;
20085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci->bdaddr_set(hci, bdaddr.b);
20095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hci_table[nb_hcis++] = hci;
20115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
20135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bt_vhci_add(int vlan_id)
20165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
20185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
20205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a VHCI to "
20215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
20225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bt_vhci_init(bt_new_hci(vlan));
20245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct bt_device_s *bt_device_add(const char *opt)
20275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct bt_scatternet_s *vlan;
20295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan_id = 0;
20305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endp = strstr(opt, ",vlan=");
20315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int len = (endp ? endp - opt : strlen(opt)) + 1;
20325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[10];
20335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pstrcpy(devname, MIN(sizeof(devname), len), opt);
20355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (endp) {
20375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vlan_id = strtol(endp + 6, &endp, 0);
20385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (*endp) {
20395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: unrecognised bluetooth vlan Id\n");
20405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
20415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
20435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vlan = qemu_find_bt_vlan(vlan_id);
20455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vlan->slave)
20475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: warning: adding a slave device to "
20485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "an empty scatternet %i\n", vlan_id);
20495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(devname, "keyboard"))
20515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return bt_keyboard_init(vlan);
20525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: unsupported bluetooth device `%s'\n", devname);
20545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
20555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int bt_parse(const char *opt)
20585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
20595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *endp, *p;
20605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int vlan;
20615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(opt, "hci", &endp)) {
20635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
20645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp)
20655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strstart(endp, ",vlan=", 0))
20665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    opt = endp + 1;
20675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return bt_hci_parse(opt);
20695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
20705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "vhci", &endp)) {
20715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!*endp || *endp == ',') {
20725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*endp) {
20735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strstart(endp, ",vlan=", &p)) {
20745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    vlan = strtol(p, (char **) &endp, 0);
20755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*endp) {
20765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: bad scatternet '%s'\n", p);
20775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        return 1;
20785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
20795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
20805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: bad parameter '%s'\n", endp + 1);
20815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    return 1;
20825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
20835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
20845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vlan = 0;
20855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bt_vhci_add(vlan);
20875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
20885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
20895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(opt, "device:", &endp))
20905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return !bt_device_add(endp);
20915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, "qemu: bad bluetooth parameter '%s'\n", opt);
20935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
20945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
20955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
20975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* QEMU Block devices */
20985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
20995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HD_ALIAS "index=%d,media=disk"
21005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define CDROM_ALIAS "index=2,media=cdrom"
21015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define FD_ALIAS "index=%d,if=floppy"
21025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define PFLASH_ALIAS "if=pflash"
21035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MTD_ALIAS "if=mtd"
21045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define SD_ALIAS "index=0,if=sd"
21055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_opt_get_free_idx(void)
21075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
21115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_opt[index].used) {
21125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_opt[index].used = 1;
21135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
21145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
21155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
21175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int drive_get_free_idx(void)
21205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
21245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drives_table[index].used) {
21255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[index].used = 1;
21265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return index;
21275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
21285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
21305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21327ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehatint drive_add(const char *file, const char *fmt, ...)
21337ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat{
21347ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_list ap;
21357ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    int index = drive_opt_get_free_idx();
21367ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat
21377ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    if (nb_drives_opt >= MAX_DRIVES || index == -1) {
21387ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        fprintf(stderr, "qemu: too many drives\n");
21397ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat        return -1;
21407ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    }
21415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21427ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    drives_opt[index].file = file;
21437ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_start(ap, fmt);
21447ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    vsnprintf(drives_opt[index].opt,
21457ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat              sizeof(drives_opt[0].opt), fmt, ap);
21467ab6d35b98bc279a5fcd36965433a51a3c9aecd9San Mehat    va_end(ap);
214792568958dd42bf35667cc6451b5edd7f7d1f73a1David 'Digit' Turner
21485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt++;
21495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return index;
21505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_remove(int index)
21535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_opt[index].used = 0;
21555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt--;
21565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_index(BlockInterfaceType type, int bus, int unit)
21595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* seek interface, bus and unit */
21635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < MAX_DRIVES; index++)
21655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].type == type &&
21665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].bus == bus &&
21675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].unit == unit &&
21685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    drives_table[index].used)
21695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return index;
21705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return -1;
21725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_get_max_bus(BlockInterfaceType type)
21755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_bus;
21775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_bus = -1;
21805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++) {
21815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if(drives_table[index].type == type &&
21825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           drives_table[index].bus > max_bus)
21835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_bus = drives_table[index].bus;
21845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
21855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return max_bus;
21865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char *drive_get_serial(BlockDriverState *bdrv)
21895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
21915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
21935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
21945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].serial;
21955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return "\0";
21975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerBlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
22005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
22025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (index = 0; index < nb_drives; index++)
22045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[index].bdrv == bdrv)
22055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return drives_table[index].onerror;
22065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return BLOCK_ERR_STOP_ENOSPC;
22085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bdrv_format_print(void *opaque, const char *name)
22115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fprintf(stderr, " %s", name);
22135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid drive_uninit(BlockDriverState *bdrv)
22165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
22185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_DRIVES; i++)
22205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drives_table[i].bdrv == bdrv) {
22215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].bdrv = NULL;
22225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drives_table[i].used = 0;
22235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            drive_remove(drives_table[i].drive_opt_idx);
22245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_drives--;
22255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
22265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
22275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint drive_init(struct drive_opt *arg, int snapshot, void *opaque)
22305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[128];
22325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char file[1024];
22335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char devname[128];
22345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char serial[21];
22355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *mediastr = "";
22365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockInterfaceType type;
22375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    enum { MEDIA_DISK, MEDIA_CDROM } media;
22385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_id, unit_id;
22395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
22405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriverState *bdrv;
22415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    BlockDriver *drv = NULL;
22425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine = opaque;
22435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_devs;
22445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
22455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cache;
22465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bdrv_flags, onerror;
22475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int drives_table_idx;
22485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *str = arg->opt;
22495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static const char * const params[] = { "bus", "unit", "if", "index",
22505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cyls", "heads", "secs", "trans",
22515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "media", "snapshot", "file",
22525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           "cache", "format", "serial", "werror",
22535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                           NULL };
22545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (check_params(buf, sizeof(buf), params, str) < 0) {
22565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
22575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         buf, str);
22585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         return -1;
22595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    file[0] = 0;
22625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
22635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_id = 0;
22645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unit_id = -1;
22655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
22665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    index = -1;
22675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cache = 3;
22685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (machine->use_scsi) {
22705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_SCSI;
22715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_SCSI_DEVS;
22725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "scsi");
22735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
22745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = IF_IDE;
22755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_devs = MAX_IDE_DEVS;
22765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), "ide");
22775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    media = MEDIA_DISK;
22795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* extract parameters */
22815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "bus", str)) {
22835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bus_id = strtol(buf, NULL, 0);
22845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (bus_id < 0) {
22855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
22865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
22875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
22885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "unit", str)) {
22915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        unit_id = strtol(buf, NULL, 0);
22925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (unit_id < 0) {
22935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
22945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
22955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
22965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
22975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "if", str)) {
22995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(devname, sizeof(devname), buf);
23005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ide")) {
23015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_IDE;
23025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_IDE_DEVS;
23035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "scsi")) {
23045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SCSI;
23055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = MAX_SCSI_DEVS;
23065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "floppy")) {
23075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_FLOPPY;
23085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "pflash")) {
23105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_PFLASH;
23115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "mtd")) {
23135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_MTD;
23145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "sd")) {
23165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_SD;
23175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (!strcmp(buf, "virtio")) {
23195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            type = IF_VIRTIO;
23205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "xen")) {
23225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    type = IF_XEN;
23235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            max_devs = 0;
23245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
23255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
23265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
23275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "index", str)) {
23315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        index = strtol(buf, NULL, 0);
23325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (index < 0) {
23335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid index\n", str);
23345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cyls", str)) {
23395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cyls = strtol(buf, NULL, 0);
23405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "heads", str)) {
23435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        heads = strtol(buf, NULL, 0);
23445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "secs", str)) {
23475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        secs = strtol(buf, NULL, 0);
23485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cyls || heads || secs) {
23515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cyls < 1 || cyls > 16383) {
23525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
23535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (heads < 1 || heads > 16) {
23565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
23575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (secs < 1 || secs > 63) {
23605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
23615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "trans", str)) {
23665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cyls) {
23675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
23685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' trans must be used with cyls,heads and secs\n",
23695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    str);
23705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
23715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "none"))
23735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_NONE;
23745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "lba"))
23755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_LBA;
23765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "auto"))
23775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            translation = BIOS_ATA_TRANSLATION_AUTO;
23785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
23795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
23805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "media", str)) {
23855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "disk")) {
23865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_DISK;
23875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (!strcmp(buf, "cdrom")) {
23885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls || secs || heads) {
23895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr,
23905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        "qemu: '%s' invalid physical CHS format\n", str);
23915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        return -1;
23925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
23935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    media = MEDIA_CDROM;
23945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else {
23955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid media\n", str);
23965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
23975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
23985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
24015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "on"))
24025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 1;
24035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "off"))
24045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    snapshot = 0;
24055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else {
24065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
24075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
24085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
24095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "cache", str)) {
24125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "off") || !strcmp(buf, "none"))
24135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 0;
24145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writethrough"))
24155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 1;
24165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "writeback"))
24175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cache = 2;
24185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
24195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           fprintf(stderr, "qemu: invalid cache option\n");
24205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           return -1;
24215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(buf), "format", str)) {
24255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strcmp(buf, "?") == 0) {
24265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: Supported formats:");
24275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_iterate_format(bdrv_format_print, NULL);
24285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "\n");
24295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return -1;
24305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drv = bdrv_find_format(buf);
24325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!drv) {
24335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid format\n", buf);
24345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
24355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (arg->file == NULL)
24395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        get_param_value(file, sizeof(file), "file", str);
24405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
24415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pstrcpy(file, sizeof(file), arg->file);
24425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!get_param_value(serial, sizeof(serial), "serial", str))
24445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    memset(serial, 0,  sizeof(serial));
24455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    onerror = BLOCK_ERR_STOP_ENOSPC;
24475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (get_param_value(buf, sizeof(serial), "werror", str)) {
24485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
24495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "werror is no supported by this format\n");
24505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
24515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(buf, "ignore"))
24535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_IGNORE;
24545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "enospc"))
24555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ENOSPC;
24565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "stop"))
24575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_STOP_ANY;
24585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (!strcmp(buf, "report"))
24595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            onerror = BLOCK_ERR_REPORT;
24605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else {
24615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
24625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
24635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* compute bus and unit according index */
24675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (index != -1) {
24695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bus_id != 0 || unit_id != -1) {
24705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr,
24715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "qemu: '%s' index cannot be used with bus and unit\n", str);
24725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
24735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (max_devs == 0)
24755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        {
24765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index;
24775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = 0;
24785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
24795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            unit_id = index % max_devs;
24805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bus_id = index / max_devs;
24815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* if user doesn't specify a unit_id,
24855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * try to find the first free
24865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
24875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (unit_id == -1) {
24895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       unit_id = 0;
24905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       while (drive_get_index(type, bus_id, unit_id) != -1) {
24915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           unit_id++;
24925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           if (max_devs && unit_id >= max_devs) {
24935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               unit_id -= max_devs;
24945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               bus_id++;
24955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           }
24965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       }
24975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* check unit id */
25005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs && unit_id >= max_devs) {
25025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
25035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        str, unit_id, max_devs - 1);
25045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
25055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /*
25085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * ignore multiple definitions
25095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
25105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (drive_get_index(type, bus_id, unit_id) != -1)
25125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
25135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init */
25155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (type == IF_IDE || type == IF_SCSI)
25175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
25185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (max_devs)
25195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%i%s%i",
25205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, bus_id, mediastr, unit_id);
25215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
25225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "%s%s%i",
25235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 devname, mediastr, unit_id);
25245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv = bdrv_new(buf);
25255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table_idx = drive_get_free_idx();
25265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bdrv = bdrv;
25275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].type = type;
25285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].bus = bus_id;
25295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].unit = unit_id;
25305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].onerror = onerror;
25315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
25325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
25335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives++;
25345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(type) {
25365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_IDE:
25375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SCSI:
25385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_XEN:
25395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(media) {
25405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_DISK:
25415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (cyls != 0) {
25425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
25435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bdrv_set_translation_hint(bdrv, translation);
25445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
25455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
25465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	case MEDIA_CDROM:
25475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
25485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
25495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
25505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
25515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_SD:
25525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FIXME: This isn't really a floppy, but it's a reasonable
25535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           approximation.  */
25545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_FLOPPY:
25555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
25565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
25575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_PFLASH:
25585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_MTD:
25595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_VIRTIO:
25605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
25615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case IF_COUNT:
25625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
25635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!file[0])
25655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -2;
25665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_flags = 0;
25675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (snapshot) {
25685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_SNAPSHOT;
25695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cache = 2; /* always use write-back with snapshot */
25705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cache == 0) /* no caching */
25725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_NOCACHE;
25735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 2) /* write-back */
25745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_WB;
25755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (cache == 3) /* not specified */
25765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flags |= BDRV_O_CACHE_DEF;
25775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
25785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: could not open disk image %s\n",
25795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        file);
25805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
25815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
25825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bdrv_key_required(bdrv))
25835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0;
25845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return drives_table_idx;
25855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
25865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void numa_add(const char *optarg)
25885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
25895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char option[128];
25905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *endptr;
25915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unsigned long long value, endvalue;
25925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nodenr;
25935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
25945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optarg = get_opt_name(option, 128, optarg, ',') + 1;
25955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(option, "node")) {
25965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "nodeid", optarg) == 0) {
25975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = nb_numa_nodes;
25985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
25995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nodenr = strtoull(option, NULL, 10);
26005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
26015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "mem", optarg) == 0) {
26035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = 0;
26045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
26055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 0);
26065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch (*endptr) {
26075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 0: case 'M': case 'm':
26085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 20;
26095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
26105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case 'G': case 'g':
26115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value <<= 30;
26125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
26135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
26145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[nodenr] = value;
26155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
26165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (get_param_value(option, 128, "cpus", optarg) == 0) {
26175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = 0;
26185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
26195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            value = strtoull(option, &endptr, 10);
26205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (value >= 64) {
26215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = 63;
26225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
26235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
26245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*endptr == '-') {
26255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    endvalue = strtoull(endptr+1, &endptr, 10);
26265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (endvalue >= 63) {
26275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        endvalue = 62;
26285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr,
26295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            "only 63 CPUs in NUMA mode supported.\n");
26305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
26315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = (1 << (endvalue + 1)) - (1 << value);
26325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
26335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value = 1 << value;
26345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
26355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
26365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_cpumask[nodenr] = value;
26375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
26385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nb_numa_nodes++;
26395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
26415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
26445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* USB devices */
26455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *used_usb_ports;
26475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic USBPort *free_usb_ports;
26485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ??? Maybe change this to register a hub to keep track of the topology.  */
26505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_usb_port(USBPort *port, void *opaque, int index,
26515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            usb_attachfn attach)
26525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->opaque = opaque;
26545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->index = index;
26555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->attach = attach;
26565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
26575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
26585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_add_dev(USBDevice *dev)
26615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
26635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Find a USB port to add the device to.  */
26655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = free_usb_ports;
26665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port->next) {
26675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        USBDevice *hub;
26685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Create a new hub and chain it on.  */
26705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        free_usb_ports = NULL;
26715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port->next = used_usb_ports;
26725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        used_usb_ports = port;
26735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hub = usb_hub_init(VM_USB_HUB_SIZE);
26755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_attach(port, hub);
26765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = free_usb_ports;
26775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
26785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port->next;
26805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = used_usb_ports;
26815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    used_usb_ports = port;
26825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, dev);
26835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
26845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26863266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#if 0
26875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void usb_msd_password_cb(void *opaque, int err)
26885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
26895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev = opaque;
26905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!err)
26925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        usb_device_add_dev(dev);
26935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
26945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev->handle_destroy(dev);
26955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
26963266b5118e1d9ac13ea87bc24f37b50d22a2b81fDavid 'Digit' Turner#endif
26975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
26985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_add(const char *devname, int is_hotplug)
26995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
27015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
27025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!free_usb_ports)
27045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p)) {
27075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_host_device_open(p);
27085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "mouse")) {
27095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_mouse_init();
27105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "tablet")) {
27115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_tablet_init();
27125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "keyboard")) {
27135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_keyboard_init();
27145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "disk:", &p)) {
27155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
27165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        BlockDriverState *bs;
27175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_msd_init(p);
27195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
27205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
27215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
27225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bs = usb_msd_get_bdrv(dev);
27235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bdrv_key_required(bs)) {
27245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            autostart = 0;
27255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (is_hotplug) {
27265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
27275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            dev);
27285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
27295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
27305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
27315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "wacom-tablet")) {
27325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_wacom_init();
27335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "serial:", &p)) {
27345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_serial_init(p);
27355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_BRLAPI
27365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "braille")) {
27375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_baum_init();
27385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(devname, "net:", &p)) {
27405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int nic = nb_nics;
27415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (net_client_init("nic", p) < 0)
27435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
27445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nd_table[nic].model = "usb";
27455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_net_init(&nd_table[nic]);
27465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
27475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = usb_bt_init(devname[2] ? hci_init(p) :
27485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        bt_new_hci(qemu_find_bt_vlan(0)));
27495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
27505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
27515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
27535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!dev)
27545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_add_dev(dev);
27575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint usb_device_del_addr(int bus_num, int addr)
27605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
27625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort **lastp;
27635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
27645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
27665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bus_num != 0)
27695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    lastp = &used_usb_ports;
27725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port = used_usb_ports;
27735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (port && port->dev->addr != addr) {
27745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        lastp = &port->next;
27755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        port = port->next;
27765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
27775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!port)
27795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
27805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev = port->dev;
27825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *lastp = port->next;
27835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_attach(port, NULL);
27845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dev->handle_destroy(dev);
27855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    port->next = free_usb_ports;
27865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free_usb_ports = port;
27875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
27885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
27895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int usb_device_del(const char *devname)
27915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
27925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int bus_num, addr;
27935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
27945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(devname, "host:", &p))
27965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return usb_host_device_close(p);
27975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
27985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!used_usb_ports)
27995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
28005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = strchr(devname, '.');
28025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p)
28035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
28045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bus_num = strtoul(devname, NULL, 0);
28055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    addr = strtoul(p + 1, NULL, 0);
28065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return usb_device_del_addr(bus_num, addr);
28085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_add(Monitor *mon, const char *devname)
28115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_add(devname, 1);
28135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_usb_del(Monitor *mon, const char *devname)
28165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_device_del(devname);
28185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid usb_info(Monitor *mon)
28215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBDevice *dev;
28235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    USBPort *port;
28245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *speed_str;
28255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!usb_enabled) {
28275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "USB support not enabled\n");
28285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
28295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
28305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (port = used_usb_ports; port; port = port->next) {
28325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dev = port->dev;
28335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!dev)
28345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
28355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch(dev->speed) {
28365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_LOW:
28375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "1.5";
28385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
28395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_FULL:
28405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "12";
28415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
28425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case USB_SPEED_HIGH:
28435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "480";
28445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
28455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
28465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            speed_str = "?";
28475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
28485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
28495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "  Device %d.%d, Speed %s Mb/s, Product %s\n",
28505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       0, dev->addr, speed_str, dev->devname);
28515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
28525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
28555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* PCMCIA/Cardbus */
28565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct pcmcia_socket_entry_s {
28585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PCMCIASocket *socket;
28595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *next;
28605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} *pcmcia_sockets = 0;
28615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_register(PCMCIASocket *socket)
28635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry;
28655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
28675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->socket = socket;
28685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    entry->next = pcmcia_sockets;
28695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pcmcia_sockets = entry;
28705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_socket_unregister(PCMCIASocket *socket)
28735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *entry, **ptr;
28755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ptr = &pcmcia_sockets;
28775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
28785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (entry->socket == socket) {
28795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *ptr = entry->next;
28805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(entry);
28815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
28825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid pcmcia_info(Monitor *mon)
28855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
28865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pcmcia_socket_entry_s *iter;
28875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!pcmcia_sockets)
28895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "No PCMCIA sockets\n");
28905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (iter = pcmcia_sockets; iter; iter = iter->next)
28925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
28935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       iter->socket->attached ? iter->socket->card_string :
28945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       "Empty");
28955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
28965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
28975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
28985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* register display */
28995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct DisplayAllocator default_allocator = {
29015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_create_displaysurface,
29025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_resize_displaysurface,
29035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    defaultallocator_free_displaysurface
29045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
29055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid register_displaystate(DisplayState *ds)
29075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState **s;
29095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = &display_state;
29105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*s != NULL)
29115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s = &(*s)->next;
29125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->next = NULL;
29135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *s = ds;
29145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayState *get_displaystate(void)
29175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return display_state;
29195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerDisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
29225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(ds->allocator ==  &default_allocator) ds->allocator = da;
29245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ds->allocator;
29255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* dumb display */
29285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dumb_display_init(void)
29305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
29325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->allocator = &default_allocator;
29335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds->surface = qemu_create_displaysurface(ds, 640, 480);
29345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_displaystate(ds);
29355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
29365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2937dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkinestatic void
2938dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkineandroid_display_init_from(int width, int height, int rotation, int bpp)
2939dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine{
2940dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
2941dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    ds->allocator = &default_allocator;
2942dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    ds->surface = qemu_create_displaysurface(ds, width, height);
2943dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    register_displaystate(ds);
2944dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine}
2945dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
29465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
29475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* I/O handling */
29485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct IOHandlerRecord {
29505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd;
29515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOCanRWHandler *fd_read_poll;
29525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandler *fd_read;
29535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandler *fd_write;
29545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int deleted;
29555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
29565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* temporary data */
29575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct pollfd *ufd;
29585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct IOHandlerRecord *next;
29595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} IOHandlerRecord;
29605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic IOHandlerRecord *first_io_handler;
29625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: fd_read_poll should be suppressed, but an API change is
29645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   necessary in the character devices to suppress fd_can_read(). */
29655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_set_fd_handler2(int fd,
29665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOCanRWHandler *fd_read_poll,
29675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOHandler *fd_read,
29685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         IOHandler *fd_write,
29695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         void *opaque)
29705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
29715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandlerRecord **pioh, *ioh;
29725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
29735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!fd_read && !fd_write) {
29745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pioh = &first_io_handler;
29755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(;;) {
29765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ioh = *pioh;
29775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh == NULL)
29785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd == fd) {
29805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->deleted = 1;
29815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
29825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
29835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pioh = &ioh->next;
29845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
29855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
29865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
29875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd == fd)
29885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto found;
29895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
29905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
29915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->next = first_io_handler;
29925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        first_io_handler = ioh;
29935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    found:
29945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd = fd;
29955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_read_poll = fd_read_poll;
29965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_read = fd_read;
29975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->fd_write = fd_write;
29985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->opaque = opaque;
29995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ioh->deleted = 0;
30005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
30025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_set_fd_handler(int fd,
30055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        IOHandler *fd_read,
30065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        IOHandler *fd_write,
30075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        void *opaque)
30085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
30105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
30135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
30145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Polling handling */
30155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct PollingEntry {
30175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingFunc *func;
30185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
30195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct PollingEntry *next;
30205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} PollingEntry;
30215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic PollingEntry *first_polling_entry;
30235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_add_polling_cb(PollingFunc *func, void *opaque)
30255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry **ppe, *pe;
30275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe = qemu_mallocz(sizeof(PollingEntry));
30285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe->func = func;
30295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pe->opaque = opaque;
30305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
30315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *ppe = pe;
30325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
30335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_polling_cb(PollingFunc *func, void *opaque)
30365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry **ppe, *pe;
30385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
30395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pe = *ppe;
30405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (pe->func == func && pe->opaque == opaque) {
30415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *ppe = pe->next;
30425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(pe);
30435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
30445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
30455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
30495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Wait objects support */
30505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct WaitObjects {
30515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int num;
30525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
30535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
30545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
30555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} WaitObjects;
30565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic WaitObjects wait_objects = {0};
30585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
30605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjects *w = &wait_objects;
30625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (w->num >= MAXIMUM_WAIT_OBJECTS)
30645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
30655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->events[w->num] = handle;
30665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->func[w->num] = func;
30675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->opaque[w->num] = opaque;
30685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    w->num++;
30695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
30705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
30735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i, found;
30755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    WaitObjects *w = &wait_objects;
30765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    found = 0;
30785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < w->num; i++) {
30795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (w->events[i] == handle)
30805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            found = 1;
30815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (found) {
30825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->events[i] = w->events[i + 1];
30835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->func[i] = w->func[i + 1];
30845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            w->opaque[i] = w->opaque[i + 1];
30855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
30865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
30875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (found)
30885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        w->num--;
30895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
30905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
30915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
30935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* ram save/restore */
30945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
30965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
30975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int v;
30985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
30995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    v = qemu_get_byte(f);
31005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch(v) {
31015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 0:
31025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_get_buffer(f, buf, len) != len)
31035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EIO;
31045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
31055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 1:
31065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        v = qemu_get_byte(f);
31075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(buf, v, len);
31085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
31095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
31105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
31115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_file_has_error(f))
31145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EIO;
31155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
31175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load_v1(QEMUFile *f, void *opaque)
31205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
31225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t i;
31235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_get_be32(f) != last_ram_offset)
31255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
31265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
31275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
31285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret)
31295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return ret;
31305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
31325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define BDRV_HASH_BLOCK_SIZE 1024
31355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define IOBUF_SIZE 4096
31365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_CBLOCK_MAGIC 0xfabe
31375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct RamDecompressState {
31395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    z_stream zstream;
31405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUFile *f;
31415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t buf[IOBUF_SIZE];
31425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} RamDecompressState;
31435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
31455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
31475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(s, 0, sizeof(*s));
31485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->f = f;
31495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = inflateInit(&s->zstream);
31505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret != Z_OK)
31515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
31525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
31535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
31565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, clen;
31585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->zstream.avail_out = len;
31605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->zstream.next_out = buf;
31615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (s->zstream.avail_out > 0) {
31625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (s->zstream.avail_in == 0) {
31635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
31645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
31655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            clen = qemu_get_be16(s->f);
31665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (clen > IOBUF_SIZE)
31675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -1;
31685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_get_buffer(s->f, s->buf, clen);
31695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->zstream.avail_in = clen;
31705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->zstream.next_in = s->buf;
31715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
31725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
31735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret != Z_OK && ret != Z_STREAM_END) {
31745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
31755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
31765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
31775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
31785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void ram_decompress_close(RamDecompressState *s)
31815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    inflateEnd(&s->zstream);
31835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
31845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_FULL	0x01
31865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_COMPRESS	0x02
31875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_MEM_SIZE	0x04
31885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_PAGE	0x08
31895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define RAM_SAVE_FLAG_EOS	0x10
31905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int is_dup_page(uint8_t *page, uint8_t ch)
31925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
31935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
31945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t *array = (uint32_t *)page;
31955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
31965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
31975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
31985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (array[i] != val)
31995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
32005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
32035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_save_block(QEMUFile *f)
32065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static ram_addr_t current_addr = 0;
32085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t saved_addr = current_addr;
32095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr = 0;
32105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int found = 0;
32115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (addr < last_ram_offset) {
32135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
32145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t *p;
32155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_physical_memory_reset_dirty(current_addr,
32175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            current_addr + TARGET_PAGE_SIZE,
32185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            MIGRATION_DIRTY_FLAG);
32195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = qemu_get_ram_ptr(current_addr);
32215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (is_dup_page(p, *p)) {
32235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
32245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_byte(f, *p);
32255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
32265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
32275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
32285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
32295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            found = 1;
32315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
32325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr += TARGET_PAGE_SIZE;
32345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        current_addr = (saved_addr + addr) % last_ram_offset;
32355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return found;
32385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint64_t bytes_transferred = 0;
32415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic ram_addr_t ram_save_remaining(void)
32435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
32455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t count = 0;
32465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
32485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
32495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            count++;
32505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return count;
32535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_remaining(void)
32565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ram_save_remaining() * TARGET_PAGE_SIZE;
32585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_transferred(void)
32615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return bytes_transferred;
32635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t ram_bytes_total(void)
32665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return last_ram_offset;
32685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
32695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_save_live(QEMUFile *f, int stage, void *opaque)
32715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
32725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
32735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t bytes_transferred_last;
32745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    double bwidth = 0;
32755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t expected_time = 0;
32765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX);
32785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (stage == 1) {
32805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Make sure all dirty bits are set */
32815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
32825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
32835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cpu_physical_memory_set_dirty(addr);
32845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
32855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Enable dirty memory tracking */
32875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(1);
32885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
32905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
32915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bytes_transferred_last = bytes_transferred;
32935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bwidth = get_clock();
32945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_file_rate_limit(f)) {
32965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
32975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
32985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = ram_save_block(f);
32995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bytes_transferred += ret * TARGET_PAGE_SIZE;
33005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == 0) /* no more blocks */
33015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
33025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bwidth = get_clock() - bwidth;
33055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
33065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* if we haven't transferred anything this round, force expected_time to a
33085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * a very high value, but without crashing */
33095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bwidth == 0)
33105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bwidth = 0.000001;
33115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* try transferring iterative blocks of memory */
33135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (stage == 3) {
33155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* flush all remaining blocks regardless of rate limiting */
33175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (ram_save_block(f) != 0) {
33185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bytes_transferred += TARGET_PAGE_SIZE;
33195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_physical_memory_set_dirty_tracking(0);
33215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
33245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
33265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return (stage == 2) && (expected_time <= migrate_max_downtime());
33285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
33295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load_dead(QEMUFile *f, void *opaque)
33315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
33325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    RamDecompressState s1, *s = &s1;
33335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t buf[10];
33345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t i;
33355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ram_decompress_open(s, f) < 0)
33375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
33385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
33395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ram_decompress_buf(s, buf, 1) < 0) {
33405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Error while reading ram block header\n");
33415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto error;
33425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (buf[0] == 0) {
33445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
33455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                   BDRV_HASH_BLOCK_SIZE) < 0) {
33465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
33475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto error;
33485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
33495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
33505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        error:
33515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf("Error block header\n");
33525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EINVAL;
33535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_decompress_close(s);
33565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
33585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
33595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int ram_load(QEMUFile *f, void *opaque, int version_id)
33615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
33625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_addr_t addr;
33635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
33645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id == 1)
33665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ram_load_v1(f, opaque);
33675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id == 2) {
33695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_get_be32(f) != last_ram_offset)
33705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -EINVAL;
33715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ram_load_dead(f, opaque);
33725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
33735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (version_id != 3)
33755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -EINVAL;
33765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
33785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr = qemu_get_be64(f);
33795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        flags = addr & ~TARGET_PAGE_MASK;
33815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr &= TARGET_PAGE_MASK;
33825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
33845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (addr != last_ram_offset)
33855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -EINVAL;
33865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
33875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
33885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_FULL) {
33895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ram_load_dead(f, opaque) < 0)
33905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return -EINVAL;
33915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
3392d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
33935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (flags & RAM_SAVE_FLAG_COMPRESS) {
33945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t ch = qemu_get_byte(f);
33955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
33965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (flags & RAM_SAVE_FLAG_PAGE)
33975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
33985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (!(flags & RAM_SAVE_FLAG_EOS));
33995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
34015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_service_io(void)
34045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
34065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
34095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* bottom halves (can be seen as timers which expire ASAP) */
34105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct QEMUBH {
34125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBHFunc *cb;
34135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
34145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int scheduled;
34155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int idle;
34165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int deleted;
34175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *next;
34185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
34195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUBH *first_bh = NULL;
34215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
34235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh;
34255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh = qemu_mallocz(sizeof(QEMUBH));
34265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->cb = cb;
34275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->opaque = opaque;
34285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->next = first_bh;
34295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    first_bh = bh;
34305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return bh;
34315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_bh_poll(void)
34345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh, **bhp;
34365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
34375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = 0;
34395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (bh = first_bh; bh; bh = bh->next) {
34405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!bh->deleted && bh->scheduled) {
34415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->scheduled = 0;
34425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!bh->idle)
34435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ret = 1;
34445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->idle = 0;
34455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bh->cb(bh->opaque);
34465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
34475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
34485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* remove deleted bhs */
34505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bhp = &first_bh;
34515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*bhp) {
34525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bh = *bhp;
34535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bh->deleted) {
34545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *bhp = bh->next;
34555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(bh);
34565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
34575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            bhp = &bh->next;
34585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
34595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
34615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_schedule_idle(QEMUBH *bh)
34645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bh->scheduled)
34665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
34675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 1;
34685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->idle = 1;
34695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_schedule(QEMUBH *bh)
34725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (bh->scheduled)
34745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
34755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 1;
34765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->idle = 0;
34775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* stop the currently executing CPU to execute the BH ASAP */
34785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
34795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_cancel(QEMUBH *bh)
34825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 0;
34845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_bh_delete(QEMUBH *bh)
34875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->scheduled = 0;
34895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bh->deleted = 1;
34905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
34915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_bh_update_timeout(int *timeout)
34935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
34945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUBH *bh;
34955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
34965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (bh = first_bh; bh; bh = bh->next) {
34975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!bh->deleted && bh->scheduled) {
34985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (bh->idle) {
34995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* idle bottom halves will be polled at least
35005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 * every 10ms */
35015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *timeout = MIN(10, *timeout);
35025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
35035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* non-idle bottom halves will be executed
35045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 * immediately */
35055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *timeout = 0;
35065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
35075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
35085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
35095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
35135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* machine registration */
35145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *first_machine = NULL;
35165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQEMUMachine *current_machine = NULL;
35175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_register_machine(QEMUMachine *m)
35195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine **pm;
35215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pm = &first_machine;
35225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pm != NULL)
35235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pm = &(*pm)->next;
35245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    m->next = NULL;
35255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pm = m;
35265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
35275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_machine(const char *name)
35305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
35325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
35345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(m->name, name))
35355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
35365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
35385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUMachine *find_default_machine(void)
35415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *m;
35435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(m = first_machine; m != NULL; m = m->next) {
35455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (m->is_default) {
35465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return m;
35475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
35485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
35505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/***********************************************************/
35535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* main execution loop */
35545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gui_update(void *opaque)
35565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
35585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds = opaque;
35595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl = ds->listeners;
35605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_refresh(ds);
35625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
35645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->gui_timer_interval &&
35655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dcl->gui_timer_interval < interval)
35665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            interval = dcl->gui_timer_interval;
35675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
35685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
35705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void nographic_update(void *opaque)
35735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint64_t interval = GUI_REFRESH_INTERVAL;
35755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
35775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct vm_change_state_entry {
35805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateHandler *cb;
35815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
3582a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_ENTRY (vm_change_state_entry) entries;
35835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
35845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3585a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turnerstatic QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
35865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerVMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
35885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                                     void *opaque)
35895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
35915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e = qemu_mallocz(sizeof (*e));
35935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->cb = cb;
35955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    e->opaque = opaque;
3596a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
35975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return e;
35985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
35995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
36015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3602a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_REMOVE (e, entries);
36035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free (e);
36045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void vm_state_notify(int running, int reason)
36075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    VMChangeStateEntry *e;
36095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
36115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        e->cb(e->opaque, running, reason);
36125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void);
36165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void);
36175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_start(void)
36195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vm_running) {
36215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_enable_ticks();
36225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_running = 1;
36235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_state_notify(1, 0);
36245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_rearm_alarm_timer(alarm_timer);
36255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        resume_all_vcpus();
36265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* reset/shutdown handler */
36305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUResetEntry {
36325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetHandler *func;
36335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    void *opaque;
36345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int order;
36355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct QEMUResetEntry *next;
36365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUResetEntry;
36375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUResetEntry *first_reset_entry;
36395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int reset_requested;
36405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int shutdown_requested;
36415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int powerdown_requested;
36425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int debug_requested;
36435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vmstop_requested;
36445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_shutdown_requested(void)
36465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = shutdown_requested;
36485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 0;
36495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
36505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_reset_requested(void)
36535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = reset_requested;
36555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    reset_requested = 0;
36565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
36575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_powerdown_requested(void)
36605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = powerdown_requested;
36625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 0;
36635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
36645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_debug_requested(void)
36675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = debug_requested;
36695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    debug_requested = 0;
36705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
36715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_vmstop_requested(void)
36745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r = vmstop_requested;
36765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = 0;
36775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return r;
36785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void do_vm_stop(int reason)
36815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (vm_running) {
36835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_disable_ticks();
36845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_running = 0;
36855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pause_all_vcpus();
36865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_state_notify(0, reason);
36875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
36915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
36925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry **pre, *re;
36935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pre = &first_reset_entry;
36955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*pre != NULL && (*pre)->order >= order) {
36965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pre = &(*pre)->next;
36975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
36985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re = qemu_mallocz(sizeof(QEMUResetEntry));
36995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->func = func;
37005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->opaque = opaque;
37015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->order = order;
37025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    re->next = NULL;
37035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *pre = re;
37045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset(void)
37075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUResetEntry *re;
37095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* reset all devices */
37115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(re = first_reset_entry; re != NULL; re = re->next) {
37125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        re->func(re->opaque);
37135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
37145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_reset_request(void)
37175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (no_reboot) {
37195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        shutdown_requested = 1;
37205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
37215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        reset_requested = 1;
37225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
37235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
37245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_shutdown_request(void)
37275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    shutdown_requested = 1;
37295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
37305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_system_powerdown_request(void)
37335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    powerdown_requested = 1;
37355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
37365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
37395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_system_vmstop_request(int reason)
37405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmstop_requested = reason;
37425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_notify_event();
37435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
37455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
37475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int io_thread_fd = -1;
37485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_increment(void)
37505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static const char byte = 0;
37525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (io_thread_fd == -1)
37545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
37555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    write(io_thread_fd, &byte, sizeof(byte));
37575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_read(void *opaque)
37605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd = (unsigned long)opaque;
37625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ssize_t len;
37635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Drain the notify pipe */
37655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
37665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        char buffer[512];
37675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = read(fd, buffer, sizeof(buffer));
37685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while ((len == -1 && errno == EINTR) || len > 0);
37695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_event_init(void)
37725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
37735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int err;
37745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fds[2];
37755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = pipe(fds);
37775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err == -1)
37785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -errno;
37795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = fcntl_setfl(fds[0], O_NONBLOCK);
37815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err < 0)
37825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
37835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    err = fcntl_setfl(fds[1], O_NONBLOCK);
37855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (err < 0)
37865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto fail;
37875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
37895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         (void *)(unsigned long)fds[0]);
37905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    io_thread_fd = fds[1];
37925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
37935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
37945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfail:
37955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fds[0]);
37965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(fds[1]);
37975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return err;
37985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
37995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
38005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerHANDLE qemu_event_handle;
38015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void dummy_event_handler(void *opaque)
38035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_event_init(void)
38075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
38095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_event_handle) {
38105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        perror("Failed CreateEvent");
38115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
38125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
38135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
38145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
38155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_event_increment(void)
38185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SetEvent(qemu_event_handle);
38205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_can_run(CPUState *env)
38245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop)
38265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
38275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stopped)
38285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
38295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
38305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
38335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_init_main_loop(void)
38345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return qemu_event_init();
38365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_init_vcpu(void *_env)
38395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
38415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
38435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kvm_init_vcpu(env);
38445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
38455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_cpu_self(void *env)
38485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
38505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void)
38535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void)
38575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_cpu_kick(void *env)
38615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
38635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_notify_event(void)
38665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = cpu_single_env;
38685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env) {
38705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_exit(env);
38715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef USE_KQEMU
38725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (env->kqemu_enabled)
38735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            kqemu_cpu_interrupt(env);
38745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
38755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     }
38765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define qemu_mutex_lock_iothread() do { } while (0)
38795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define qemu_mutex_unlock_iothread() do { } while (0)
38805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_stop(int reason)
38825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
38835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do_vm_stop(reason);
38845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
38855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* CONFIG_IOTHREAD */
38875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-thread.h"
38895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerQemuMutex qemu_global_mutex;
38915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuMutex qemu_fair_mutex;
38925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuThread io_thread;
38945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuThread *tcg_cpu_thread;
38965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond *tcg_halt_cond;
38975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
38985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_system_ready;
38995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* cpu creation */
39005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_cpu_cond;
39015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* system init */
39025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_system_cond;
39035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QemuCond qemu_pause_cond;
39045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void block_io_signals(void);
39065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unblock_io_signals(void);
39075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tcg_has_work(void);
39085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_init_main_loop(void)
39105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
39115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
39125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = qemu_event_init();
39145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret)
39155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret;
39165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_init(&qemu_pause_cond);
39185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_init(&qemu_fair_mutex);
39195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_init(&qemu_global_mutex);
39205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
39215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unblock_io_signals();
39235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(&io_thread);
39245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
39265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
39275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_wait_io_event(CPUState *env)
39295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
39305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!tcg_has_work())
39315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
39325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_global_mutex);
39345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /*
39365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * Users of qemu_global_mutex can be starved, having no chance
39375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * to acquire it since this path will get to it first.
39385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     * So use another lock to provide fairness.
39395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     */
39405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_fair_mutex);
39415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_fair_mutex);
39425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
39445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop) {
39455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->stop = 0;
39465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->stopped = 1;
39475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_signal(&qemu_pause_cond);
39485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
39505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env);
39525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *kvm_cpu_thread_fn(void *arg)
39545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
39555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = arg;
39565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    block_io_signals();
39585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(env->thread);
39595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* signal CPU creation */
39615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
39625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->created = 1;
39635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_signal(&qemu_cpu_cond);
39645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* and wait for machine initialization */
39665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_system_ready)
39675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
39685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
39705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_can_run(env))
39715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_cpu_exec(env);
39725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_wait_io_event(env);
39735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
39745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
39765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
39775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_cpu_exec(void);
39795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void *tcg_cpu_thread_fn(void *arg)
39815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
39825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = arg;
39835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    block_io_signals();
39855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(env->thread);
39865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* signal CPU creation */
39885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_global_mutex);
39895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu)
39905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->created = 1;
39915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_signal(&qemu_cpu_cond);
39925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* and wait for machine initialization */
39945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!qemu_system_ready)
39955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
39965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
39975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
39985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_cpu_exec();
39995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_wait_io_event(cur_cpu);
40005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
40035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_cpu_kick(void *_env)
40065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
40085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_broadcast(env->halt_cond);
40095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
40105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(env->thread, SIGUSR1);
40115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_cpu_self(void *env)
40145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return (cpu_single_env != NULL);
40165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void cpu_signal(int sig)
40195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (cpu_single_env)
40215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_exit(cpu_single_env);
40225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void block_io_signals(void)
40255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigset_t set;
40275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction sigact;
40285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
40305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR2);
40315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGIO);
40325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGALRM);
40335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_BLOCK, &set, NULL);
40345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
40365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR1);
40375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
40385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&sigact, 0, sizeof(sigact));
40405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigact.sa_handler = cpu_signal;
40415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGUSR1, &sigact, NULL);
40425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void unblock_io_signals(void)
40455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigset_t set;
40475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
40495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR2);
40505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGIO);
40515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGALRM);
40525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_UNBLOCK, &set, NULL);
40535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigemptyset(&set);
40555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaddset(&set, SIGUSR1);
40565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pthread_sigmask(SIG_BLOCK, &set, NULL);
40575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_signal_lock(unsigned int msecs)
40605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock(&qemu_fair_mutex);
40625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (qemu_mutex_trylock(&qemu_global_mutex)) {
40645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
40655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
40665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
40675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_fair_mutex);
40695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_mutex_lock_iothread(void)
40725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
40745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_lock(&qemu_fair_mutex);
40755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_lock(&qemu_global_mutex);
40765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mutex_unlock(&qemu_fair_mutex);
40775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else
40785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_signal_lock(100);
40795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void qemu_mutex_unlock_iothread(void)
40825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock(&qemu_global_mutex);
40845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int all_vcpus_paused(void)
40875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
40885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
40895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
40915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!penv->stopped)
40925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
40935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
40945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
40955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
40975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
40985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
40995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void pause_all_vcpus(void)
41005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
41025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
41045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stop = 1;
41055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(penv->thread, SIGUSR1);
41065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cpu_kick(penv);
41075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
41085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (!all_vcpus_paused()) {
41115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
41125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = first_cpu;
41135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (penv) {
41145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_thread_signal(penv->thread, SIGUSR1);
41155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            penv = (CPUState *)penv->next_cpu;
41165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void resume_all_vcpus(void)
41215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *penv = first_cpu;
41235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (penv) {
41255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stop = 0;
41265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv->stopped = 0;
41275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_signal(penv->thread, SIGUSR1);
41285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cpu_kick(penv);
41295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        penv = (CPUState *)penv->next_cpu;
41305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_init_vcpu(void *_env)
41345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
41365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* share a single thread for all cpus with TCG */
41375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!tcg_cpu_thread) {
41385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->thread = qemu_mallocz(sizeof(QemuThread));
41395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->halt_cond = qemu_mallocz(sizeof(QemuCond));
41405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_init(env->halt_cond);
41415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
41425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (env->created == 0)
41435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
41445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_cpu_thread = env->thread;
41455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_halt_cond = env->halt_cond;
41465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
41475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->thread = tcg_cpu_thread;
41485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->halt_cond = tcg_halt_cond;
41495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void kvm_start_vcpu(CPUState *env)
41535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
41555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kvm_init_vcpu(env);
41565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->thread = qemu_mallocz(sizeof(QemuThread));
41575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    env->halt_cond = qemu_mallocz(sizeof(QemuCond));
41585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_init(env->halt_cond);
41595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
41605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (env->created == 0)
41615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
41625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
41635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_init_vcpu(void *_env)
41665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = _env;
41685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
41705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kvm_start_vcpu(env);
41715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
41725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcg_init_vcpu(env);
41735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_notify_event(void)
41765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_event_increment();
41785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid vm_stop(int reason)
41815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
41825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QemuThread me;
41835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_thread_self(&me);
41845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
41855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!qemu_thread_equal(&me, &io_thread)) {
41865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_system_vmstop_request(reason);
41875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /*
41885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * FIXME: should not return to device code in case
41895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * vm_stop() has been requested.
41905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
41915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_single_env) {
41925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_exit(cpu_single_env);
41935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            cpu_single_env->stop = 1;
41945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
41955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
41965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
41975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do_vm_stop(reason);
41985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
41995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
42015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
42045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void host_main_loop_wait(int *timeout)
42055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
42065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, ret2, i;
42075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    PollingEntry *pe;
42085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: need to suppress polling by better using win32 events */
42115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = 0;
42125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
42135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret |= pe->func(pe->opaque);
42145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret == 0) {
42165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int err;
42175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        WaitObjects *w = &wait_objects;
42185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
42205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
42215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (w->func[ret - WAIT_OBJECT_0])
42225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
42235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Check for additional signaled events */
42255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
42265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* Check if event is signaled */
42285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ret2 = WaitForSingleObject(w->events[i], 0);
42295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(ret2 == WAIT_OBJECT_0) {
42305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (w->func[i])
42315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        w->func[i](w->opaque[i]);
42325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else if (ret2 == WAIT_TIMEOUT) {
42335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
42345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    err = GetLastError();
42355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
42365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
42375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
42385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (ret == WAIT_TIMEOUT) {
42395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
42405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = GetLastError();
42415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
42425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
42435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *timeout = 0;
42465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
42475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
42485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void host_main_loop_wait(int *timeout)
42495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
42505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
42515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
42525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid main_loop_wait(int timeout)
42545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
42555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    IOHandlerRecord *ioh;
42565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set rfds, wfds, xfds;
42575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret, nfds;
42585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct timeval tv;
42595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_update_timeout(&timeout);
42615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    host_main_loop_wait(&timeout);
42635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* poll any events */
42655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: separate device handlers from system ones */
42665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nfds = -1;
42675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&rfds);
42685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&wfds);
42695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&xfds);
42705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
42715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->deleted)
42725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
42735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->fd_read &&
42745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            (!ioh->fd_read_poll ||
42755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             ioh->fd_read_poll(ioh->opaque) != 0)) {
42765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_SET(ioh->fd, &rfds);
42775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd > nfds)
42785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nfds = ioh->fd;
42795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
42805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ioh->fd_write) {
42815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_SET(ioh->fd, &wfds);
42825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->fd > nfds)
42835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nfds = ioh->fd;
42845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
42855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tv.tv_sec = timeout / 1000;
42885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tv.tv_usec = (timeout % 1000) * 1000;
42895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
42905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
42915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
42925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
42935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
42945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
42955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_unlock_iothread();
42965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
42975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_mutex_lock_iothread();
42985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret > 0) {
42995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        IOHandlerRecord **pioh;
43005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
43025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
43035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->fd_read(ioh->opaque);
43045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
43055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
43065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ioh->fd_write(ioh->opaque);
43075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
43085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* remove deleted IO handlers */
43115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pioh = &first_io_handler;
43125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	while (*pioh) {
43135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ioh = *pioh;
43145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (ioh->deleted) {
43155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                *pioh = ioh->next;
43165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_free(ioh);
43175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
43185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pioh = &ioh->next;
43195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SLIRP)
43225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (slirp_is_inited()) {
43235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
43245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&rfds);
43255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&wfds);
43265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            FD_ZERO(&xfds);
43275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
43285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slirp_select_poll(&rfds, &wfds, &xfds);
43295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    charpipe_poll();
43325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* rearm timer, if not periodic */
43345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
43355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
43365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_rearm_alarm_timer(alarm_timer);
43375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* vm time timers */
43405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (vm_running) {
43415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
4342a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
43435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_get_clock(vm_clock));
43445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
43455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* real time timers */
4347a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
43485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    qemu_get_clock(rt_clock));
43495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4350a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
4351a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner                    qemu_get_clock(host_clock));
4352a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
43535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Check bottom-halves last in case any of the earlier events triggered
43545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       them.  */
43555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_bh_poll();
43565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
43585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_cpu_exec(CPUState *env)
43605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
43615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
43625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
43635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t ti;
43645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
43665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
43675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ti = profile_getclock();
43685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount) {
43705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int64_t count;
43715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int decr;
43725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
43735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u16.low = 0;
43745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = 0;
43755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count = qemu_next_deadline();
43765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count = (count + (1 << icount_time_shift) - 1)
43775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                >> icount_time_shift;
43785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount += count;
43795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        decr = (count > 0xffff) ? 0xffff : count;
43805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count -= decr;
43815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u16.low = decr;
43825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = count;
43835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
4384a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner#ifdef CONFIG_TRACE
4385a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner    if (tbflush_requested) {
4386a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        tbflush_requested = 0;
4387a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        tb_flush(env);
4388a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner        return EXCP_INTERRUPT;
4389a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner    }
4390a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner#endif
4391a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner
4392a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner
43935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = cpu_exec(env);
43945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
43955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_time += profile_getclock() - ti;
43965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
43975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount) {
43985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Fold pending instructions back into the
43995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           instruction counter, and clear the interrupt flag.  */
44005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_icount -= (env->icount_decr.u16.low
44015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        + env->icount_extra);
44025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_decr.u32 = 0;
44035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->icount_extra = 0;
44045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
44065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
44075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void tcg_cpu_exec(void)
44095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
44105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret = 0;
44115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (next_cpu == NULL)
44135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        next_cpu = first_cpu;
44145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
44155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        CPUState *env = cur_cpu = next_cpu;
44165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!vm_running)
44185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
44195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (timer_alarm_pending) {
44205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            timer_alarm_pending = 0;
44215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
44225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_can_run(env))
44245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ret = qemu_cpu_exec(env);
44255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == EXCP_DEBUG) {
44265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_set_stop_cpu(env);
44275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            debug_requested = 1;
44285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
44295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
44315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
44325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_has_work(CPUState *env)
44345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
44355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stop)
44365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
44375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->stopped)
44385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
44395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!env->halted)
44405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
44415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_cpu_has_work(env))
44425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
44435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
44445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
44455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int tcg_has_work(void)
44475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
44485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
44495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu)
44515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_has_work(env))
44525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 1;
44535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
44545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
44555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int qemu_calculate_timeout(void)
44575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
44585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
44595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int timeout;
44605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
44615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!vm_running)
44625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timeout = 5000;
44635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (tcg_has_work())
44645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timeout = 0;
44655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!use_icount)
44665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        timeout = 5000;
44675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else {
44685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner     /* XXX: use timeout computed from timers */
44695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int64_t add;
44705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int64_t delta;
44715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Advance virtual time to the next event.  */
44725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (use_icount == 1) {
44735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* When not using an adaptive execution frequency
44745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               we tend to get badly out of sync with real time,
44755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               so just delay for a reasonable amount of time.  */
44765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta = 0;
44775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
44785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta = cpu_get_icount() - cpu_get_clock();
44795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
44805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (delta > 0) {
44815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* If virtual time is ahead of real time then just
44825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               wait for IO.  */
44835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            timeout = (delta / 1000000) + 1;
44845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
44855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Wait for either IO to occur or the next
44865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               timer event.  */
44875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            add = qemu_next_deadline();
44885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* We advance the timer before checking for IO.
44895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               Limit the amount we advance so that early IO
44905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner               activity won't get the guest too far ahead.  */
44915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (add > 10000000)
44925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                add = 10000000;
44935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            delta += add;
44945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            add = (add + (1 << icount_time_shift) - 1)
44955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                  >> icount_time_shift;
44965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_icount += add;
44975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            timeout = delta / 1000000;
44985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (timeout < 0)
44995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                timeout = 0;
45005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
45015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
45025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return timeout;
45045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* CONFIG_IOTHREAD */
45055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1000;
45065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
45085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vm_can_run(void)
45105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
45115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (powerdown_requested)
45125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
45135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reset_requested)
45145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
45155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (shutdown_requested)
45165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
45175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (debug_requested)
45185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
45195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1;
45205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
45215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void main_loop(void)
45235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
45245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int r;
45255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_IOTHREAD
45275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_system_ready = 1;
45285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cond_broadcast(&qemu_system_cond);
45295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (;;) {
45325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        do {
45335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
45345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            int64_t ti;
45355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_IOTHREAD
45375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tcg_cpu_exec();
45385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
45405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ti = profile_getclock();
45415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            main_loop_wait(qemu_calculate_timeout());
45435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_PROFILER
45445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            dev_time += profile_getclock() - ti;
45455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
45465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } while (vm_can_run());
45475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_debug_requested())
45495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(EXCP_DEBUG);
45505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_shutdown_requested()) {
45515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (no_shutdown) {
45525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vm_stop(0);
45535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 0;
45545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
45555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
45565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
45575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_reset_requested()) {
45585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pause_all_vcpus();
45595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_reset();
45605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            resume_all_vcpus();
45615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
45625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (qemu_powerdown_requested())
45635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_system_powerdown();
45645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((r = qemu_vmstop_requested()))
45655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_stop(r);
45665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
45675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    pause_all_vcpus();
45685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
45695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45707fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinevoid version(void)
45715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
45725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
45735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
45745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_help(int exitcode)
45765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
45775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    version();
45785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("usage: %s [options] [disk_image]\n"
45795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
45805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
45815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
45825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
45835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           opt_help
45845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text) stringify(text) "\n"
45855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
45865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
45875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
45885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
45895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
45905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "During emulation, the following keys are useful:\n"
45915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-f      toggle full screen\n"
45925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt-n      switch to virtual console 'n'\n"
45935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "ctrl-alt        toggle mouse and keyboard grab\n"
45945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "\n"
45955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "When using -nographic, press 'ctrl-a h' to get some help.\n"
45965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           ,
45975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "qemu",
45985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_RAM_SIZE,
45995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
46005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_SCRIPT,
46015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_NETWORK_DOWN_SCRIPT,
46025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           DEFAULT_GDBSTUB_PORT,
46045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           "/tmp/qemu.log");
46055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    exit(exitcode);
46065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
46075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define HAS_ARG 0x0001
46095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum {
46115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
46125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    opt_enum,
46135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
46145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
46155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
46165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
46175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
46185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
46195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct QEMUOption {
46215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *name;
46225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int flags;
46235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int index;
46245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} QEMUOption;
46255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const QEMUOption qemu_options[] = {
46275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { "h", 0, QEMU_OPTION_h },
46285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEF(option, opt_arg, opt_enum, opt_help)        \
46295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { option, opt_arg, opt_enum },
46305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define DEFHEADING(text)
46315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-options.h"
46325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEF
46335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef DEFHEADING
46345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef GEN_DOCS
46355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL, 0, 0 },
46365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
46375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO
46395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct soundhw soundhw[] = {
46405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO_CHOICE
46415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_I386) || defined(TARGET_MIPS)
46425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "pcspk",
46445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "PC speaker",
46455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
46465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
46475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = pcspk_audio_init }
46485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
46495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SB16
46525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "sb16",
46545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Creative Sound Blaster 16",
46555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
46565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
46575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = SB16_init }
46585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
46595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_CS4231A
46625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "cs4231a",
46645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "CS4231A",
46655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
46665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
46675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = cs4231a_init }
46685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
46695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_ADLIB
46725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "adlib",
46745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_YMF262
46755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Yamaha YMF262 (OPL3)",
46765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
46775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Yamaha YM3812 (OPL2)",
46785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
46805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
46815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = Adlib_init }
46825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
46835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_GUS
46865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "gus",
46885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Gravis Ultrasound GF1",
46895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
46905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        1,
46915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_isa = GUS_init }
46925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
46935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
46945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
46955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_AC97
46965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
46975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "ac97",
46985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "Intel 82801AA AC97 Audio",
46995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
47005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
47015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_pci = ac97_init }
47025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
47035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_ES1370
47065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
47075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "es1370",
47085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        "ENSONIQ AudioPCI ES1370",
47095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
47105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        0,
47115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        { .init_pci = es1370_init }
47125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
47135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* HAS_AUDIO_CHOICE */
47165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL, NULL, 0, 0, { NULL } }
47185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
47195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void select_soundhw (const char *optarg)
47215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
47225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct soundhw *c;
47235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (*optarg == '?') {
47255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    show_valid_cards:
47265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        printf ("Valid sound card names (comma separated):\n");
47285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (c = soundhw; c->name; ++c) {
47295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf ("%-11s %s\n", c->name, c->descr);
47305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
47315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        printf ("\n-soundhw all will enable all of the above\n");
47325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit (*optarg != '?');
47335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
47345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else {
47355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        size_t l;
47365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *p;
47375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        char *e;
47385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int bad_card = 0;
47395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp (optarg, "all")) {
47415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (c = soundhw; c->name; ++c) {
47425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                c->enabled = 1;
47435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
47445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return;
47455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
47465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = optarg;
47485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        while (*p) {
47495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            e = strchr (p, ',');
47505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            l = !e ? strlen (p) : (size_t) (e - p);
47515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (c = soundhw; c->name; ++c) {
47535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strncmp (c->name, p, l)) {
47545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    c->enabled = 1;
47555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
47565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
47575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
47585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!c->name) {
47605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (l > 80) {
47615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf (stderr,
47625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             "Unknown sound card name (too big to show)\n");
47635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
47645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else {
47655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
47665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             (int) l, p);
47675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
47685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bad_card = 1;
47695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
47705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p += l + (e != NULL);
47715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
47725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bad_card)
47745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto show_valid_cards;
47755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
47765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
47775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
47785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void select_vgahw (const char *p)
47805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
47815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *opts;
47825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
47835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cirrus_vga_enabled = 0;
47845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    std_vga_enabled = 0;
47855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    vmsvga_enabled = 0;
47865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    xenfb_enabled = 0;
47875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(p, "std", &opts)) {
47885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        std_vga_enabled = 1;
47895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "cirrus", &opts)) {
47905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cirrus_vga_enabled = 1;
47915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "vmware", &opts)) {
47925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vmsvga_enabled = 1;
47935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (strstart(p, "xenfb", &opts)) {
47945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        xenfb_enabled = 1;
47955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strstart(p, "none", &opts)) {
47965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    invalid_vga:
47975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Unknown vga type: %s\n", p);
47985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
47995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
48005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*opts) {
48015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *nextopt;
48025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strstart(opts, ",retrace=", &nextopt)) {
48045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            opts = nextopt;
48055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(opts, "dumb", &nextopt))
48065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_DUMB;
48075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else if (strstart(opts, "precise", &nextopt))
48085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                vga_retrace_method = VGA_RETRACE_PRECISE;
48095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else goto invalid_vga;
48105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else goto invalid_vga;
48115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        opts = nextopt;
48125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
48135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
48165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BOOL WINAPI qemu_ctrl_handler(DWORD type)
48175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    exit(STATUS_CONTROL_C_EXIT);
48195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return TRUE;
48205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
48225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint qemu_uuid_parse(const char *str, uint8_t *uuid)
48245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
48265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(strlen(str) != 36)
48285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
48295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
48315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
48325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
48335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if(ret != 16)
48355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
48365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
48385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
48395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
48405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
48425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_NET_CLIENTS 32
48455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
48475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void termsig_handler(int signal)
48495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_system_shutdown_request();
48515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void sigchld_handler(int signal)
48545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    waitpid(-1, NULL, WNOHANG);
48565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void sighandler_setup(void)
48595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sigaction act;
48615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&act, 0, sizeof(act));
48635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = termsig_handler;
48645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGINT,  &act, NULL);
48655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGHUP,  &act, NULL);
48665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGTERM, &act, NULL);
48675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_handler = sigchld_handler;
48695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    act.sa_flags = SA_NOCLDSTOP;
48705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sigaction(SIGCHLD, &act, NULL);
48715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
48745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
48765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Look for support files in the same directory as the executable.  */
48775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
48785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
48795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p;
48805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[MAX_PATH];
48815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DWORD len;
48825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
48845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (len == 0) {
48855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
48865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
48875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
48885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf[len] = 0;
48895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = buf + len - 1;
48905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (p != buf && *p != '\\')
48915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p--;
48925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *p = 0;
48935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(buf, R_OK) == 0) {
48945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return qemu_strdup(buf);
48955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
48965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
48975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
48985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* !_WIN32 */
48995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Find a likely location for support files using the location of the binary.
49015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   For installed binaries this will be "$bindir/../share/qemu".  When
49025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   running from the build tree this will be "$bindir/../pc-bios".  */
49035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define SHARE_SUFFIX "/share/qemu"
49045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define BUILD_SUFFIX "/pc-bios"
49055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic char *find_datadir(const char *argv0)
49065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
49075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *dir;
49085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p = NULL;
49095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *res;
49105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef PATH_MAX
49115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[PATH_MAX];
49125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
49135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    size_t max_len;
49145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(__linux__)
49165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
49175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
49185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
49195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
49205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
49215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
49225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
49235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(__FreeBSD__)
49255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
49265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int len;
49275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
49285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len > 0) {
49295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            buf[len] = 0;
49305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p = buf;
49315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
49325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
49345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If we don't have any way of figuring out the actual executable
49355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       location then try argv[0].  */
49365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!p) {
49375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef PATH_MAX
49385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = buf;
49395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
49405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = realpath(argv0, p);
49415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!p) {
49425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return NULL;
49435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
49445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dir = dirname(p);
49465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dir = dirname(dir);
49475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_len = strlen(dir) +
49495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
49505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    res = qemu_mallocz(max_len);
49515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
49525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(res, R_OK)) {
49535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
49545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (access(res, R_OK)) {
49555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_free(res);
49565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            res = NULL;
49575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
49585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef PATH_MAX
49605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free(p);
49615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
49625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return res;
49635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
49645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef SHARE_SUFFIX
49655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef BUILD_SUFFIX
49665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
49675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *qemu_find_file(int type, const char *name)
49695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
49705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int len;
49715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *subdir;
49725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *buf;
49735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If name contains path separators then try it as a straight path.  */
49755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((strchr(name, '/') || strchr(name, '\\'))
49765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        && access(name, R_OK) == 0) {
49775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return strdup(name);
49785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (type) {
49805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_BIOS:
49815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "";
49825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
49835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case QEMU_FILE_TYPE_KEYMAP:
49845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        subdir = "keymaps/";
49855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
49865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
49875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        abort();
49885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
49905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf = qemu_mallocz(len);
49915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
49925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (access(buf, R_OK)) {
49935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_free(buf);
49945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
49955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
49965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return buf;
49975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
49985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
49997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinestatic int
50007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkineadd_dns_server( const char*  server_name )
50017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine{
50027fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    SockAddress   addr;
50037fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50047fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (sock_address_init_resolve( &addr, server_name, 55, 0 ) < 0) {
50057fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stdout,
50067fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: can't resolve DNS server name '%s'\n",
50077fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                server_name );
50087fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
50097fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
50107fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    fprintf(stderr,
50127fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            "DNS server name '%s' resolved to %s\n", server_name, sock_address_to_string(&addr) );
50137fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50147fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if ( slirp_add_dns_server( &addr ) < 0 ) {
50157fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        fprintf(stderr,
50167fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                "### WARNING: could not add DNS server '%s' to the network stack\n", server_name);
50177fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        return -1;
50187fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
50197fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    return 0;
50207fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine}
50217fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50227fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine/* Appends a parameter to a string of parameters separated with space.
50237fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine * Pararm:
50247fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  param_str String containing parameters separated with space.
50257fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  param Parameter to append to the string.
50267fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine *  size - Size (in characters) of the buffer addressed by param_str.
50277fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine */
50287fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkinestatic void
50297fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkineappend_param(char* param_str, const char* arg, int size)
50307fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine{
50317fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (*param_str) {
50327fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncat(param_str, " ", size);
50337fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncat(param_str, arg, size);
50347fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    } else {
50357fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncpy(param_str, arg, size);
50367fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        param_str[size - 1] = '\0';
50377fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
50387fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine}
50397fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
50405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint main(int argc, char **argv, char **envp)
50415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
50425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *gdbstub_dev = NULL;
50435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t boot_devices_bitmap = 0;
50445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
50455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int snapshot, linux_boot, net_boot;
50465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *initrd_filename;
50475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *kernel_filename, *kernel_cmdline;
50485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *boot_devices = "";
50495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayState *ds;
50505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    DisplayChangeListener *dcl;
50515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int cyls, heads, secs, translation;
50525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *net_clients[MAX_NET_CLIENTS];
50535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_net_clients;
50545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *bt_opts[MAX_BT_CMDLINE];
50555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int nb_bt_opts;
50565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int hda_index;
50575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int optind;
50585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *r, *optarg;
50595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *monitor_hd = NULL;
50605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *monitor_device;
50615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *serial_devices[MAX_SERIAL_PORTS];
50625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int serial_device_index;
50635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *parallel_devices[MAX_PARALLEL_PORTS];
50645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int parallel_device_index;
50655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
50665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int virtio_console_index;
50675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *loadvm = NULL;
50685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    QEMUMachine *machine;
50695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *cpu_model;
50705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *usb_devices[MAX_USB_CMDLINE];
50715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int usb_devices_index;
50725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
50735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fds[2];
50745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
50755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int tb_size;
50765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *pid_file = NULL;
50775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *incoming = NULL;
50785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
50795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int fd = 0;
50805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct passwd *pwd = NULL;
50815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *chroot_dir = NULL;
50825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *run_as = NULL;
50835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
50845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
50855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int show_vnc_port = 0;
5086074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
5087074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    IniFile*  hw_ini = NULL;
5088074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
50897fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Container for the kernel initialization parameters collected in this
50907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * routine. */
50917fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char kernel_cmdline_append[1024];
50927fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Combines kernel initialization parameters passed from the UI with
50937fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * the parameters collected in this routine. */
50947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char kernel_cmdline_full[1024];
50957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    char tmp_str[1024];
50967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    int    dns_count = 0;
50975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5098a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner    init_clocks();
5099a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner
51005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_cache_utils_init(envp);
51015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5102a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    QLIST_INIT (&vm_change_state_head);
51035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
51045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
51055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct sigaction act;
51065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sigfillset(&act.sa_mask);
51075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        act.sa_flags = 0;
51085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        act.sa_handler = SIG_IGN;
51095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sigaction(SIGPIPE, &act, NULL);
51105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
51125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
51135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Note: cpu_interrupt() is currently not SMP safe, so we force
51145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       QEMU to run on a single CPU */
51155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
51165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        HANDLE h;
51175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        DWORD mask, smask;
51185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int i;
51195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        h = GetCurrentProcess();
51205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (GetProcessAffinityMask(h, &mask, &smask)) {
51215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(i = 0; i < 32; i++) {
51225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (mask & (1 << i))
51235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
51245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
51255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (i != 32) {
51265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                mask = 1 << i;
51275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                SetProcessAffinityMask(h, mask);
51285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
51295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
51305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
51325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_MACHINE);
51345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine = find_default_machine();
51355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_model = NULL;
51365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    initrd_filename = NULL;
51375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ram_size = 0;
51385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snapshot = 0;
51395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_filename = NULL;
51405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    kernel_cmdline = "";
51417fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    kernel_cmdline_append[0] = '\0';
51427fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    kernel_cmdline_full[0] = '\0';
51435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cyls = heads = secs = 0;
51445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    translation = BIOS_ATA_TRANSLATION_AUTO;
51455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    monitor_device = "vc:80Cx24C";
51465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_devices[0] = "vc:80Cx24C";
51485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_SERIAL_PORTS; i++)
51495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        serial_devices[i] = NULL;
51505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    serial_device_index = 0;
51515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_devices[0] = "vc:80Cx24C";
51535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
51545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        parallel_devices[i] = NULL;
51555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    parallel_device_index = 0;
51565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++)
51585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        virtio_consoles[i] = NULL;
51595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    virtio_console_index = 0;
51605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < MAX_NODES; i++) {
51625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_mem[i] = 0;
51635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        node_cpumask[i] = 0;
51645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
51655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    usb_devices_index = 0;
51675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_net_clients = 0;
51695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_bt_opts = 0;
51705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives = 0;
51715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_drives_opt = 0;
51725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_numa_nodes = 0;
51735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    hda_index = -1;
51745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    nb_nics = 0;
51765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tb_size = 0;
51785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    autostart= 1;
51795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_watchdogs();
51815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    optind = 1;
51835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(;;) {
51845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (optind >= argc)
51855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
51865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        r = argv[optind];
51875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (r[0] != '-') {
51885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
51895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
51905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const QEMUOption *popt;
51915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
51925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            optind++;
51935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* Treat --foo the same as -foo.  */
51945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (r[1] == '-')
51955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                r++;
51965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            popt = qemu_options;
51975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for(;;) {
51985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!popt->name) {
51995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "%s: invalid option -- '%s'\n",
52005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            argv[0], r);
52015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
52025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!strcmp(popt->name, r + 1))
52045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
52055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                popt++;
52065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
52075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (popt->flags & HAS_ARG) {
52085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (optind >= argc) {
52095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "%s: option '%s' requires an argument\n",
52105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            argv[0], r);
52115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
52125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = argv[optind++];
52145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
52155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                optarg = NULL;
52165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
52175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
52185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch(popt->index) {
52195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_M:
52205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine = find_machine(optarg);
52215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (!machine) {
52225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    QEMUMachine *m;
52235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    printf("Supported machines are:\n");
52245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for(m = first_machine; m != NULL; m = m->next) {
52255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("%-10s %s%s\n",
52265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->name, m->desc,
52275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               m->is_default ? " (default)" : "");
52285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
52295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(*optarg != '?');
52305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cpu:
52335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* hw initialization will check this */
52345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (*optarg == '?') {
52355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* XXX: implement xxx_cpu_list for targets that still miss it */
52365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(cpu_list)
52375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_list(stdout, &fprintf);
52385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
52395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(0);
52405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
52415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_model = optarg;
52425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
52435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_initrd:
52455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                initrd_filename = optarg;
52465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hda:
52485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (cyls == 0)
52495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    hda_index = drive_add(optarg, HD_ALIAS, 0);
52505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else
52515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    hda_index = drive_add(optarg, HD_ALIAS
52525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     ",cyls=%d,heads=%d,secs=%d%s",
52535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             0, cyls, heads, secs,
52545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_LBA ?
52555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=lba" :
52565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             translation == BIOS_ATA_TRANSLATION_NONE ?
52575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 ",trans=none" : "");
52585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 break;
52595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdb:
52605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdc:
52615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdd:
52625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
52635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_drive:
52655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(NULL, "%s", optarg);
52665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	        break;
52675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mtdblock:
52685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, MTD_ALIAS);
52695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sd:
52715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, SD_ALIAS);
52725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pflash:
52745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, PFLASH_ALIAS);
52755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_snapshot:
52775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snapshot = 1;
52785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
52795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_hdachs:
52805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
52815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
52825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
52835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cyls = strtol(p, (char **)&p, 0);
52845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (cyls < 1 || cyls > 16383)
52855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
52865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
52875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
52885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
52895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    heads = strtol(p, (char **)&p, 0);
52905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (heads < 1 || heads > 16)
52915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
52925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != ',')
52935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
52945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
52955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    secs = strtol(p, (char **)&p, 0);
52965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (secs < 1 || secs > 63)
52975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto chs_fail;
52985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == ',') {
52995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
53005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (!strcmp(p, "none"))
53015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_NONE;
53025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "lba"))
53035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_LBA;
53045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else if (!strcmp(p, "auto"))
53055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            translation = BIOS_ATA_TRANSLATION_AUTO;
53065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        else
53075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto chs_fail;
53085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p != '\0') {
53095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    chs_fail:
53105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: invalid physical CHS format\n");
53115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
53125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
53135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    if (hda_index != -1)
53145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        snprintf(drives_opt[hda_index].opt,
53155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 sizeof(drives_opt[hda_index].opt),
53165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
53175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                 0, cyls, heads, secs,
53185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			         translation == BIOS_ATA_TRANSLATION_LBA ?
53195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			     	    ",trans=lba" :
53205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			         translation == BIOS_ATA_TRANSLATION_NONE ?
53215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			             ",trans=none" : "");
53225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
53235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_numa:
53255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_numa_nodes >= MAX_NODES) {
53265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many NUMA nodes\n");
53275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
53285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
53295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                numa_add(optarg);
53305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nographic:
53325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_NOGRAPHIC;
53335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_CURSES
53355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_curses:
53365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_CURSES;
53375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
53395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_portrait:
53405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                graphic_rotate = 1;
53415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_kernel:
53435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_filename = optarg;
53445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_append:
53465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kernel_cmdline = optarg;
53475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_cdrom:
53495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, CDROM_ALIAS);
53505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_boot:
53525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                boot_devices = optarg;
53535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* We just do some generic consistency checks */
53545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
53555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    /* Could easily be extended to 64 devices if needed */
53565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
5357d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
53585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    boot_devices_bitmap = 0;
53595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for (p = boot_devices; *p != '\0'; p++) {
53605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        /* Allowed boot devices are:
53615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * a b     : floppy disk drives
53625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * c ... f : IDE disk drives
53635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * g ... m : machine implementation dependant drives
53645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * n ... p : network devices
53655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * It's up to each machine implementation to check
53665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * if the given boot devices match the actual hardware
53675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         * implementation and firmware features.
53685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                         */
53695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (*p < 'a' || *p > 'q') {
53705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
53715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
53725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
53735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
53745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr,
53755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                    "Boot device '%c' was given twice\n",*p);
53765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
53775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
53785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        boot_devices_bitmap |= 1 << (*p - 'a');
53795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
53805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
53815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fda:
53835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_fdb:
53845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
53855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
53875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_fd_bootchk:
53885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fd_bootchk = 0;
53895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
53915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_net:
53925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_net_clients >= MAX_NET_CLIENTS) {
53935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many network clients\n");
53945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
53955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
53965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_clients[nb_net_clients] = optarg;
53975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_net_clients++;
53985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
53995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
54005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tftp:
54015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		tftp_prefix = optarg;
54025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bootp:
54045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bootp_filename = optarg;
54055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0  /* ANDROID disabled */
54075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
54085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smb:
54095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		net_slirp_smb(optarg);
54105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* ANDROID */
54135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_redir:
54145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                net_slirp_redir(NULL, optarg, NULL);
54155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bt:
54185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_bt_opts >= MAX_BT_CMDLINE) {
54195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many bluetooth options\n");
54205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
54215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
54225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bt_opts[nb_bt_opts++] = optarg;
54235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAS_AUDIO
54255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_audio_help:
54265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                AUD_help ();
54275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit (0);
54285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_soundhw:
54305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_soundhw (optarg);
54315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_h:
54345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_help(0);
54355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_version:
54375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                version();
54385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(0);
54395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_m: {
54415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                uint64_t value;
54425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                char *ptr;
54435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                value = strtoul(optarg, &ptr, 10);
54455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                switch (*ptr) {
54465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 0: case 'M': case 'm':
54475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 20;
54485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
54495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                case 'G': case 'g':
54505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    value <<= 30;
54515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
54525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                default:
54535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
54545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
54555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
54565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                /* On 32-bit hosts, QEMU is limited by virtual address space */
54585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value > (2047 << 20)
54595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_KQEMU
54605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    && HOST_LONG_BITS == 32
54615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
54625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    ) {
54635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
54645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
54655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
54665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (value != (uint64_t)(ram_addr_t)value) {
54675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: ram size too large\n");
54685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
54695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
54705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                ram_size = value;
54715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
54735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_d:
54745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
54755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int mask;
54765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const CPULogItem *item;
54775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
54785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    mask = cpu_str_to_log_mask(optarg);
54795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!mask) {
54805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Log items (comma separated):\n");
54815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    for(item = cpu_log_items; item->mask != 0; item++) {
54825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("%-10s %s\n", item->name, item->help);
54835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
54845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
54855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
54865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cpu_set_log(mask);
54875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
54885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_s:
54905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
54915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_gdb:
54935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev = optarg;
54945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_L:
54965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                data_dir = optarg;
54975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
54985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_bios:
54995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                bios_name = optarg;
55005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_singlestep:
55025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                singlestep = 1;
55035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_S:
55055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0  /* ANDROID */
55065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Sorry, stopped launch is not supported in the Android emulator\n" );
55075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
55085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
55095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                autostart = 0;
55105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
55125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_k:
55135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		keyboard_layout = optarg;
55145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
55155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
55165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_localtime:
55175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_utc = 0;
55185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_vga:
55205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                select_vgahw (optarg);
55215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_PPC) || defined(TARGET_SPARC)
55235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_g:
55245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
55255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    const char *p;
55265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    int w, h, depth;
55275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p = optarg;
55285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    w = strtol(p, (char **)&p, 10);
55295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (w <= 0) {
55305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_error:
55315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "qemu: invalid resolution or depth\n");
55325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
55335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
55345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p != 'x')
55355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
55365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    p++;
55375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    h = strtol(p, (char **)&p, 10);
55385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (h <= 0)
55395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
55405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (*p == 'x') {
55415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        p++;
55425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = strtol(p, (char **)&p, 10);
55435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (depth != 8 && depth != 15 && depth != 16 &&
55445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            depth != 24 && depth != 32)
55455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto graphic_error;
55465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else if (*p == '\0') {
55475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        depth = graphic_depth;
55485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
55495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        goto graphic_error;
55505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
55515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
55525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_width = w;
55535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_height = h;
55545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    graphic_depth = depth;
55555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
55565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
55585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_echr:
55595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
55605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    char *r;
55615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    term_escape_char = strtol(optarg, &r, 0);
55625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (r == optarg)
55635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        printf("Bad argument to echr\n");
55645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    break;
55655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
55665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_monitor:
55675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = optarg;
55685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_serial:
55705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (serial_device_index >= MAX_SERIAL_PORTS) {
55715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many serial ports\n");
55725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
55735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
55745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[serial_device_index] = optarg;
55755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_device_index++;
55765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog:
55785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                i = select_watchdog(optarg);
55795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (i > 0)
55805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit (i == 1 ? 1 : 0);
55815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_watchdog_action:
55835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (select_watchdog_action(optarg) == -1) {
55845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Unknown -watchdog-action parameter\n");
55855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
55865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
55875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_virtiocon:
55895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
55905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many virtio consoles\n");
55915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
55925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
55935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_consoles[virtio_console_index] = optarg;
55945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                virtio_console_index++;
55955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
55965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_parallel:
55975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
55985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "qemu: too many parallel ports\n");
55995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
56005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
56015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_devices[parallel_device_index] = optarg;
56025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                parallel_device_index++;
56035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_loadvm:
56055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		loadvm = optarg;
56065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
56075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_full_screen:
56085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                full_screen = 1;
56095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SDL
56115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_frame:
56125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_frame = 1;
56135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_alt_grab:
56155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                alt_grab = 1;
56165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_quit:
56185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_quit = 1;
56195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_sdl:
56215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_SDL;
56225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_pidfile:
56255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pid_file = optarg;
56265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
56285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_win2k_hack:
56295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                win2k_install_hack = 1;
56305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_rtc_td_hack:
56325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                rtc_td_hack = 1;
56335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_acpitable:
56355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(acpi_table_add(optarg) < 0) {
56365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Wrong acpi table provided\n");
56375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
56385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
56395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smbios:
56415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(smbios_entry_add(optarg) < 0) {
56425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Wrong smbios provided\n");
56435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
56445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
56455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
56485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_kqemu:
56495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 0;
56505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_kernel_kqemu:
56525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 2;
56535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KVM
56565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_enable_kvm:
56575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kvm_allowed = 1;
56585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
56595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                kqemu_allowed = 0;
56605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usb:
56645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
56655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_usbdevice:
56675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_enabled = 1;
56685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (usb_devices_index >= MAX_USB_CMDLINE) {
56695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Too many USB devices\n");
56705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
56715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
56725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices[usb_devices_index] = optarg;
56735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usb_devices_index++;
56745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_smp:
56765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                smp_cpus = atoi(optarg);
56775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (smp_cpus < 1) {
56785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Invalid number of CPUs\n");
56795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
56805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
56815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_vnc:
56835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                display_type = DT_VNC;
56845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		vnc_display = optarg;
56855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
56865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
56875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_acpi:
56885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                acpi_enabled = 0;
56895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_hpet:
56915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_hpet = 1;
56925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_virtio_balloon:
56945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_virtio_balloon = 1;
56955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
56965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
56975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_reboot:
56985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_reboot = 1;
56995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_no_shutdown:
57015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                no_shutdown = 1;
57025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_show_cursor:
57045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cursor_hide = 0;
57055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_uuid:
57075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
57085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Fail to parse UUID string."
57095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            " Wrong format.\n");
57105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
57115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
57125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
57145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_daemonize:
57155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		daemonize = 1;
57165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
57175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
57185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    case QEMU_OPTION_option_rom:
57195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		if (nb_option_roms >= MAX_OPTION_ROMS) {
57205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    fprintf(stderr, "Too many option ROMs\n");
57215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		    exit(1);
57225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		}
57235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		option_rom[nb_option_roms] = optarg;
57245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		nb_option_roms++;
57255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		break;
57265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ARM) || defined(TARGET_M68K)
57275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_semihosting:
57285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                semihosting_enabled = 1;
57295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
57315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_name:
57325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_name = optarg;
57335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC) || defined(TARGET_PPC)
57355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_prom_env:
57365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (nb_prom_envs >= MAX_PROM_ENVS) {
57375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Too many prom variables\n");
57385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
57395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
57405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                prom_envs[nb_prom_envs] = optarg;
57415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nb_prom_envs++;
57425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
57445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_ARM
57455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_old_param:
57465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                old_param = 1;
57475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
57495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_clock:
57505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                configure_alarms(optarg);
57515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_startdate:
57535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                {
57545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    struct tm tm;
57555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    time_t rtc_start_date;
57565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (!strcmp(optarg, "now")) {
57575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = -1;
57585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    } else {
57595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
57605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_year,
57615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mon,
57625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_mday,
57635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_hour,
57645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_min,
57655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               &tm.tm_sec) == 6) {
57665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            /* OK */
57675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else if (sscanf(optarg, "%d-%d-%d",
57685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_year,
57695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mon,
57705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          &tm.tm_mday) == 3) {
57715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_hour = 0;
57725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_min = 0;
57735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            tm.tm_sec = 0;
57745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        } else {
57755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            goto date_fail;
57765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
57775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_year -= 1900;
57785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        tm.tm_mon--;
57795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_start_date = mktimegm(&tm);
57805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        if (rtc_start_date == -1) {
57815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        date_fail:
57825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            fprintf(stderr, "Invalid date format. Valid format are:\n"
57835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
57845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            exit(1);
57855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        }
57865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        rtc_date_offset = time(NULL) - rtc_start_date;
57875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
57885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
57895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tb_size:
57915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tb_size = strtol(optarg, NULL, 0);
57925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (tb_size < 0)
57935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tb_size = 0;
57945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
57955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_icount:
57965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                use_icount = 1;
57975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strcmp(optarg, "auto") == 0) {
57985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    icount_time_shift = -1;
57995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                } else {
58005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    icount_time_shift = strtol(optarg, NULL, 0);
58015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
58025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_incoming:
58045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                incoming = optarg;
58055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
58075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_chroot:
58085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                chroot_dir = optarg;
58095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_runas:
58115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                run_as = optarg;
58125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
58145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_XEN
58155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_domid:
58165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_domid = atoi(optarg);
58175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_create:
58195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_CREATE;
58205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_xen_attach:
58225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                xen_mode = XEN_ATTACH;
58235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
58255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
58265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
58275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_mic:
58285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                audio_input_source = (char*)optarg;
58295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
5831a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turner            case QEMU_OPTION_trace:
58325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_filename = optarg;
58335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                tracing = 1;
58345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
58365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_miss:
58375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_cache_miss = 1;
58385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_trace_addr:
58405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                trace_all_addr = 1;
58415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
58435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_tracing:
58445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (strcmp(optarg, "off") == 0)
58455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 0;
58465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else if (strcmp(optarg, "on") == 0 && trace_filename)
58475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    tracing = 1;
58485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                else {
58495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    fprintf(stderr, "Unexpected option to -tracing ('%s')\n",
58505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                            optarg);
58515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    exit(1);
58525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
58535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
58555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_load_miss:
58565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_load_miss_penalty = atoi(optarg);
58575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_dcache_store_miss:
58595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                dcache_store_miss_penalty = atoi(optarg);
58605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
58625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
58635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_NAND
58645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case QEMU_OPTION_nand:
58655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                nand_add_dev(optarg);
58665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
58675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
5868d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_ports:
5869d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_ports = (char*)optarg;
5870d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
5871d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
5872d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_port:
5873d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_port = (char*)optarg;
5874d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
5875d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
5876d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_android_report_console:
5877d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                android_op_report_console = (char*)optarg;
5878d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
5879d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
5880d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            case QEMU_OPTION_http_proxy:
5881d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                op_http_proxy = (char*)optarg;
5882d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine                break;
588343552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
588443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            case QEMU_OPTION_charmap:
588543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                op_charmap_file = (char*)optarg;
588643552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                break;
5887dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
5888dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            case QEMU_OPTION_android_gui:
5889dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                android_op_gui = (char*)optarg;
5890dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                break;
5891074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
5892074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine            case QEMU_OPTION_android_hw:
5893074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                android_op_hwini = (char*)optarg;
5894074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine                break;
58957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            case QEMU_OPTION_dns_server:
58967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                android_op_dns_server = (char*)optarg;
58977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                break;
58987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
5899b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_radio:
5900b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_radio = (char*)optarg;
5901b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5902b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5903b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_gps:
5904b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_gps = (char*)optarg;
5905b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5906b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5907b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio:
5908b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio = (char*)optarg;
5909b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5910b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5911b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio_in:
5912b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio_in = (char*)optarg;
5913b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5914b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5915b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_audio_out:
5916b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_audio_out = (char*)optarg;
5917b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5918b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5919b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            case QEMU_OPTION_cpu_delay:
5920b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                android_op_cpu_delay = (char*)optarg;
5921b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                break;
5922b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5923b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
5924b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine            case QEMU_OPTION_android_memcheck:
5925b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                android_op_memcheck = (char*)optarg;
59267fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                snprintf(tmp_str, sizeof(tmp_str), "memcheck=%s",
59277fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                         android_op_memcheck);
59287fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                tmp_str[sizeof(tmp_str) - 1] = '\0';
59297fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                /* This will set ro.kernel.memcheck system property
59307fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                 * to memcheck's tracing flags. */
59317fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
5932b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine                break;
5933b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif // CONFIG_MEMCHECK
59345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
59355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
59365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
59375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
593843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    /* Initialize character map. */
593943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (android_charmap_setup(op_charmap_file)) {
594043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        if (op_charmap_file) {
594143552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            fprintf(stderr,
594243552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    "Unable to initialize character map from file %s.\n",
594343552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    op_charmap_file);
594443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        } else {
594543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine            fprintf(stderr,
594643552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine                    "Unable to initialize default character map.\n");
594743552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        }
594843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine        exit(1);
594943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
595043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
59515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If no data_dir is specified then try to find it relative to the
59525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       executable path.  */
59535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
59545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = find_datadir(argv[0]);
59555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
59565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* If all else fails use the install patch specified when building.  */
59575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!data_dir) {
59585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        data_dir = CONFIG_QEMU_SHAREDIR;
59595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
59605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5961074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#ifdef CONFIG_STANDALONE_CORE
5962074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    /* Initialize hardware configuration. */
5963074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    if (android_op_hwini) {
5964074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      hw_ini = iniFile_newFromFile(android_op_hwini);
5965074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      if (hw_ini == NULL) {
5966074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine        fprintf(stderr, "Could not find %s file.\n", android_op_hwini);
5967074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine        exit(1);
5968074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      }
5969074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    } else {
5970074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine      hw_ini = iniFile_newFromMemory("", 0);
5971074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    }
5972074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
5973074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    androidHwConfig_read(android_hw, hw_ini);
5974074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine    iniFile_free(hw_ini);
5975074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine#endif  // CONFIG_STANDALONE_CORE
5976074d1f955a15c19214cee92c627c8c4697e98cd3Vladimir Chtchetkine
5977b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize modem */
5978b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_radio) {
5979b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("radio", android_op_radio, NULL);
5980b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
5981b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "unsupported character device specification: %s\n"
5982b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                            "used -help-char-devices for list of available formats\n",
5983b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_radio);
5984b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5985b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5986b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
5987b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gsmModem != 0 ) {
5988b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
5989b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "could not initialize qemud 'gsm' channel");
5990b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
5991b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
5992b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
5993b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
5994b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize GPS */
5995b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_gps) {
5996b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        CharDriverState*  cs = qemu_chr_open("gps", android_op_gps, NULL);
5997b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (cs == NULL) {
5998b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "unsupported character device specification: %s\n"
5999b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                            "used -help-char-devices for list of available formats\n",
6000b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_gps);
6001b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6002b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6003b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
6004b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    } else if (android_hw->hw_gps != 0) {
6005b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
6006b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "could not initialize qemud 'gps' channel" );
6007b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6008b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6009b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
6010b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6011b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    /* Initialize audio. */
6012b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio) {
6013b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (android_op_audio_in || android_op_audio_out) {
6014b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "you can't use -audio with -audio-in or -audio-out\n" );
6015b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6016b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6017b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 0, android_op_audio ) ) {
6018b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
6019b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio);
6020b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6021b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6022b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_op_audio_out = android_op_audio;
6023b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        android_op_audio_in  = android_op_audio;
6024b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6025b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 1, android_op_audio ) ) {
6026b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout,
6027b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    "emulator: warning: '%s' is not a valid audio input backend. audio record disabled\n",
6028b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio);
6029b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            android_op_audio_in = "none";
6030b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6031b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
6032b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6033b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio_in) {
6034b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        static char  env[64]; /* note: putenv needs a static unique string buffer */
6035b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 1, android_op_audio_in ) ) {
6036b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio input backend. see -help-audio-in\n",
6037b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio_in);
6038b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6039b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6040b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        bufprint( env, env+sizeof(env), "QEMU_AUDIO_IN_DRV=%s", android_op_audio_in );
6041b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        putenv( env );
6042b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6043b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (!android_hw->hw_audioInput) {
6044b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout, "Emulated hardware doesn't have audio input.\n");
6045b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6046b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
6047b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_audio_out) {
6048b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        static char  env[64]; /* note: putenv needs a static unique string buffer */
6049b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if ( !audio_check_backend_name( 0, android_op_audio_out ) ) {
6050b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
6051b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine                    android_op_audio_out);
6052b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6053b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6054b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        bufprint( env, env+sizeof(env), "QEMU_AUDIO_OUT_DRV=%s", android_op_audio_out );
6055b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        putenv( env );
6056b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (!android_hw->hw_audioOutput) {
6057b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stdout, "Emulated hardware doesn't have audio output\n");
6058b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6059b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
6060b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6061b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (android_op_cpu_delay) {
6062b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        char*   end;
6063b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        long    delay = strtol(android_op_cpu_delay, &end, 0);
6064b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (end == NULL || *end || delay < 0 || delay > 1000 ) {
6065b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            fprintf(stderr, "option -cpu-delay must be an integer between 0 and 1000\n" );
6066b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            exit(1);
6067b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        }
6068b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        if (delay > 0)
6069b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine            delay = (1000-delay);
6070b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
6071b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        qemu_cpu_delay = (int) delay;
6072b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
6073b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
60747fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (android_op_dns_server) {
60757fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        char*  x = strchr(android_op_dns_server, ',');
60767fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = 0;
60777fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (x == NULL)
60787fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
60797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            if ( add_dns_server( android_op_dns_server ) == 0 )
60807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                dns_count = 1;
60817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
60827fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        else
60837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        {
60847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            x = android_op_dns_server;
60857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            while (*x) {
60867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                char*  y = strchr(x, ',');
60877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
60887fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y != NULL) {
60897fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    *y = 0;
60907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y++;
60917fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                } else {
60927fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    y = x + strlen(x);
60937fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
60947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
60957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                if (y > x && add_dns_server( x ) == 0) {
60967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                    dns_count += 1;
60977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                }
60987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                x = y;
60997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            }
61007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
61017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (dns_count == 0)
61027fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            fprintf( stdout, "### WARNING: will use system default DNS server\n" );
61037fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
61047fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
61057fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count == 0)
61067fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        dns_count = slirp_get_system_dns_servers();
61077fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (dns_count) {
61087fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        snprintf(tmp_str, sizeof(tmp_str), "android.ndns=%d", dns_count);
61097fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
61107fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
61117fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
6112b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK
6113b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (android_op_memcheck) {
6114b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        memcheck_init(android_op_memcheck);
6115b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
6116b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine#endif  // CONFIG_MEMCHECK
6117b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
61185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
61195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_allowed && kqemu_allowed) {
61205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr,
61215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "You can not enable both KVM and kqemu at the same time\n");
61225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
61235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
61245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
61255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
61275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > machine->max_cpus) {
61285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
61295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
61305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                machine->max_cpus);
61315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
61325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
61335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC) {
61355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (serial_device_index == 0)
61365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           serial_devices[0] = "stdio";
61375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (parallel_device_index == 0)
61385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           parallel_devices[0] = "null";
61395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       if (strncmp(monitor_device, "vc", 2) == 0)
61405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           monitor_device = "stdio";
61415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
61425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
61445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
61455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid_t pid;
61465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pipe(fds) == -1)
61485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
61495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid = fork();
61515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pid > 0) {
61525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    uint8_t status;
61535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    ssize_t len;
61545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    close(fds[1]);
61565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	again:
61585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len = read(fds[0], &status, 1);
61595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len == -1 && (errno == EINTR))
61605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                goto again;
61615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len != 1)
61635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
61645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else if (status == 1) {
61655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Could not acquire pidfile\n");
61665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
61675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
61685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(0);
61695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	} else if (pid < 0)
61705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
61715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	setsid();
61735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	pid = fork();
61755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (pid > 0)
61765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(0);
61775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	else if (pid < 0)
61785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
61795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	umask(027);
61815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTSTP, SIG_IGN);
61835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTTOU, SIG_IGN);
61845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        signal(SIGTTIN, SIG_IGN);
61855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
61865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
61885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (daemonize) {
61895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint8_t status = 1;
61905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            write(fds[1], &status, 1);
61915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else
61925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Could not acquire pid file\n");
61935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
61945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
61955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
61965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
61975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
61985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (smp_cpus > 1)
61995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_allowed = 0;
62005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
62015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_init_main_loop()) {
62025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu_init_main_loop failed\n");
62035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
62045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    linux_boot = (kernel_filename != NULL);
62065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
62075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && *kernel_cmdline != '\0') {
62095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-append only allowed with -kernel option\n");
62105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
62115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!linux_boot && initrd_filename != NULL) {
62145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-initrd only allowed with -kernel option\n");
62155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
62165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* boot to floppy or the default cd if no hard disk defined yet */
62195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!boot_devices[0]) {
62205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        boot_devices = "cad";
62215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    setvbuf(stdout, NULL, _IOLBF, 0);
62235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (init_timer_alarm() < 0) {
62255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "could not initialize alarm timer\n");
62265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
62275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (use_icount && icount_time_shift < 0) {
62295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        use_icount = 2;
62305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* 125MIPS seems a reasonable initial guess at the guest speed.
62315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           It will be corrected fairly quickly anyway.  */
62325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        icount_time_shift = 3;
62335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        init_icount_adjust();
62345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
62375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    socket_init();
62385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
62395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init network clients */
62415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_net_clients == 0) {
62425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* if no clients, we use a default config */
62435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "nic";
62445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_SLIRP
62455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        net_clients[nb_net_clients++] = "user";
62465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
62475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0;i < nb_net_clients; i++) {
62505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (net_client_parse(net_clients[i]) < 0)
62515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
62525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_client_check();
62545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_I386
62565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* XXX: this should be moved in the PC machine instantiation code */
62575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (net_boot != 0) {
62585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int netroms = 0;
62595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	for (i = 0; i < nb_nics && i < 4; i++) {
62605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    const char *model = nd_table[i].model;
62615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    char buf[1024];
62625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char *filename;
62635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (net_boot & (1 << i)) {
62645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (model == NULL)
62655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    model = "ne2k_pci";
62665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "pxe-%s.bin", model);
62675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
62685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename && get_image_size(filename) > 0) {
62695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    if (nb_option_roms >= MAX_OPTION_ROMS) {
62705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        fprintf(stderr, "Too many option ROMs\n");
62715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        exit(1);
62725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    }
62735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    option_rom[nb_option_roms] = qemu_strdup(buf);
62745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    nb_option_roms++;
62755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    netroms++;
62765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
62775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (filename) {
62785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    qemu_free(filename);
62795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                }
62805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
62815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
62825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (netroms == 0) {
62835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    fprintf(stderr, "No valid PXE rom found for network device\n");
62845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
62855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	}
62865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
62875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
62885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the bluetooth world */
62905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < nb_bt_opts; i++)
62915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (bt_parse(bt_opts[i]))
62925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
62935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the memory */
62955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ram_size == 0)
62965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
62975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
62985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_KQEMU
62995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
63005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       guest ram allocation.  It needs to go away.  */
63015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kqemu_allowed) {
63025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
63035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
63045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!kqemu_phys_ram_base) {
63055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Could not allocate physical memory\n");
63065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
63075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
63095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
63105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init the dynamic translator */
63125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_exec_init_all(tb_size * 1024 * 1024);
63135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_init();
63155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create the cdrom drive, even if no disk is there */
63175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
63195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, CDROM_ALIAS);
63205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create at least one floppy */
63225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
63245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, FD_ALIAS, 0);
63255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* we always create one sd slot, even if no card is in it */
63275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_drives_opt < MAX_DRIVES)
63295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        drive_add(NULL, SD_ALIAS);
63305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* open the virtual block devices */
63325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < nb_drives_opt; i++)
63345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (drive_init(&drives_opt[i], snapshot, machine) == -1)
63355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
63365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
63385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
63395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
63415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* must be after terminal init, SDL library changes signal handlers */
63425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sighandler_setup();
63435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
63445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Maintain compatibility with multiple stdio monitors */
63465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(monitor_device,"stdio")) {
63475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
63485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const char *devname = serial_devices[i];
63495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (devname && !strcmp(devname,"mon:stdio")) {
63505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
63515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
63525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else if (devname && !strcmp(devname,"stdio")) {
63535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                monitor_device = NULL;
63545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                serial_devices[i] = "mon:stdio";
63555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
63565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
63575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
63595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (nb_numa_nodes > 0) {
63615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int i;
63625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (nb_numa_nodes > smp_cpus) {
63645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            nb_numa_nodes = smp_cpus;
63655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* If no memory size if given for any node, assume the default case
63685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * and distribute the available memory equally across all nodes
63695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
63705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
63715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_mem[i] != 0)
63725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
63735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
63755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            uint64_t usedmem = 0;
63765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* On Linux, the each node's border has to be 8MB aligned,
63785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             * the final node gets the rest.
63795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             */
63805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < nb_numa_nodes - 1; i++) {
63815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
63825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                usedmem += node_mem[i];
63835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
63845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            node_mem[i] = ram_size - usedmem;
63855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
63875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
63885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] != 0)
63895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
63905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
63915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* assigning the VCPUs round-robin is easier to implement, guest OSes
63925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * must cope with this anyway, because there are BIOSes out there in
63935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         * real machines which also use this scheme.
63945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner         */
63955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i == nb_numa_nodes) {
63965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (i = 0; i < smp_cpus; i++) {
63975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                node_cpumask[i % nb_numa_nodes] |= 1 << i;
63985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
63995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
64035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
64045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_init(smp_cpus);
64065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
64075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "failed to initialize KVM\n");
64085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
64095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device) {
64135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
64145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!monitor_hd) {
64155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
64165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
64175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
64215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = serial_devices[i];
64225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
64235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
64245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "serial%d", i);
64255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            serial_hds[i] = qemu_chr_open(label, devname, NULL);
64265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!serial_hds[i]) {
64275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open serial device '%s'\n",
64285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
64295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
64305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
64315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
64355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
64365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
64375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
64385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "parallel%d", i);
64395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            parallel_hds[i] = qemu_chr_open(label, devname, NULL);
64405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!parallel_hds[i]) {
64415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
64425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
64435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
64445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
64455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
64495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
64505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
64515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            char label[32];
64525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(label, sizeof(label), "virtcon%d", i);
64535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
64545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!virtcon_hds[i]) {
64555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "qemu: could not open virtio console '%s'\n",
64565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        devname);
64575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                exit(1);
64585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
64595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
64605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    module_call_init(MODULE_INIT_DEVICE);
64635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_TRACE
64665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (trace_filename) {
64675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        trace_init(trace_filename);
64685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0
64695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        // We don't need the dcache code until we can get load and store tracing
64705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        // working again.
64715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcache_init(dcache_size, dcache_ways, dcache_line_size,
64725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dcache_replace_policy, dcache_load_miss_penalty,
64735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    dcache_store_miss_penalty);
64745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
64755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "-- When done tracing, exit the emulator. --\n");
64765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
64775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
64785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64797fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    /* Combine kernel command line passed from the UI with parameters
64807fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine     * collected during initialization. */
64817fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (*kernel_cmdline) {
64827fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        if (kernel_cmdline_append[0]) {
64837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            snprintf(kernel_cmdline_full, sizeof(kernel_cmdline_full), "%s %s",
64847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                     kernel_cmdline, kernel_cmdline_append);
64857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        } else {
64867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            strncpy(kernel_cmdline_full, kernel_cmdline, sizeof(kernel_cmdline_full));
64877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine            kernel_cmdline_full[sizeof(kernel_cmdline_full) - 1] = '\0';
64887fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        }
64897fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    } else if (kernel_cmdline_append[0]) {
64907fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        strncpy(kernel_cmdline_full, kernel_cmdline_append, sizeof(kernel_cmdline_full));
64917fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
64927fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
64935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    machine->init(ram_size, boot_devices,
64947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine                  kernel_filename, kernel_cmdline_full, initrd_filename, cpu_model);
64955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
64975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu) {
64985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (i = 0; i < nb_numa_nodes; i++) {
64995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (node_cpumask[i] & (1 << env->cpu_index)) {
65005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                env->numa_node = i;
65015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
65025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
65035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
65045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    current_machine = machine;
65065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Set KVM's vcpu state to qemu's initial CPUState. */
65085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
65095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int ret;
65105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = kvm_sync_vcpus();
65125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0) {
65135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "failed to initialize vcpus\n");
65145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
65155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
65165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
65175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* init USB devices */
65195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (usb_enabled) {
65205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for(i = 0; i < usb_devices_index; i++) {
65215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (usb_device_add(usb_devices[i], 0) < 0) {
65225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                fprintf(stderr, "Warning: could not add USB device %s\n",
65235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                        usb_devices[i]);
65245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
65255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
65265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
65275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6528dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    if (!display_state) {
6529dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        if (android_op_gui) {
6530dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            /* Initialize display from the command line parameters. */
6531dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            if (parse_androig_gui_option(android_op_gui,
6532dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_width,
6533dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_height,
6534dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                         &android_display_bpp)) {
6535dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                exit(1);
6536dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            }
6537dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            android_display_init_from(android_display_width,
6538dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                      android_display_height, 0,
6539dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                      android_display_bpp);
6540dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        } else {
6541dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            dumb_display_init();
6542dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        }
6543dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    } else if (android_op_gui) {
6544dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        /* Resize display from the command line parameters. */
6545dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        if (parse_androig_gui_option(android_op_gui,
6546dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_width,
6547dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_height,
6548dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                     &android_display_bpp)) {
6549dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine            exit(1);
6550dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        }
6551dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine        display_state->surface = qemu_resize_displaysurface(display_state,
6552dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                                            android_display_width,
6553dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine                                                            android_display_height);
6554dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine    }
6555dd50f7d7d919dfa2a2cebd383635ba74c10e3777Vladimir Chtchetkine
65565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* just use the first displaystate for the moment */
65575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ds = display_state;
65585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_DEFAULT) {
65605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
65615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_SDL;
65625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
65635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        display_type = DT_VNC;
65645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display = "localhost:0,to=99";
65655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        show_vnc_port = 1;
65665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
65675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6568d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
65695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (display_type) {
65715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_NOGRAPHIC:
65725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_CURSES)
65745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_CURSES:
65755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        curses_display_init(ds, full_screen);
65765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6578eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine#if defined(CONFIG_SDL) && !defined(CONFIG_STANDALONE_CORE)
65795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
65805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sdl_display_init(ds, full_screen, no_frame);
65815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined(CONFIG_COCOA)
65835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_SDL:
65845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cocoa_display_init(ds, full_screen);
65855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
65875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case DT_VNC:
65885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vnc_display_init(ds);
65895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (vnc_display_open(ds, vnc_display) < 0)
65905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
65915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
65925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (show_vnc_port) {
65935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
65945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
65955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
65975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
65985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
65995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dpy_resize(ds);
66005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dcl = ds->listeners;
66025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (dcl != NULL) {
66035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (dcl->dpy_refresh != NULL) {
66045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
66055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
66065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
66075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dcl = dcl->next;
66085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
66115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
66125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
66135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    text_consoles_set_display(display_state);
66165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_chr_initial_reset();
66175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_device && monitor_hd)
66195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
66205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
66225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = serial_devices[i];
66235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
66245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
66255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
66265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
66275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
66305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = parallel_devices[i];
66315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (devname && strcmp(devname, "none")) {
66325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
66335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
66345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
66355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
66385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        const char *devname = virtio_consoles[i];
66395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (virtcon_hds[i] && devname) {
66405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (strstart(devname, "vc", 0))
66415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
66425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
66435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
66465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
66475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdbstub_dev);
66485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exit(1);
66495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (loadvm)
66525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        do_loadvm(cur_mon, loadvm);
66535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* call android-specific setup function */
66555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_setup();
66565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (incoming) {
66585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        autostart = 0; /* fixme how to deal with -daemonize */
66595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_start_incoming_migration(incoming);
66605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (autostart)
66635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_start();
66645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
66665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
66675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	uint8_t status = 0;
66685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ssize_t len;
66695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    again1:
66715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	len = write(fds[1], &status, 1);
66725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (len == -1 && (errno == EINTR))
66735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    goto again1;
66745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (len != 1)
66765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
66775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6678a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (chdir("/")) {
6679a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            perror("not able to chdir to /");
6680a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            exit(1);
6681a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        }
66825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	TFR(fd = open("/dev/null", O_RDWR));
66835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (fd == -1)
66845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    exit(1);
66855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (run_as) {
66885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        pwd = getpwnam(run_as);
66895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!pwd) {
66905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
66915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
66925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
66935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
66945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
66955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (chroot_dir) {
66965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (chroot(chroot_dir) < 0) {
66975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "chroot failed\n");
66985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
66995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
6700a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        if (chdir("/")) {
6701a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            perror("not able to chdir to /");
6702a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner            exit(1);
6703a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner        }
67045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
67055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
67065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (run_as) {
67075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setgid(pwd->pw_gid) < 0) {
67085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
67095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
67105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
67115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setuid(pwd->pw_uid) < 0) {
67125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
67135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
67145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
67155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (setuid(0) != -1) {
67165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Dropping privileges failed\n");
67175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            exit(1);
67185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
67195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
67205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
67215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (daemonize) {
67225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 0);
67235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 1);
67245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dup2(fd, 2);
67255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
67265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        close(fd);
67275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
67285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
67295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
67305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    main_loop();
67315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    quit_timers();
67325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    net_cleanup();
67335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    android_emulation_teardown();
67345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
67355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
6736eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine
6737eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkinevoid
6738eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkineandroid_emulation_teardown(void)
6739eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine{
6740eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine    android_charmap_done();
6741eb8382507c6b802f378cf940fae4775633c1d84eVladimir Chtchetkine}
6742