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