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