blob: bf97b90b523525d34d33388f98aed0d465266417 [file] [log] [blame]
bellard0824d6f2003-06-24 13:42:40 +00001/*
bellard80cabfa2004-03-14 12:20:30 +00002 * QEMU System Emulator
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard68d0f702008-01-06 17:21:48 +00004 * Copyright (c) 2003-2008 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard1df912c2003-06-25 16:20:35 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
bellard0824d6f2003-06-24 13:42:40 +000023 */
pbrook87ecb682007-11-17 17:14:51 +000024#include "hw/hw.h"
25#include "hw/boards.h"
26#include "hw/usb.h"
27#include "hw/pcmcia.h"
28#include "hw/pc.h"
pbrook87ecb682007-11-17 17:14:51 +000029#include "hw/audiodev.h"
30#include "hw/isa.h"
aurel322e4d9fb2008-04-08 06:01:02 +000031#include "hw/baum.h"
pbrook87ecb682007-11-17 17:14:51 +000032#include "net.h"
33#include "console.h"
34#include "sysemu.h"
35#include "gdbstub.h"
36#include "qemu-timer.h"
37#include "qemu-char.h"
38#include "block.h"
39#include "audio/audio.h"
bellard67b915a2004-03-31 23:37:16 +000040
bellard0824d6f2003-06-24 13:42:40 +000041#include <unistd.h>
bellard0824d6f2003-06-24 13:42:40 +000042#include <fcntl.h>
43#include <signal.h>
44#include <time.h>
bellard0824d6f2003-06-24 13:42:40 +000045#include <errno.h>
bellard67b915a2004-03-31 23:37:16 +000046#include <sys/time.h>
bellardc88676f2006-08-06 13:36:11 +000047#include <zlib.h>
bellard67b915a2004-03-31 23:37:16 +000048
49#ifndef _WIN32
50#include <sys/times.h>
bellardf1510b22003-06-25 00:07:40 +000051#include <sys/wait.h>
bellard67b915a2004-03-31 23:37:16 +000052#include <termios.h>
53#include <sys/poll.h>
54#include <sys/mman.h>
bellardf1510b22003-06-25 00:07:40 +000055#include <sys/ioctl.h>
56#include <sys/socket.h>
bellardc94c8d62004-09-13 21:37:34 +000057#include <netinet/in.h>
bellard9d728e82004-09-05 23:09:03 +000058#include <dirent.h>
bellard7c9d8e02005-11-15 22:16:05 +000059#include <netdb.h>
thscb4b9762007-09-13 12:39:35 +000060#include <sys/select.h>
61#include <arpa/inet.h>
bellard7d3505c2004-05-12 19:32:15 +000062#ifdef _BSD
63#include <sys/stat.h>
blueswir1128ab2f2008-08-15 18:33:42 +000064#if !defined(__APPLE__) && !defined(__OpenBSD__)
bellard7d3505c2004-05-12 19:32:15 +000065#include <libutil.h>
bellard83fb7ad2004-07-05 21:25:26 +000066#endif
blueswir1128ab2f2008-08-15 18:33:42 +000067#ifdef __OpenBSD__
68#include <net/if.h>
69#endif
ths5c40d2b2007-06-23 16:03:36 +000070#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
71#include <freebsd/stdlib.h>
bellard7d3505c2004-05-12 19:32:15 +000072#else
bellardec530c82006-04-25 22:36:06 +000073#ifndef __sun__
bellardf1510b22003-06-25 00:07:40 +000074#include <linux/if.h>
75#include <linux/if_tun.h>
bellard7d3505c2004-05-12 19:32:15 +000076#include <pty.h>
77#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000078#include <linux/rtc.h>
thsbd494f42007-09-16 20:03:23 +000079
80/* For the benefit of older linux systems which don't supply it,
81 we use a local copy of hpet.h. */
82/* #include <linux/hpet.h> */
83#include "hpet.h"
84
bellarde57a8c02005-11-10 23:58:52 +000085#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000086#include <linux/parport.h>
thsd5d10bc2007-02-17 22:54:49 +000087#else
88#include <sys/stat.h>
89#include <sys/ethernet.h>
90#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000091#include <netinet/arp.h>
92#include <netinet/in.h>
93#include <netinet/in_systm.h>
94#include <netinet/ip.h>
95#include <netinet/ip_icmp.h> // must come after ip.h
96#include <netinet/udp.h>
97#include <netinet/tcp.h>
98#include <net/if.h>
99#include <syslog.h>
100#include <stropts.h>
bellard67b915a2004-03-31 23:37:16 +0000101#endif
bellard7d3505c2004-05-12 19:32:15 +0000102#endif
bellardec530c82006-04-25 22:36:06 +0000103#endif
bellard67b915a2004-03-31 23:37:16 +0000104
aliguori03ff3ca2008-09-15 15:51:35 +0000105#include "qemu_socket.h"
106
bellardc20709a2004-04-21 23:27:19 +0000107#if defined(CONFIG_SLIRP)
108#include "libslirp.h"
109#endif
110
blueswir19892fbf2008-08-24 10:34:20 +0000111#if defined(__OpenBSD__)
112#include <util.h>
113#endif
114
ths8a16d272008-07-19 09:56:24 +0000115#if defined(CONFIG_VDE)
116#include <libvdeplug.h>
117#endif
118
bellard67b915a2004-03-31 23:37:16 +0000119#ifdef _WIN32
bellard7d3505c2004-05-12 19:32:15 +0000120#include <malloc.h>
bellard67b915a2004-03-31 23:37:16 +0000121#include <sys/timeb.h>
ths4fddf622007-12-17 04:42:29 +0000122#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000123#define getopt_long_only getopt_long
124#define memalign(align, size) malloc(size)
125#endif
126
bellard73332e52004-04-04 20:22:28 +0000127#ifdef CONFIG_SDL
bellard96bcd4f2004-07-10 16:26:15 +0000128#ifdef __APPLE__
bellard83fb7ad2004-07-05 21:25:26 +0000129#include <SDL/SDL.h>
bellard96bcd4f2004-07-10 16:26:15 +0000130#endif
bellard73332e52004-04-04 20:22:28 +0000131#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000132
bellard5b0753e2005-03-01 21:37:28 +0000133#ifdef CONFIG_COCOA
134#undef main
135#define main qemu_main
136#endif /* CONFIG_COCOA */
137
bellard0824d6f2003-06-24 13:42:40 +0000138#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000139
bellard8a7ddc32004-03-31 19:00:16 +0000140#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000141
bellard5a671352003-10-01 00:13:48 +0000142#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
thsb46a8902007-10-21 23:20:45 +0000143#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
pbrooka14d6c82006-12-23 15:37:33 +0000144#ifdef __sun__
145#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
146#else
147#define SMBD_COMMAND "/usr/sbin/smbd"
148#endif
bellardf1510b22003-06-25 00:07:40 +0000149
bellard0824d6f2003-06-24 13:42:40 +0000150//#define DEBUG_UNUSED_IOPORT
bellardfd872592004-05-12 19:11:15 +0000151//#define DEBUG_IOPORT
bellard330d0412003-07-26 18:11:40 +0000152
bellard77d4bc32004-05-26 22:13:53 +0000153#ifdef TARGET_PPC
154#define DEFAULT_RAM_SIZE 144
155#else
bellard1bfe8562004-07-08 21:17:50 +0000156#define DEFAULT_RAM_SIZE 128
bellard77d4bc32004-05-26 22:13:53 +0000157#endif
bellard313aa562003-08-10 21:52:11 +0000158
pbrook0d92ed32006-05-21 16:30:15 +0000159/* Max number of USB devices that can be specified on the commandline. */
160#define MAX_USB_CMDLINE 8
161
bellard7dea1da2003-11-16 15:59:30 +0000162/* XXX: use a two level table to limit memory usage */
163#define MAX_IOPORTS 65536
bellard0824d6f2003-06-24 13:42:40 +0000164
bellard80cabfa2004-03-14 12:20:30 +0000165const char *bios_dir = CONFIG_QEMU_SHAREDIR;
j_mayer1192dad2007-10-05 13:08:35 +0000166const char *bios_name = NULL;
bellardc4b1fcc2004-03-14 21:44:30 +0000167void *ioport_opaque[MAX_IOPORTS];
bellardfc01f7e2003-06-30 10:03:06 +0000168IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
169IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
thse4bcb142007-12-02 04:51:10 +0000170/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000171 to store the VM snapshots */
thse4bcb142007-12-02 04:51:10 +0000172DriveInfo drives_table[MAX_DRIVES+1];
173int nb_drives;
bellardfaea38e2006-08-05 21:31:00 +0000174/* point to the block driver where the snapshots are managed */
175BlockDriverState *bs_snapshots;
bellard313aa562003-08-10 21:52:11 +0000176int vga_ram_size;
177static DisplayState display_state;
bellarda20dd502003-09-30 21:07:02 +0000178int nographic;
balrog4d3b6f62008-02-10 16:33:14 +0000179int curses;
bellard3d11d0e2004-12-12 16:56:30 +0000180const char* keyboard_layout = NULL;
bellard313aa562003-08-10 21:52:11 +0000181int64_t ticks_per_sec;
aurel3200f82b82008-04-27 21:12:55 +0000182ram_addr_t ram_size;
bellard80cabfa2004-03-14 12:20:30 +0000183int pit_min_timer_count = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000184int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000185NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000186int vm_running;
balrogf6503052008-02-17 11:42:19 +0000187static int rtc_utc = 1;
188static int rtc_date_offset = -1; /* -1 means no change */
bellard1bfe8562004-07-08 21:17:50 +0000189int cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +0000190int vmsvga_enabled = 0;
bellardd8272202005-04-06 20:32:23 +0000191#ifdef TARGET_SPARC
192int graphic_width = 1024;
193int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000194int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000195#else
bellard1bfe8562004-07-08 21:17:50 +0000196int graphic_width = 800;
197int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000198int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000199#endif
bellardd63d3072004-10-03 13:29:03 +0000200int full_screen = 0;
ths43523e92007-02-18 18:19:32 +0000201int no_frame = 0;
ths667acca2006-12-11 02:08:05 +0000202int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000203CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000204CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
bellarda09db212005-04-30 16:10:35 +0000205#ifdef TARGET_I386
206int win2k_install_hack = 0;
207#endif
bellardbb36d472005-11-05 14:22:28 +0000208int usb_enabled = 0;
bellard7c9d8e02005-11-15 22:16:05 +0000209static VLANState *first_vlan;
bellard6a00d602005-11-21 23:25:50 +0000210int smp_cpus = 1;
ths73fc9742006-12-22 02:09:07 +0000211const char *vnc_display;
bellardd3e9db92005-12-17 01:27:28 +0000212#if defined(TARGET_SPARC)
bellardba3c64f2005-12-05 20:31:52 +0000213#define MAX_CPUS 16
bellardd3e9db92005-12-17 01:27:28 +0000214#elif defined(TARGET_I386)
215#define MAX_CPUS 255
bellardba3c64f2005-12-05 20:31:52 +0000216#else
bellardd3e9db92005-12-17 01:27:28 +0000217#define MAX_CPUS 1
bellardba3c64f2005-12-05 20:31:52 +0000218#endif
bellard6515b202006-05-03 22:02:44 +0000219int acpi_enabled = 1;
bellard52ca8d62006-06-14 16:03:05 +0000220int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000221int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000222int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000223int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000224int graphic_rotate = 0;
ths71e3ceb2006-12-22 02:11:31 +0000225int daemonize = 0;
ths9ae02552007-01-05 17:39:04 +0000226const char *option_rom[MAX_OPTION_ROMS];
227int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000228int semihosting_enabled = 0;
pbrook3c07f8e2007-01-21 16:47:01 +0000229int autostart = 1;
balrog2b8f2d42007-07-27 22:08:46 +0000230#ifdef TARGET_ARM
231int old_param = 0;
232#endif
thsc35734b2007-03-19 15:17:08 +0000233const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000234int alt_grab = 0;
blueswir166508602007-05-01 14:16:52 +0000235#ifdef TARGET_SPARC
236unsigned int nb_prom_envs = 0;
237const char *prom_envs[MAX_PROM_ENVS];
238#endif
thse4bcb142007-12-02 04:51:10 +0000239int nb_drives_opt;
balrog609497a2008-01-14 02:56:53 +0000240struct drive_opt {
241 const char *file;
242 char opt[1024];
243} drives_opt[MAX_DRIVES];
bellard0824d6f2003-06-24 13:42:40 +0000244
balrogee5605e2007-12-03 03:01:40 +0000245static CPUState *cur_cpu;
246static CPUState *next_cpu;
balrog76ea08f2007-12-16 11:48:54 +0000247static int event_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000248/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000249static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000250/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000251#define MAX_ICOUNT_SHIFT 10
252/* Compensate for varying guest execution speed. */
253static int64_t qemu_icount_bias;
254QEMUTimer *icount_rt_timer;
255QEMUTimer *icount_vm_timer;
balrogee5605e2007-12-03 03:01:40 +0000256
blueswir18fcb1b92008-09-18 18:29:08 +0000257uint8_t qemu_uuid[16];
258
balrogaeb30be2007-07-02 15:03:13 +0000259#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
260
bellard0824d6f2003-06-24 13:42:40 +0000261/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000262/* x86 ISA bus support */
263
264target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000265PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000266
aliguori477e3ed2008-07-23 15:19:59 +0000267static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
268static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
269
270static uint32_t ioport_read(int index, uint32_t address)
271{
272 static IOPortReadFunc *default_func[3] = {
273 default_ioport_readb,
274 default_ioport_readw,
275 default_ioport_readl
276 };
277 IOPortReadFunc *func = ioport_read_table[index][address];
278 if (!func)
279 func = default_func[index];
280 return func(ioport_opaque[address], address);
281}
282
283static void ioport_write(int index, uint32_t address, uint32_t data)
284{
285 static IOPortWriteFunc *default_func[3] = {
286 default_ioport_writeb,
287 default_ioport_writew,
288 default_ioport_writel
289 };
290 IOPortWriteFunc *func = ioport_write_table[index][address];
291 if (!func)
292 func = default_func[index];
293 func(ioport_opaque[address], address, data);
294}
295
pbrook9596ebb2007-11-18 01:44:38 +0000296static uint32_t default_ioport_readb(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000297{
298#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000299 fprintf(stderr, "unused inb: port=0x%04x\n", address);
bellard0824d6f2003-06-24 13:42:40 +0000300#endif
bellardfc01f7e2003-06-30 10:03:06 +0000301 return 0xff;
bellard0824d6f2003-06-24 13:42:40 +0000302}
303
pbrook9596ebb2007-11-18 01:44:38 +0000304static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000305{
306#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000307 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
bellard0824d6f2003-06-24 13:42:40 +0000308#endif
309}
310
311/* default is to make two byte accesses */
pbrook9596ebb2007-11-18 01:44:38 +0000312static uint32_t default_ioport_readw(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000313{
314 uint32_t data;
aliguori477e3ed2008-07-23 15:19:59 +0000315 data = ioport_read(0, address);
bellarddb45c292004-05-12 19:50:26 +0000316 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000317 data |= ioport_read(0, address) << 8;
bellard0824d6f2003-06-24 13:42:40 +0000318 return data;
319}
320
pbrook9596ebb2007-11-18 01:44:38 +0000321static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000322{
aliguori477e3ed2008-07-23 15:19:59 +0000323 ioport_write(0, address, data & 0xff);
bellarddb45c292004-05-12 19:50:26 +0000324 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000325 ioport_write(0, address, (data >> 8) & 0xff);
bellardfc01f7e2003-06-30 10:03:06 +0000326}
327
pbrook9596ebb2007-11-18 01:44:38 +0000328static uint32_t default_ioport_readl(void *opaque, uint32_t address)
bellardfc01f7e2003-06-30 10:03:06 +0000329{
330#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000331 fprintf(stderr, "unused inl: port=0x%04x\n", address);
bellardfc01f7e2003-06-30 10:03:06 +0000332#endif
333 return 0xffffffff;
334}
335
pbrook9596ebb2007-11-18 01:44:38 +0000336static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
bellardfc01f7e2003-06-30 10:03:06 +0000337{
338#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000339 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
bellardfc01f7e2003-06-30 10:03:06 +0000340#endif
bellard0824d6f2003-06-24 13:42:40 +0000341}
342
bellardfc01f7e2003-06-30 10:03:06 +0000343/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000344int register_ioport_read(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000345 IOPortReadFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000346{
bellardfc01f7e2003-06-30 10:03:06 +0000347 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000348
bellardc4b1fcc2004-03-14 21:44:30 +0000349 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000350 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000351 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000352 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000353 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000354 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000355 } else {
balrog88fdf562008-04-26 21:11:22 +0000356 hw_error("register_ioport_read: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000357 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000358 }
359 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000360 ioport_read_table[bsize][i] = func;
bellardc4b1fcc2004-03-14 21:44:30 +0000361 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
balrog88fdf562008-04-26 21:11:22 +0000362 hw_error("register_ioport_read: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000363 ioport_opaque[i] = opaque;
364 }
bellard0824d6f2003-06-24 13:42:40 +0000365 return 0;
366}
367
bellardfc01f7e2003-06-30 10:03:06 +0000368/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000369int register_ioport_write(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000370 IOPortWriteFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000371{
bellardfc01f7e2003-06-30 10:03:06 +0000372 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000373
bellardc4b1fcc2004-03-14 21:44:30 +0000374 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000375 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000376 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000377 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000378 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000379 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000380 } else {
balrog88fdf562008-04-26 21:11:22 +0000381 hw_error("register_ioport_write: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000382 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000383 }
384 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000385 ioport_write_table[bsize][i] = func;
balrog88fdf562008-04-26 21:11:22 +0000386 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
387 hw_error("register_ioport_write: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000388 ioport_opaque[i] = opaque;
389 }
bellardf1510b22003-06-25 00:07:40 +0000390 return 0;
391}
392
bellard69b91032004-05-18 23:05:28 +0000393void isa_unassign_ioport(int start, int length)
394{
395 int i;
396
397 for(i = start; i < start + length; i++) {
398 ioport_read_table[0][i] = default_ioport_readb;
399 ioport_read_table[1][i] = default_ioport_readw;
400 ioport_read_table[2][i] = default_ioport_readl;
401
402 ioport_write_table[0][i] = default_ioport_writeb;
403 ioport_write_table[1][i] = default_ioport_writew;
404 ioport_write_table[2][i] = default_ioport_writel;
405 }
406}
407
bellard20f32282005-01-03 23:36:21 +0000408/***********************************************************/
409
bellardc45886d2004-01-05 00:02:06 +0000410void cpu_outb(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000411{
bellardfd872592004-05-12 19:11:15 +0000412#ifdef DEBUG_IOPORT
413 if (loglevel & CPU_LOG_IOPORT)
414 fprintf(logfile, "outb: %04x %02x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000415#endif
aliguori477e3ed2008-07-23 15:19:59 +0000416 ioport_write(0, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000417#ifdef USE_KQEMU
418 if (env)
419 env->last_io_time = cpu_get_time_fast();
420#endif
bellard0824d6f2003-06-24 13:42:40 +0000421}
422
bellardc45886d2004-01-05 00:02:06 +0000423void cpu_outw(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000424{
bellardfd872592004-05-12 19:11:15 +0000425#ifdef DEBUG_IOPORT
426 if (loglevel & CPU_LOG_IOPORT)
427 fprintf(logfile, "outw: %04x %04x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000428#endif
aliguori477e3ed2008-07-23 15:19:59 +0000429 ioport_write(1, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000430#ifdef USE_KQEMU
431 if (env)
432 env->last_io_time = cpu_get_time_fast();
433#endif
bellard0824d6f2003-06-24 13:42:40 +0000434}
435
bellardc45886d2004-01-05 00:02:06 +0000436void cpu_outl(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000437{
bellardfd872592004-05-12 19:11:15 +0000438#ifdef DEBUG_IOPORT
439 if (loglevel & CPU_LOG_IOPORT)
440 fprintf(logfile, "outl: %04x %08x\n", addr, val);
441#endif
aliguori477e3ed2008-07-23 15:19:59 +0000442 ioport_write(2, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000443#ifdef USE_KQEMU
444 if (env)
445 env->last_io_time = cpu_get_time_fast();
446#endif
bellard0824d6f2003-06-24 13:42:40 +0000447}
448
bellardc45886d2004-01-05 00:02:06 +0000449int cpu_inb(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000450{
bellardfd872592004-05-12 19:11:15 +0000451 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000452 val = ioport_read(0, addr);
bellardfd872592004-05-12 19:11:15 +0000453#ifdef DEBUG_IOPORT
454 if (loglevel & CPU_LOG_IOPORT)
455 fprintf(logfile, "inb : %04x %02x\n", addr, val);
456#endif
bellard89bfc102006-02-08 22:46:31 +0000457#ifdef USE_KQEMU
458 if (env)
459 env->last_io_time = cpu_get_time_fast();
460#endif
bellardfd872592004-05-12 19:11:15 +0000461 return val;
bellard0824d6f2003-06-24 13:42:40 +0000462}
463
bellardc45886d2004-01-05 00:02:06 +0000464int cpu_inw(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000465{
bellardfd872592004-05-12 19:11:15 +0000466 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000467 val = ioport_read(1, addr);
bellardfd872592004-05-12 19:11:15 +0000468#ifdef DEBUG_IOPORT
469 if (loglevel & CPU_LOG_IOPORT)
470 fprintf(logfile, "inw : %04x %04x\n", addr, val);
471#endif
bellard89bfc102006-02-08 22:46:31 +0000472#ifdef USE_KQEMU
473 if (env)
474 env->last_io_time = cpu_get_time_fast();
475#endif
bellardfd872592004-05-12 19:11:15 +0000476 return val;
bellard0824d6f2003-06-24 13:42:40 +0000477}
478
bellardc45886d2004-01-05 00:02:06 +0000479int cpu_inl(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000480{
bellardfd872592004-05-12 19:11:15 +0000481 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000482 val = ioport_read(2, addr);
bellardfd872592004-05-12 19:11:15 +0000483#ifdef DEBUG_IOPORT
484 if (loglevel & CPU_LOG_IOPORT)
485 fprintf(logfile, "inl : %04x %08x\n", addr, val);
486#endif
bellard89bfc102006-02-08 22:46:31 +0000487#ifdef USE_KQEMU
488 if (env)
489 env->last_io_time = cpu_get_time_fast();
490#endif
bellardfd872592004-05-12 19:11:15 +0000491 return val;
bellard0824d6f2003-06-24 13:42:40 +0000492}
493
494/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000495void hw_error(const char *fmt, ...)
496{
497 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000498 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000499
500 va_start(ap, fmt);
501 fprintf(stderr, "qemu: hardware error: ");
502 vfprintf(stderr, fmt, ap);
503 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000504 for(env = first_cpu; env != NULL; env = env->next_cpu) {
505 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000506#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000507 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000508#else
bellard6a00d602005-11-21 23:25:50 +0000509 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000510#endif
bellard6a00d602005-11-21 23:25:50 +0000511 }
bellard0824d6f2003-06-24 13:42:40 +0000512 va_end(ap);
513 abort();
514}
515
bellard8a7ddc32004-03-31 19:00:16 +0000516/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000517/* keyboard/mouse */
518
519static QEMUPutKBDEvent *qemu_put_kbd_event;
520static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000521static QEMUPutMouseEntry *qemu_put_mouse_event_head;
522static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000523
524void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
525{
526 qemu_put_kbd_event_opaque = opaque;
527 qemu_put_kbd_event = func;
528}
529
ths455204e2007-01-05 16:42:13 +0000530QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
531 void *opaque, int absolute,
532 const char *name)
bellard63066f42004-06-03 18:45:02 +0000533{
ths455204e2007-01-05 16:42:13 +0000534 QEMUPutMouseEntry *s, *cursor;
535
536 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
537 if (!s)
538 return NULL;
539
540 s->qemu_put_mouse_event = func;
541 s->qemu_put_mouse_event_opaque = opaque;
542 s->qemu_put_mouse_event_absolute = absolute;
543 s->qemu_put_mouse_event_name = qemu_strdup(name);
544 s->next = NULL;
545
546 if (!qemu_put_mouse_event_head) {
547 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
548 return s;
549 }
550
551 cursor = qemu_put_mouse_event_head;
552 while (cursor->next != NULL)
553 cursor = cursor->next;
554
555 cursor->next = s;
556 qemu_put_mouse_event_current = s;
557
558 return s;
559}
560
561void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
562{
563 QEMUPutMouseEntry *prev = NULL, *cursor;
564
565 if (!qemu_put_mouse_event_head || entry == NULL)
566 return;
567
568 cursor = qemu_put_mouse_event_head;
569 while (cursor != NULL && cursor != entry) {
570 prev = cursor;
571 cursor = cursor->next;
572 }
573
574 if (cursor == NULL) // does not exist or list empty
575 return;
576 else if (prev == NULL) { // entry is head
577 qemu_put_mouse_event_head = cursor->next;
578 if (qemu_put_mouse_event_current == entry)
579 qemu_put_mouse_event_current = cursor->next;
580 qemu_free(entry->qemu_put_mouse_event_name);
581 qemu_free(entry);
582 return;
583 }
584
585 prev->next = entry->next;
586
587 if (qemu_put_mouse_event_current == entry)
588 qemu_put_mouse_event_current = prev;
589
590 qemu_free(entry->qemu_put_mouse_event_name);
591 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000592}
593
594void kbd_put_keycode(int keycode)
595{
596 if (qemu_put_kbd_event) {
597 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
598 }
599}
600
601void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
602{
ths455204e2007-01-05 16:42:13 +0000603 QEMUPutMouseEvent *mouse_event;
604 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000605 int width;
ths455204e2007-01-05 16:42:13 +0000606
607 if (!qemu_put_mouse_event_current) {
608 return;
609 }
610
611 mouse_event =
612 qemu_put_mouse_event_current->qemu_put_mouse_event;
613 mouse_event_opaque =
614 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
615
616 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000617 if (graphic_rotate) {
618 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
619 width = 0x7fff;
620 else
aurel32b94ed572008-03-10 19:34:27 +0000621 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000622 mouse_event(mouse_event_opaque,
623 width - dy, dx, dz, buttons_state);
624 } else
625 mouse_event(mouse_event_opaque,
626 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000627 }
628}
629
bellard09b26c52006-04-12 21:09:08 +0000630int kbd_mouse_is_absolute(void)
631{
ths455204e2007-01-05 16:42:13 +0000632 if (!qemu_put_mouse_event_current)
633 return 0;
634
635 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
636}
637
638void do_info_mice(void)
639{
640 QEMUPutMouseEntry *cursor;
641 int index = 0;
642
643 if (!qemu_put_mouse_event_head) {
644 term_printf("No mouse devices connected\n");
645 return;
646 }
647
648 term_printf("Mouse devices available:\n");
649 cursor = qemu_put_mouse_event_head;
650 while (cursor != NULL) {
651 term_printf("%c Mouse #%d: %s\n",
652 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
653 index, cursor->qemu_put_mouse_event_name);
654 index++;
655 cursor = cursor->next;
656 }
657}
658
659void do_mouse_set(int index)
660{
661 QEMUPutMouseEntry *cursor;
662 int i = 0;
663
664 if (!qemu_put_mouse_event_head) {
665 term_printf("No mouse devices connected\n");
666 return;
667 }
668
669 cursor = qemu_put_mouse_event_head;
670 while (cursor != NULL && index != i) {
671 i++;
672 cursor = cursor->next;
673 }
674
675 if (cursor != NULL)
676 qemu_put_mouse_event_current = cursor;
677 else
678 term_printf("Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000679}
680
bellard87858c82003-06-27 12:01:39 +0000681/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000682uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000683{
684 union {
685 uint64_t ll;
686 struct {
687#ifdef WORDS_BIGENDIAN
688 uint32_t high, low;
689#else
690 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000691#endif
bellard87858c82003-06-27 12:01:39 +0000692 } l;
693 } u, res;
694 uint64_t rl, rh;
695
696 u.ll = a;
697 rl = (uint64_t)u.l.low * (uint64_t)b;
698 rh = (uint64_t)u.l.high * (uint64_t)b;
699 rh += (rl >> 32);
700 res.l.high = rh / c;
701 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
702 return res.ll;
703}
704
bellard1dce7c32006-07-13 23:20:22 +0000705/***********************************************************/
706/* real time host monotonic timer */
707
708#define QEMU_TIMER_BASE 1000000000LL
709
710#ifdef WIN32
711
712static int64_t clock_freq;
713
714static void init_get_clock(void)
715{
bellarda8e5ac32006-07-14 09:36:13 +0000716 LARGE_INTEGER freq;
717 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000718 ret = QueryPerformanceFrequency(&freq);
719 if (ret == 0) {
720 fprintf(stderr, "Could not calibrate ticks\n");
721 exit(1);
722 }
723 clock_freq = freq.QuadPart;
724}
725
726static int64_t get_clock(void)
727{
728 LARGE_INTEGER ti;
729 QueryPerformanceCounter(&ti);
730 return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
731}
732
733#else
734
735static int use_rt_clock;
736
737static void init_get_clock(void)
738{
739 use_rt_clock = 0;
740#if defined(__linux__)
741 {
742 struct timespec ts;
743 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
744 use_rt_clock = 1;
745 }
746 }
747#endif
748}
749
750static int64_t get_clock(void)
751{
752#if defined(__linux__)
753 if (use_rt_clock) {
754 struct timespec ts;
755 clock_gettime(CLOCK_MONOTONIC, &ts);
756 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000757 } else
bellard1dce7c32006-07-13 23:20:22 +0000758#endif
759 {
760 /* XXX: using gettimeofday leads to problems if the date
761 changes, so it should be avoided. */
762 struct timeval tv;
763 gettimeofday(&tv, NULL);
764 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
765 }
766}
bellard1dce7c32006-07-13 23:20:22 +0000767#endif
768
pbrook2e70f6e2008-06-29 01:03:05 +0000769/* Return the virtual CPU time, based on the instruction counter. */
770static int64_t cpu_get_icount(void)
771{
772 int64_t icount;
773 CPUState *env = cpu_single_env;;
774 icount = qemu_icount;
775 if (env) {
776 if (!can_do_io(env))
777 fprintf(stderr, "Bad clock read\n");
778 icount -= (env->icount_decr.u16.low + env->icount_extra);
779 }
780 return qemu_icount_bias + (icount << icount_time_shift);
781}
782
bellard1dce7c32006-07-13 23:20:22 +0000783/***********************************************************/
784/* guest cycle counter */
785
786static int64_t cpu_ticks_prev;
787static int64_t cpu_ticks_offset;
788static int64_t cpu_clock_offset;
789static int cpu_ticks_enabled;
790
791/* return the host CPU cycle counter and handle stop/restart */
792int64_t cpu_get_ticks(void)
793{
pbrook2e70f6e2008-06-29 01:03:05 +0000794 if (use_icount) {
795 return cpu_get_icount();
796 }
bellard1dce7c32006-07-13 23:20:22 +0000797 if (!cpu_ticks_enabled) {
798 return cpu_ticks_offset;
799 } else {
800 int64_t ticks;
801 ticks = cpu_get_real_ticks();
802 if (cpu_ticks_prev > ticks) {
803 /* Note: non increasing ticks may happen if the host uses
804 software suspend */
805 cpu_ticks_offset += cpu_ticks_prev - ticks;
806 }
807 cpu_ticks_prev = ticks;
808 return ticks + cpu_ticks_offset;
809 }
810}
811
812/* return the host CPU monotonic timer and handle stop/restart */
813static int64_t cpu_get_clock(void)
814{
815 int64_t ti;
816 if (!cpu_ticks_enabled) {
817 return cpu_clock_offset;
818 } else {
819 ti = get_clock();
820 return ti + cpu_clock_offset;
821 }
822}
823
824/* enable cpu_get_ticks() */
825void cpu_enable_ticks(void)
826{
827 if (!cpu_ticks_enabled) {
828 cpu_ticks_offset -= cpu_get_real_ticks();
829 cpu_clock_offset -= get_clock();
830 cpu_ticks_enabled = 1;
831 }
832}
833
834/* disable cpu_get_ticks() : the clock is stopped. You must not call
835 cpu_get_ticks() after that. */
836void cpu_disable_ticks(void)
837{
838 if (cpu_ticks_enabled) {
839 cpu_ticks_offset = cpu_get_ticks();
840 cpu_clock_offset = cpu_get_clock();
841 cpu_ticks_enabled = 0;
842 }
843}
844
845/***********************************************************/
846/* timers */
ths5fafdf22007-09-16 21:08:06 +0000847
bellard8a7ddc32004-03-31 19:00:16 +0000848#define QEMU_TIMER_REALTIME 0
849#define QEMU_TIMER_VIRTUAL 1
850
851struct QEMUClock {
852 int type;
853 /* XXX: add frequency */
854};
855
856struct QEMUTimer {
857 QEMUClock *clock;
858 int64_t expire_time;
859 QEMUTimerCB *cb;
860 void *opaque;
861 struct QEMUTimer *next;
862};
863
thsc8994012007-08-19 21:56:03 +0000864struct qemu_alarm_timer {
865 char const *name;
thsefe75412007-08-24 01:36:32 +0000866 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000867
868 int (*start)(struct qemu_alarm_timer *t);
869 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000870 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000871 void *priv;
872};
873
thsefe75412007-08-24 01:36:32 +0000874#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000875#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000876
877static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
878{
879 return t->flags & ALARM_FLAG_DYNTICKS;
880}
881
882static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
883{
884 if (!alarm_has_dynticks(t))
885 return;
886
887 t->rearm(t);
888}
889
890/* TODO: MIN_TIMER_REARM_US should be optimized */
891#define MIN_TIMER_REARM_US 250
892
thsc8994012007-08-19 21:56:03 +0000893static struct qemu_alarm_timer *alarm_timer;
894
895#ifdef _WIN32
896
897struct qemu_alarm_win32 {
898 MMRESULT timerId;
899 HANDLE host_alarm;
900 unsigned int period;
901} alarm_win32_data = {0, NULL, -1};
902
903static int win32_start_timer(struct qemu_alarm_timer *t);
904static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000905static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000906
907#else
908
909static int unix_start_timer(struct qemu_alarm_timer *t);
910static void unix_stop_timer(struct qemu_alarm_timer *t);
911
ths231c6582007-08-26 17:29:15 +0000912#ifdef __linux__
913
thsefe75412007-08-24 01:36:32 +0000914static int dynticks_start_timer(struct qemu_alarm_timer *t);
915static void dynticks_stop_timer(struct qemu_alarm_timer *t);
916static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
917
thsc40ec5a2007-08-19 22:09:40 +0000918static int hpet_start_timer(struct qemu_alarm_timer *t);
919static void hpet_stop_timer(struct qemu_alarm_timer *t);
920
thsc8994012007-08-19 21:56:03 +0000921static int rtc_start_timer(struct qemu_alarm_timer *t);
922static void rtc_stop_timer(struct qemu_alarm_timer *t);
923
thsefe75412007-08-24 01:36:32 +0000924#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000925
926#endif /* _WIN32 */
927
pbrook2e70f6e2008-06-29 01:03:05 +0000928/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000929 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000930 When the guest is idle real and virtual time will be aligned in
931 the IO wait loop. */
932#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
933
934static void icount_adjust(void)
935{
936 int64_t cur_time;
937 int64_t cur_icount;
938 int64_t delta;
939 static int64_t last_delta;
940 /* If the VM is not running, then do nothing. */
941 if (!vm_running)
942 return;
943
944 cur_time = cpu_get_clock();
945 cur_icount = qemu_get_clock(vm_clock);
946 delta = cur_icount - cur_time;
947 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
948 if (delta > 0
949 && last_delta + ICOUNT_WOBBLE < delta * 2
950 && icount_time_shift > 0) {
951 /* The guest is getting too far ahead. Slow time down. */
952 icount_time_shift--;
953 }
954 if (delta < 0
955 && last_delta - ICOUNT_WOBBLE > delta * 2
956 && icount_time_shift < MAX_ICOUNT_SHIFT) {
957 /* The guest is getting too far behind. Speed time up. */
958 icount_time_shift++;
959 }
960 last_delta = delta;
961 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
962}
963
964static void icount_adjust_rt(void * opaque)
965{
966 qemu_mod_timer(icount_rt_timer,
967 qemu_get_clock(rt_clock) + 1000);
968 icount_adjust();
969}
970
971static void icount_adjust_vm(void * opaque)
972{
973 qemu_mod_timer(icount_vm_timer,
974 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
975 icount_adjust();
976}
977
978static void init_icount_adjust(void)
979{
980 /* Have both realtime and virtual time triggers for speed adjustment.
981 The realtime trigger catches emulated time passing too slowly,
982 the virtual time trigger catches emulated time passing too fast.
983 Realtime triggers occur even when idle, so use them less frequently
984 than VM triggers. */
985 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
986 qemu_mod_timer(icount_rt_timer,
987 qemu_get_clock(rt_clock) + 1000);
988 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
989 qemu_mod_timer(icount_vm_timer,
990 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
991}
992
thsc8994012007-08-19 21:56:03 +0000993static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000994#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000995#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000996 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
997 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000998 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +0000999 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +00001000 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +00001001 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001002#endif
thsefe75412007-08-24 01:36:32 +00001003 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001004#else
thsefe75412007-08-24 01:36:32 +00001005 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
1006 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
1007 {"win32", 0, win32_start_timer,
1008 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +00001009#endif
1010 {NULL, }
1011};
1012
blueswir13f47aa82008-03-09 06:59:01 +00001013static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +00001014{
1015 int i;
1016
1017 printf("Available alarm timers, in order of precedence:\n");
1018 for (i = 0; alarm_timers[i].name; i++)
1019 printf("%s\n", alarm_timers[i].name);
1020}
1021
1022static void configure_alarms(char const *opt)
1023{
1024 int i;
1025 int cur = 0;
1026 int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
1027 char *arg;
1028 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +00001029 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +00001030
aurel323adda042008-03-09 23:43:49 +00001031 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +00001032 show_available_alarms();
1033 exit(0);
1034 }
1035
1036 arg = strdup(opt);
1037
1038 /* Reorder the array */
1039 name = strtok(arg, ",");
1040 while (name) {
balroge2b577e2007-09-17 21:25:20 +00001041 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +00001042 if (!strcmp(alarm_timers[i].name, name))
1043 break;
1044 }
1045
1046 if (i == count) {
1047 fprintf(stderr, "Unknown clock %s\n", name);
1048 goto next;
1049 }
1050
1051 if (i < cur)
1052 /* Ignore */
1053 goto next;
1054
1055 /* Swap */
1056 tmp = alarm_timers[i];
1057 alarm_timers[i] = alarm_timers[cur];
1058 alarm_timers[cur] = tmp;
1059
1060 cur++;
1061next:
1062 name = strtok(NULL, ",");
1063 }
1064
1065 free(arg);
1066
1067 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +00001068 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +00001069 for (i = cur; i < count; i++)
1070 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +00001071 } else {
1072 show_available_alarms();
1073 exit(1);
thsf3dcfad2007-08-24 01:26:02 +00001074 }
thsf3dcfad2007-08-24 01:26:02 +00001075}
1076
bellard8a7ddc32004-03-31 19:00:16 +00001077QEMUClock *rt_clock;
1078QEMUClock *vm_clock;
1079
1080static QEMUTimer *active_timers[2];
bellard8a7ddc32004-03-31 19:00:16 +00001081
pbrook9596ebb2007-11-18 01:44:38 +00001082static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +00001083{
1084 QEMUClock *clock;
1085 clock = qemu_mallocz(sizeof(QEMUClock));
1086 if (!clock)
1087 return NULL;
1088 clock->type = type;
1089 return clock;
1090}
1091
1092QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
1093{
1094 QEMUTimer *ts;
1095
1096 ts = qemu_mallocz(sizeof(QEMUTimer));
1097 ts->clock = clock;
1098 ts->cb = cb;
1099 ts->opaque = opaque;
1100 return ts;
1101}
1102
1103void qemu_free_timer(QEMUTimer *ts)
1104{
1105 qemu_free(ts);
1106}
1107
1108/* stop a timer, but do not dealloc it */
1109void qemu_del_timer(QEMUTimer *ts)
1110{
1111 QEMUTimer **pt, *t;
1112
1113 /* NOTE: this code must be signal safe because
1114 qemu_timer_expired() can be called from a signal. */
1115 pt = &active_timers[ts->clock->type];
1116 for(;;) {
1117 t = *pt;
1118 if (!t)
1119 break;
1120 if (t == ts) {
1121 *pt = t->next;
1122 break;
1123 }
1124 pt = &t->next;
1125 }
1126}
1127
1128/* modify the current timer so that it will be fired when current_time
1129 >= expire_time. The corresponding callback will be called. */
1130void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1131{
1132 QEMUTimer **pt, *t;
1133
1134 qemu_del_timer(ts);
1135
1136 /* add the timer in the sorted list */
1137 /* NOTE: this code must be signal safe because
1138 qemu_timer_expired() can be called from a signal. */
1139 pt = &active_timers[ts->clock->type];
1140 for(;;) {
1141 t = *pt;
1142 if (!t)
1143 break;
ths5fafdf22007-09-16 21:08:06 +00001144 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +00001145 break;
1146 pt = &t->next;
1147 }
1148 ts->expire_time = expire_time;
1149 ts->next = *pt;
1150 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +00001151
1152 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +00001153 if (pt == &active_timers[ts->clock->type]) {
1154 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
1155 qemu_rearm_alarm_timer(alarm_timer);
1156 }
1157 /* Interrupt execution to force deadline recalculation. */
1158 if (use_icount && cpu_single_env) {
1159 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1160 }
1161 }
bellard8a7ddc32004-03-31 19:00:16 +00001162}
1163
1164int qemu_timer_pending(QEMUTimer *ts)
1165{
1166 QEMUTimer *t;
1167 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1168 if (t == ts)
1169 return 1;
1170 }
1171 return 0;
1172}
1173
1174static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1175{
1176 if (!timer_head)
1177 return 0;
1178 return (timer_head->expire_time <= current_time);
1179}
1180
1181static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1182{
1183 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001184
bellard8a7ddc32004-03-31 19:00:16 +00001185 for(;;) {
1186 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001187 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001188 break;
1189 /* remove timer from the list before calling the callback */
1190 *ptimer_head = ts->next;
1191 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001192
bellard8a7ddc32004-03-31 19:00:16 +00001193 /* run the callback (the timer list can be modified) */
1194 ts->cb(ts->opaque);
1195 }
1196}
1197
1198int64_t qemu_get_clock(QEMUClock *clock)
1199{
1200 switch(clock->type) {
1201 case QEMU_TIMER_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001202 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001203 default:
1204 case QEMU_TIMER_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001205 if (use_icount) {
1206 return cpu_get_icount();
1207 } else {
1208 return cpu_get_clock();
1209 }
bellard8a7ddc32004-03-31 19:00:16 +00001210 }
1211}
1212
bellard1dce7c32006-07-13 23:20:22 +00001213static void init_timers(void)
1214{
1215 init_get_clock();
1216 ticks_per_sec = QEMU_TIMER_BASE;
1217 rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1218 vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1219}
1220
bellard8a7ddc32004-03-31 19:00:16 +00001221/* save a timer */
1222void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1223{
1224 uint64_t expire_time;
1225
1226 if (qemu_timer_pending(ts)) {
1227 expire_time = ts->expire_time;
1228 } else {
1229 expire_time = -1;
1230 }
1231 qemu_put_be64(f, expire_time);
1232}
1233
1234void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1235{
1236 uint64_t expire_time;
1237
1238 expire_time = qemu_get_be64(f);
1239 if (expire_time != -1) {
1240 qemu_mod_timer(ts, expire_time);
1241 } else {
1242 qemu_del_timer(ts);
1243 }
1244}
1245
1246static void timer_save(QEMUFile *f, void *opaque)
1247{
1248 if (cpu_ticks_enabled) {
1249 hw_error("cannot save state if virtual timers are running");
1250 }
thsbee8d682007-12-16 23:41:11 +00001251 qemu_put_be64(f, cpu_ticks_offset);
1252 qemu_put_be64(f, ticks_per_sec);
1253 qemu_put_be64(f, cpu_clock_offset);
bellard8a7ddc32004-03-31 19:00:16 +00001254}
1255
1256static int timer_load(QEMUFile *f, void *opaque, int version_id)
1257{
bellardc88676f2006-08-06 13:36:11 +00001258 if (version_id != 1 && version_id != 2)
bellard8a7ddc32004-03-31 19:00:16 +00001259 return -EINVAL;
1260 if (cpu_ticks_enabled) {
1261 return -EINVAL;
1262 }
thsbee8d682007-12-16 23:41:11 +00001263 cpu_ticks_offset=qemu_get_be64(f);
1264 ticks_per_sec=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001265 if (version_id == 2) {
thsbee8d682007-12-16 23:41:11 +00001266 cpu_clock_offset=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001267 }
bellard8a7ddc32004-03-31 19:00:16 +00001268 return 0;
1269}
1270
bellard67b915a2004-03-31 23:37:16 +00001271#ifdef _WIN32
ths5fafdf22007-09-16 21:08:06 +00001272void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
bellard67b915a2004-03-31 23:37:16 +00001273 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1274#else
bellard8a7ddc32004-03-31 19:00:16 +00001275static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001276#endif
bellard8a7ddc32004-03-31 19:00:16 +00001277{
bellard02ba45c2004-06-25 14:46:23 +00001278#if 0
1279#define DISP_FREQ 1000
1280 {
1281 static int64_t delta_min = INT64_MAX;
1282 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1283 static int count;
1284 ti = qemu_get_clock(vm_clock);
1285 if (last_clock != 0) {
1286 delta = ti - last_clock;
1287 if (delta < delta_min)
1288 delta_min = delta;
1289 if (delta > delta_max)
1290 delta_max = delta;
1291 delta_cum += delta;
1292 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001293 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
bellard02ba45c2004-06-25 14:46:23 +00001294 muldiv64(delta_min, 1000000, ticks_per_sec),
1295 muldiv64(delta_max, 1000000, ticks_per_sec),
1296 muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1297 (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1298 count = 0;
1299 delta_min = INT64_MAX;
1300 delta_max = 0;
1301 delta_cum = 0;
1302 }
1303 }
1304 last_clock = ti;
1305 }
1306#endif
thsefe75412007-08-24 01:36:32 +00001307 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001308 (!use_icount &&
1309 qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1310 qemu_get_clock(vm_clock))) ||
bellard8a7ddc32004-03-31 19:00:16 +00001311 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1312 qemu_get_clock(rt_clock))) {
bellard06d9f2f2006-05-01 13:23:04 +00001313#ifdef _WIN32
thsc8994012007-08-19 21:56:03 +00001314 struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1315 SetEvent(data->host_alarm);
bellard06d9f2f2006-05-01 13:23:04 +00001316#endif
balrogee5605e2007-12-03 03:01:40 +00001317 CPUState *env = next_cpu;
1318
balrogd5d08332008-01-05 19:41:47 +00001319 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1320
balrog4f8eb8d2007-12-16 12:39:38 +00001321 if (env) {
1322 /* stop the currently executing cpu because a timer occured */
1323 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
bellarda332e112005-09-03 17:55:47 +00001324#ifdef USE_KQEMU
balrog4f8eb8d2007-12-16 12:39:38 +00001325 if (env->kqemu_enabled) {
1326 kqemu_cpu_interrupt(env);
1327 }
balrogee5605e2007-12-03 03:01:40 +00001328#endif
balrog4f8eb8d2007-12-16 12:39:38 +00001329 }
balrogee5605e2007-12-03 03:01:40 +00001330 event_pending = 1;
bellard8a7ddc32004-03-31 19:00:16 +00001331 }
1332}
1333
pbrook2e70f6e2008-06-29 01:03:05 +00001334static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001335{
pbrook2e70f6e2008-06-29 01:03:05 +00001336 int64_t delta;
thsefe75412007-08-24 01:36:32 +00001337
1338 if (active_timers[QEMU_TIMER_VIRTUAL]) {
pbrook2e70f6e2008-06-29 01:03:05 +00001339 delta = active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1340 qemu_get_clock(vm_clock);
1341 } else {
1342 /* To avoid problems with overflow limit this to 2^32. */
1343 delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001344 }
1345
pbrook2e70f6e2008-06-29 01:03:05 +00001346 if (delta < 0)
1347 delta = 0;
thsefe75412007-08-24 01:36:32 +00001348
pbrook2e70f6e2008-06-29 01:03:05 +00001349 return delta;
1350}
1351
blueswir18632fb92008-09-14 13:59:34 +00001352#if defined(__linux__) || defined(_WIN32)
pbrook2e70f6e2008-06-29 01:03:05 +00001353static uint64_t qemu_next_deadline_dyntick(void)
1354{
1355 int64_t delta;
1356 int64_t rtdelta;
1357
1358 if (use_icount)
1359 delta = INT32_MAX;
1360 else
1361 delta = (qemu_next_deadline() + 999) / 1000;
1362
1363 if (active_timers[QEMU_TIMER_REALTIME]) {
1364 rtdelta = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
1365 qemu_get_clock(rt_clock))*1000;
1366 if (rtdelta < delta)
1367 delta = rtdelta;
1368 }
1369
1370 if (delta < MIN_TIMER_REARM_US)
1371 delta = MIN_TIMER_REARM_US;
1372
1373 return delta;
thsefe75412007-08-24 01:36:32 +00001374}
blueswir18632fb92008-09-14 13:59:34 +00001375#endif
thsefe75412007-08-24 01:36:32 +00001376
bellardfd872592004-05-12 19:11:15 +00001377#ifndef _WIN32
1378
bellard829309c2004-05-20 13:20:12 +00001379#if defined(__linux__)
1380
bellardfd872592004-05-12 19:11:15 +00001381#define RTC_FREQ 1024
1382
thsc8994012007-08-19 21:56:03 +00001383static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001384{
thsc8994012007-08-19 21:56:03 +00001385 struct sigaction act;
1386
1387 /* timer signal */
1388 sigfillset(&act.sa_mask);
1389 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001390 act.sa_handler = host_alarm_handler;
1391
1392 sigaction(SIGIO, &act, NULL);
1393 fcntl(fd, F_SETFL, O_ASYNC);
1394 fcntl(fd, F_SETOWN, getpid());
1395}
1396
thsc40ec5a2007-08-19 22:09:40 +00001397static int hpet_start_timer(struct qemu_alarm_timer *t)
1398{
1399 struct hpet_info info;
1400 int r, fd;
1401
1402 fd = open("/dev/hpet", O_RDONLY);
1403 if (fd < 0)
1404 return -1;
1405
1406 /* Set frequency */
1407 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1408 if (r < 0) {
1409 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1410 "error, but for better emulation accuracy type:\n"
1411 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1412 goto fail;
1413 }
1414
1415 /* Check capabilities */
1416 r = ioctl(fd, HPET_INFO, &info);
1417 if (r < 0)
1418 goto fail;
1419
1420 /* Enable periodic mode */
1421 r = ioctl(fd, HPET_EPI, 0);
1422 if (info.hi_flags && (r < 0))
1423 goto fail;
1424
1425 /* Enable interrupt */
1426 r = ioctl(fd, HPET_IE_ON, 0);
1427 if (r < 0)
1428 goto fail;
1429
1430 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001431 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001432
1433 return 0;
1434fail:
1435 close(fd);
1436 return -1;
1437}
1438
1439static void hpet_stop_timer(struct qemu_alarm_timer *t)
1440{
pbrookfcdc2122007-08-23 20:22:22 +00001441 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001442
1443 close(fd);
1444}
1445
thsc8994012007-08-19 21:56:03 +00001446static int rtc_start_timer(struct qemu_alarm_timer *t)
1447{
1448 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001449 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001450
balrogaeb30be2007-07-02 15:03:13 +00001451 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001452 if (rtc_fd < 0)
1453 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001454 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1455 if (current_rtc_freq != RTC_FREQ &&
1456 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001457 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1458 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1459 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1460 goto fail;
1461 }
1462 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1463 fail:
1464 close(rtc_fd);
1465 return -1;
1466 }
thsc8994012007-08-19 21:56:03 +00001467
1468 enable_sigio_timer(rtc_fd);
1469
pbrookfcdc2122007-08-23 20:22:22 +00001470 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001471
bellardfd872592004-05-12 19:11:15 +00001472 return 0;
1473}
1474
thsc8994012007-08-19 21:56:03 +00001475static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001476{
pbrookfcdc2122007-08-23 20:22:22 +00001477 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001478
1479 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001480}
1481
thsefe75412007-08-24 01:36:32 +00001482static int dynticks_start_timer(struct qemu_alarm_timer *t)
1483{
1484 struct sigevent ev;
1485 timer_t host_timer;
1486 struct sigaction act;
1487
1488 sigfillset(&act.sa_mask);
1489 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001490 act.sa_handler = host_alarm_handler;
1491
1492 sigaction(SIGALRM, &act, NULL);
1493
1494 ev.sigev_value.sival_int = 0;
1495 ev.sigev_notify = SIGEV_SIGNAL;
1496 ev.sigev_signo = SIGALRM;
1497
1498 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1499 perror("timer_create");
1500
1501 /* disable dynticks */
1502 fprintf(stderr, "Dynamic Ticks disabled\n");
1503
1504 return -1;
1505 }
1506
1507 t->priv = (void *)host_timer;
1508
1509 return 0;
1510}
1511
1512static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1513{
1514 timer_t host_timer = (timer_t)t->priv;
1515
1516 timer_delete(host_timer);
1517}
1518
1519static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1520{
1521 timer_t host_timer = (timer_t)t->priv;
1522 struct itimerspec timeout;
1523 int64_t nearest_delta_us = INT64_MAX;
1524 int64_t current_us;
1525
1526 if (!active_timers[QEMU_TIMER_REALTIME] &&
1527 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001528 return;
thsefe75412007-08-24 01:36:32 +00001529
pbrook2e70f6e2008-06-29 01:03:05 +00001530 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001531
1532 /* check whether a timer is already running */
1533 if (timer_gettime(host_timer, &timeout)) {
1534 perror("gettime");
1535 fprintf(stderr, "Internal timer error: aborting\n");
1536 exit(1);
1537 }
1538 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1539 if (current_us && current_us <= nearest_delta_us)
1540 return;
1541
1542 timeout.it_interval.tv_sec = 0;
1543 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1544 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1545 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1546 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1547 perror("settime");
1548 fprintf(stderr, "Internal timer error: aborting\n");
1549 exit(1);
1550 }
1551}
1552
ths70744b32007-08-26 17:31:30 +00001553#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001554
thsc8994012007-08-19 21:56:03 +00001555static int unix_start_timer(struct qemu_alarm_timer *t)
1556{
1557 struct sigaction act;
1558 struct itimerval itv;
1559 int err;
1560
1561 /* timer signal */
1562 sigfillset(&act.sa_mask);
1563 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001564 act.sa_handler = host_alarm_handler;
1565
1566 sigaction(SIGALRM, &act, NULL);
1567
1568 itv.it_interval.tv_sec = 0;
1569 /* for i386 kernel 2.6 to get 1 ms */
1570 itv.it_interval.tv_usec = 999;
1571 itv.it_value.tv_sec = 0;
1572 itv.it_value.tv_usec = 10 * 1000;
1573
1574 err = setitimer(ITIMER_REAL, &itv, NULL);
1575 if (err)
1576 return -1;
1577
1578 return 0;
1579}
1580
1581static void unix_stop_timer(struct qemu_alarm_timer *t)
1582{
1583 struct itimerval itv;
1584
1585 memset(&itv, 0, sizeof(itv));
1586 setitimer(ITIMER_REAL, &itv, NULL);
1587}
1588
bellard829309c2004-05-20 13:20:12 +00001589#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001590
thsc8994012007-08-19 21:56:03 +00001591#ifdef _WIN32
1592
1593static int win32_start_timer(struct qemu_alarm_timer *t)
1594{
1595 TIMECAPS tc;
1596 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001597 UINT flags;
thsc8994012007-08-19 21:56:03 +00001598
1599 data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1600 if (!data->host_alarm) {
1601 perror("Failed CreateEvent");
thsc396a7f2007-08-20 15:42:22 +00001602 return -1;
thsc8994012007-08-19 21:56:03 +00001603 }
1604
1605 memset(&tc, 0, sizeof(tc));
1606 timeGetDevCaps(&tc, sizeof(tc));
1607
1608 if (data->period < tc.wPeriodMin)
1609 data->period = tc.wPeriodMin;
1610
1611 timeBeginPeriod(data->period);
1612
thsefe75412007-08-24 01:36:32 +00001613 flags = TIME_CALLBACK_FUNCTION;
1614 if (alarm_has_dynticks(t))
1615 flags |= TIME_ONESHOT;
1616 else
1617 flags |= TIME_PERIODIC;
1618
thsc8994012007-08-19 21:56:03 +00001619 data->timerId = timeSetEvent(1, // interval (ms)
1620 data->period, // resolution
1621 host_alarm_handler, // function
1622 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001623 flags);
thsc8994012007-08-19 21:56:03 +00001624
1625 if (!data->timerId) {
1626 perror("Failed to initialize win32 alarm timer");
1627
1628 timeEndPeriod(data->period);
1629 CloseHandle(data->host_alarm);
1630 return -1;
1631 }
1632
1633 qemu_add_wait_object(data->host_alarm, NULL, NULL);
1634
1635 return 0;
1636}
1637
1638static void win32_stop_timer(struct qemu_alarm_timer *t)
1639{
1640 struct qemu_alarm_win32 *data = t->priv;
1641
1642 timeKillEvent(data->timerId);
1643 timeEndPeriod(data->period);
1644
1645 CloseHandle(data->host_alarm);
1646}
1647
thsefe75412007-08-24 01:36:32 +00001648static void win32_rearm_timer(struct qemu_alarm_timer *t)
1649{
1650 struct qemu_alarm_win32 *data = t->priv;
1651 uint64_t nearest_delta_us;
1652
1653 if (!active_timers[QEMU_TIMER_REALTIME] &&
1654 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001655 return;
thsefe75412007-08-24 01:36:32 +00001656
pbrook2e70f6e2008-06-29 01:03:05 +00001657 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001658 nearest_delta_us /= 1000;
1659
1660 timeKillEvent(data->timerId);
1661
1662 data->timerId = timeSetEvent(1,
1663 data->period,
1664 host_alarm_handler,
1665 (DWORD)t,
1666 TIME_ONESHOT | TIME_PERIODIC);
1667
1668 if (!data->timerId) {
1669 perror("Failed to re-arm win32 alarm timer");
1670
1671 timeEndPeriod(data->period);
1672 CloseHandle(data->host_alarm);
1673 exit(1);
1674 }
1675}
1676
thsc8994012007-08-19 21:56:03 +00001677#endif /* _WIN32 */
1678
bellard1dce7c32006-07-13 23:20:22 +00001679static void init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001680{
thsc8994012007-08-19 21:56:03 +00001681 struct qemu_alarm_timer *t;
1682 int i, err = -1;
bellard06d9f2f2006-05-01 13:23:04 +00001683
thsc8994012007-08-19 21:56:03 +00001684 for (i = 0; alarm_timers[i].name; i++) {
1685 t = &alarm_timers[i];
1686
thsc8994012007-08-19 21:56:03 +00001687 err = t->start(t);
1688 if (!err)
1689 break;
bellard67b915a2004-03-31 23:37:16 +00001690 }
bellardfd872592004-05-12 19:11:15 +00001691
thsc8994012007-08-19 21:56:03 +00001692 if (err) {
1693 fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1694 fprintf(stderr, "Terminating\n");
1695 exit(1);
bellard67b915a2004-03-31 23:37:16 +00001696 }
thsc8994012007-08-19 21:56:03 +00001697
1698 alarm_timer = t;
bellard8a7ddc32004-03-31 19:00:16 +00001699}
1700
pbrook9596ebb2007-11-18 01:44:38 +00001701static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001702{
thsc8994012007-08-19 21:56:03 +00001703 alarm_timer->stop(alarm_timer);
1704 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001705}
1706
bellardc4b1fcc2004-03-14 21:44:30 +00001707/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001708/* host time/date access */
1709void qemu_get_timedate(struct tm *tm, int offset)
1710{
1711 time_t ti;
1712 struct tm *ret;
1713
1714 time(&ti);
1715 ti += offset;
1716 if (rtc_date_offset == -1) {
1717 if (rtc_utc)
1718 ret = gmtime(&ti);
1719 else
1720 ret = localtime(&ti);
1721 } else {
1722 ti -= rtc_date_offset;
1723 ret = gmtime(&ti);
1724 }
1725
1726 memcpy(tm, ret, sizeof(struct tm));
1727}
1728
1729int qemu_timedate_diff(struct tm *tm)
1730{
1731 time_t seconds;
1732
1733 if (rtc_date_offset == -1)
1734 if (rtc_utc)
1735 seconds = mktimegm(tm);
1736 else
1737 seconds = mktime(tm);
1738 else
1739 seconds = mktimegm(tm) + rtc_date_offset;
1740
1741 return seconds - time(NULL);
1742}
1743
1744/***********************************************************/
bellard82c643f2004-07-14 17:28:13 +00001745/* character device */
bellardc45886d2004-01-05 00:02:06 +00001746
pbrooke5b0bc42007-01-27 23:46:43 +00001747static void qemu_chr_event(CharDriverState *s, int event)
1748{
1749 if (!s->chr_event)
1750 return;
1751 s->chr_event(s->handler_opaque, event);
1752}
1753
ths86e94de2007-01-05 22:01:59 +00001754static void qemu_chr_reset_bh(void *opaque)
1755{
1756 CharDriverState *s = opaque;
pbrooke5b0bc42007-01-27 23:46:43 +00001757 qemu_chr_event(s, CHR_EVENT_RESET);
ths86e94de2007-01-05 22:01:59 +00001758 qemu_bh_delete(s->bh);
1759 s->bh = NULL;
1760}
1761
1762void qemu_chr_reset(CharDriverState *s)
1763{
1764 if (s->bh == NULL) {
1765 s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1766 qemu_bh_schedule(s->bh);
1767 }
1768}
1769
bellard82c643f2004-07-14 17:28:13 +00001770int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
bellard67b915a2004-03-31 23:37:16 +00001771{
bellard82c643f2004-07-14 17:28:13 +00001772 return s->chr_write(s, buf, len);
bellard67b915a2004-03-31 23:37:16 +00001773}
1774
bellarde57a8c02005-11-10 23:58:52 +00001775int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00001776{
bellarde57a8c02005-11-10 23:58:52 +00001777 if (!s->chr_ioctl)
1778 return -ENOTSUP;
1779 return s->chr_ioctl(s, cmd, arg);
bellardf8d179e2005-11-08 22:30:36 +00001780}
1781
pbrooke5b0bc42007-01-27 23:46:43 +00001782int qemu_chr_can_read(CharDriverState *s)
1783{
1784 if (!s->chr_can_read)
1785 return 0;
1786 return s->chr_can_read(s->handler_opaque);
1787}
1788
1789void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1790{
1791 s->chr_read(s->handler_opaque, buf, len);
1792}
1793
balrogbd9bdce2007-11-25 00:55:06 +00001794void qemu_chr_accept_input(CharDriverState *s)
1795{
1796 if (s->chr_accept_input)
1797 s->chr_accept_input(s);
1798}
pbrooke5b0bc42007-01-27 23:46:43 +00001799
bellard82c643f2004-07-14 17:28:13 +00001800void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
bellard0824d6f2003-06-24 13:42:40 +00001801{
bellard82c643f2004-07-14 17:28:13 +00001802 char buf[4096];
1803 va_list ap;
1804 va_start(ap, fmt);
1805 vsnprintf(buf, sizeof(buf), fmt, ap);
thsffe8ab82007-12-16 03:16:05 +00001806 qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
bellard82c643f2004-07-14 17:28:13 +00001807 va_end(ap);
1808}
1809
bellard5905b2e2004-08-01 21:53:26 +00001810void qemu_chr_send_event(CharDriverState *s, int event)
1811{
1812 if (s->chr_send_event)
1813 s->chr_send_event(s, event);
1814}
1815
ths5fafdf22007-09-16 21:08:06 +00001816void qemu_chr_add_handlers(CharDriverState *s,
1817 IOCanRWHandler *fd_can_read,
pbrooke5b0bc42007-01-27 23:46:43 +00001818 IOReadHandler *fd_read,
1819 IOEventHandler *fd_event,
1820 void *opaque)
bellard82c643f2004-07-14 17:28:13 +00001821{
pbrooke5b0bc42007-01-27 23:46:43 +00001822 s->chr_can_read = fd_can_read;
1823 s->chr_read = fd_read;
1824 s->chr_event = fd_event;
1825 s->handler_opaque = opaque;
1826 if (s->chr_update_read_handler)
1827 s->chr_update_read_handler(s);
bellard82c643f2004-07-14 17:28:13 +00001828}
ths3b46e622007-09-17 08:09:54 +00001829
bellard82c643f2004-07-14 17:28:13 +00001830static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1831{
1832 return len;
1833}
1834
ths52f61fd2006-12-22 21:20:52 +00001835static CharDriverState *qemu_chr_open_null(void)
bellard82c643f2004-07-14 17:28:13 +00001836{
1837 CharDriverState *chr;
1838
1839 chr = qemu_mallocz(sizeof(CharDriverState));
1840 if (!chr)
1841 return NULL;
1842 chr->chr_write = null_chr_write;
bellard82c643f2004-07-14 17:28:13 +00001843 return chr;
1844}
1845
ths20d8a3e2007-02-18 17:04:49 +00001846/* MUX driver for serial I/O splitting */
1847static int term_timestamps;
1848static int64_t term_timestamps_start;
ths9c1de612007-02-21 17:25:30 +00001849#define MAX_MUX 4
balrogbd9bdce2007-11-25 00:55:06 +00001850#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
1851#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
ths20d8a3e2007-02-18 17:04:49 +00001852typedef struct {
1853 IOCanRWHandler *chr_can_read[MAX_MUX];
1854 IOReadHandler *chr_read[MAX_MUX];
1855 IOEventHandler *chr_event[MAX_MUX];
1856 void *ext_opaque[MAX_MUX];
1857 CharDriverState *drv;
balrogbd9bdce2007-11-25 00:55:06 +00001858 unsigned char buffer[MUX_BUFFER_SIZE];
1859 int prod;
1860 int cons;
ths20d8a3e2007-02-18 17:04:49 +00001861 int mux_cnt;
1862 int term_got_escape;
1863 int max_size;
1864} MuxDriver;
1865
1866
1867static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1868{
1869 MuxDriver *d = chr->opaque;
1870 int ret;
1871 if (!term_timestamps) {
1872 ret = d->drv->chr_write(d->drv, buf, len);
1873 } else {
1874 int i;
1875
1876 ret = 0;
1877 for(i = 0; i < len; i++) {
1878 ret += d->drv->chr_write(d->drv, buf+i, 1);
1879 if (buf[i] == '\n') {
1880 char buf1[64];
1881 int64_t ti;
1882 int secs;
1883
1884 ti = get_clock();
1885 if (term_timestamps_start == -1)
1886 term_timestamps_start = ti;
1887 ti -= term_timestamps_start;
1888 secs = ti / 1000000000;
1889 snprintf(buf1, sizeof(buf1),
1890 "[%02d:%02d:%02d.%03d] ",
1891 secs / 3600,
1892 (secs / 60) % 60,
1893 secs % 60,
1894 (int)((ti / 1000000) % 1000));
thsffe8ab82007-12-16 03:16:05 +00001895 d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
ths20d8a3e2007-02-18 17:04:49 +00001896 }
1897 }
1898 }
1899 return ret;
1900}
1901
blueswir17ccfb2e2008-09-14 06:45:34 +00001902static const char * const mux_help[] = {
ths20d8a3e2007-02-18 17:04:49 +00001903 "% h print this help\n\r",
1904 "% x exit emulator\n\r",
1905 "% s save disk data back to file (if -snapshot)\n\r",
1906 "% t toggle console timestamps\n\r"
1907 "% b send break (magic sysrq)\n\r",
1908 "% c switch between console and monitor\n\r",
1909 "% % sends %\n\r",
1910 NULL
1911};
1912
1913static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1914static void mux_print_help(CharDriverState *chr)
1915{
1916 int i, j;
1917 char ebuf[15] = "Escape-Char";
1918 char cbuf[50] = "\n\r";
1919
1920 if (term_escape_char > 0 && term_escape_char < 26) {
blueswir1363a37d2008-08-21 17:58:08 +00001921 snprintf(cbuf, sizeof(cbuf), "\n\r");
1922 snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
ths20d8a3e2007-02-18 17:04:49 +00001923 } else {
blueswir1363a37d2008-08-21 17:58:08 +00001924 snprintf(cbuf, sizeof(cbuf),
1925 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
1926 term_escape_char);
ths20d8a3e2007-02-18 17:04:49 +00001927 }
thsffe8ab82007-12-16 03:16:05 +00001928 chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
ths20d8a3e2007-02-18 17:04:49 +00001929 for (i = 0; mux_help[i] != NULL; i++) {
1930 for (j=0; mux_help[i][j] != '\0'; j++) {
1931 if (mux_help[i][j] == '%')
thsffe8ab82007-12-16 03:16:05 +00001932 chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
ths20d8a3e2007-02-18 17:04:49 +00001933 else
thsffe8ab82007-12-16 03:16:05 +00001934 chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
ths20d8a3e2007-02-18 17:04:49 +00001935 }
1936 }
1937}
1938
1939static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1940{
1941 if (d->term_got_escape) {
1942 d->term_got_escape = 0;
1943 if (ch == term_escape_char)
1944 goto send_char;
1945 switch(ch) {
1946 case '?':
1947 case 'h':
1948 mux_print_help(chr);
1949 break;
1950 case 'x':
1951 {
blueswir17ccfb2e2008-09-14 06:45:34 +00001952 const char *term = "QEMU: Terminated\n\r";
thsffe8ab82007-12-16 03:16:05 +00001953 chr->chr_write(chr,(uint8_t *)term,strlen(term));
ths20d8a3e2007-02-18 17:04:49 +00001954 exit(0);
1955 break;
1956 }
1957 case 's':
1958 {
1959 int i;
thse4bcb142007-12-02 04:51:10 +00001960 for (i = 0; i < nb_drives; i++) {
1961 bdrv_commit(drives_table[i].bdrv);
ths20d8a3e2007-02-18 17:04:49 +00001962 }
1963 }
1964 break;
1965 case 'b':
balrog36ddb832007-05-18 17:46:59 +00001966 qemu_chr_event(chr, CHR_EVENT_BREAK);
ths20d8a3e2007-02-18 17:04:49 +00001967 break;
1968 case 'c':
1969 /* Switch to the next registered device */
1970 chr->focus++;
1971 if (chr->focus >= d->mux_cnt)
1972 chr->focus = 0;
1973 break;
1974 case 't':
1975 term_timestamps = !term_timestamps;
1976 term_timestamps_start = -1;
1977 break;
1978 }
1979 } else if (ch == term_escape_char) {
1980 d->term_got_escape = 1;
1981 } else {
1982 send_char:
1983 return 1;
1984 }
1985 return 0;
1986}
1987
balrogbd9bdce2007-11-25 00:55:06 +00001988static void mux_chr_accept_input(CharDriverState *chr)
1989{
1990 int m = chr->focus;
1991 MuxDriver *d = chr->opaque;
1992
1993 while (d->prod != d->cons &&
1994 d->chr_can_read[m] &&
1995 d->chr_can_read[m](d->ext_opaque[m])) {
1996 d->chr_read[m](d->ext_opaque[m],
1997 &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
1998 }
1999}
2000
ths20d8a3e2007-02-18 17:04:49 +00002001static int mux_chr_can_read(void *opaque)
2002{
2003 CharDriverState *chr = opaque;
2004 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00002005
2006 if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
2007 return 1;
ths20d8a3e2007-02-18 17:04:49 +00002008 if (d->chr_can_read[chr->focus])
balrogbd9bdce2007-11-25 00:55:06 +00002009 return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
ths20d8a3e2007-02-18 17:04:49 +00002010 return 0;
2011}
2012
2013static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
2014{
2015 CharDriverState *chr = opaque;
2016 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00002017 int m = chr->focus;
ths20d8a3e2007-02-18 17:04:49 +00002018 int i;
balrogbd9bdce2007-11-25 00:55:06 +00002019
2020 mux_chr_accept_input (opaque);
2021
ths20d8a3e2007-02-18 17:04:49 +00002022 for(i = 0; i < size; i++)
balrogbd9bdce2007-11-25 00:55:06 +00002023 if (mux_proc_byte(chr, d, buf[i])) {
2024 if (d->prod == d->cons &&
2025 d->chr_can_read[m] &&
2026 d->chr_can_read[m](d->ext_opaque[m]))
2027 d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
2028 else
2029 d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
2030 }
ths20d8a3e2007-02-18 17:04:49 +00002031}
2032
2033static void mux_chr_event(void *opaque, int event)
2034{
2035 CharDriverState *chr = opaque;
2036 MuxDriver *d = chr->opaque;
2037 int i;
2038
2039 /* Send the event to all registered listeners */
2040 for (i = 0; i < d->mux_cnt; i++)
2041 if (d->chr_event[i])
2042 d->chr_event[i](d->ext_opaque[i], event);
2043}
2044
2045static void mux_chr_update_read_handler(CharDriverState *chr)
2046{
2047 MuxDriver *d = chr->opaque;
2048
2049 if (d->mux_cnt >= MAX_MUX) {
2050 fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
2051 return;
2052 }
2053 d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
2054 d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
2055 d->chr_read[d->mux_cnt] = chr->chr_read;
2056 d->chr_event[d->mux_cnt] = chr->chr_event;
2057 /* Fix up the real driver with mux routines */
2058 if (d->mux_cnt == 0) {
2059 qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
2060 mux_chr_event, chr);
2061 }
2062 chr->focus = d->mux_cnt;
2063 d->mux_cnt++;
2064}
2065
pbrook9596ebb2007-11-18 01:44:38 +00002066static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
ths20d8a3e2007-02-18 17:04:49 +00002067{
2068 CharDriverState *chr;
2069 MuxDriver *d;
2070
2071 chr = qemu_mallocz(sizeof(CharDriverState));
2072 if (!chr)
2073 return NULL;
2074 d = qemu_mallocz(sizeof(MuxDriver));
2075 if (!d) {
2076 free(chr);
2077 return NULL;
2078 }
2079
2080 chr->opaque = d;
2081 d->drv = drv;
2082 chr->focus = -1;
2083 chr->chr_write = mux_chr_write;
2084 chr->chr_update_read_handler = mux_chr_update_read_handler;
balrogbd9bdce2007-11-25 00:55:06 +00002085 chr->chr_accept_input = mux_chr_accept_input;
ths20d8a3e2007-02-18 17:04:49 +00002086 return chr;
2087}
2088
2089
bellardfd1dff42006-02-01 21:29:26 +00002090#ifdef _WIN32
bellard82c643f2004-07-14 17:28:13 +00002091
bellardfd1dff42006-02-01 21:29:26 +00002092static void socket_cleanup(void)
2093{
2094 WSACleanup();
2095}
bellard82c643f2004-07-14 17:28:13 +00002096
bellardfd1dff42006-02-01 21:29:26 +00002097static int socket_init(void)
2098{
2099 WSADATA Data;
2100 int ret, err;
2101
2102 ret = WSAStartup(MAKEWORD(2,2), &Data);
2103 if (ret != 0) {
2104 err = WSAGetLastError();
2105 fprintf(stderr, "WSAStartup: %d\n", err);
2106 return -1;
2107 }
2108 atexit(socket_cleanup);
2109 return 0;
2110}
2111
2112static int send_all(int fd, const uint8_t *buf, int len1)
2113{
2114 int ret, len;
ths3b46e622007-09-17 08:09:54 +00002115
bellardfd1dff42006-02-01 21:29:26 +00002116 len = len1;
2117 while (len > 0) {
2118 ret = send(fd, buf, len, 0);
2119 if (ret < 0) {
2120 int errno;
2121 errno = WSAGetLastError();
2122 if (errno != WSAEWOULDBLOCK) {
2123 return -1;
2124 }
2125 } else if (ret == 0) {
2126 break;
2127 } else {
2128 buf += ret;
2129 len -= ret;
2130 }
2131 }
2132 return len1 - len;
2133}
2134
bellardfd1dff42006-02-01 21:29:26 +00002135#else
2136
bellard1d969052004-09-18 19:34:39 +00002137static int unix_write(int fd, const uint8_t *buf, int len1)
2138{
2139 int ret, len;
2140
2141 len = len1;
2142 while (len > 0) {
2143 ret = write(fd, buf, len);
2144 if (ret < 0) {
2145 if (errno != EINTR && errno != EAGAIN)
2146 return -1;
2147 } else if (ret == 0) {
2148 break;
2149 } else {
2150 buf += ret;
2151 len -= ret;
2152 }
2153 }
2154 return len1 - len;
2155}
2156
bellardfd1dff42006-02-01 21:29:26 +00002157static inline int send_all(int fd, const uint8_t *buf, int len1)
2158{
2159 return unix_write(fd, buf, len1);
2160}
bellardfd1dff42006-02-01 21:29:26 +00002161#endif /* !_WIN32 */
2162
2163#ifndef _WIN32
2164
2165typedef struct {
2166 int fd_in, fd_out;
bellardfd1dff42006-02-01 21:29:26 +00002167 int max_size;
2168} FDCharDriver;
2169
ths20d8a3e2007-02-18 17:04:49 +00002170#define STDIO_MAX_CLIENTS 1
2171static int stdio_nb_clients = 0;
bellardfd1dff42006-02-01 21:29:26 +00002172
bellard82c643f2004-07-14 17:28:13 +00002173static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2174{
2175 FDCharDriver *s = chr->opaque;
bellard1d969052004-09-18 19:34:39 +00002176 return unix_write(s->fd_out, buf, len);
bellard82c643f2004-07-14 17:28:13 +00002177}
2178
bellard7c9d8e02005-11-15 22:16:05 +00002179static int fd_chr_read_poll(void *opaque)
2180{
2181 CharDriverState *chr = opaque;
2182 FDCharDriver *s = chr->opaque;
2183
pbrooke5b0bc42007-01-27 23:46:43 +00002184 s->max_size = qemu_chr_can_read(chr);
bellard7c9d8e02005-11-15 22:16:05 +00002185 return s->max_size;
2186}
2187
2188static void fd_chr_read(void *opaque)
2189{
2190 CharDriverState *chr = opaque;
2191 FDCharDriver *s = chr->opaque;
2192 int size, len;
2193 uint8_t buf[1024];
ths3b46e622007-09-17 08:09:54 +00002194
bellard7c9d8e02005-11-15 22:16:05 +00002195 len = sizeof(buf);
2196 if (len > s->max_size)
2197 len = s->max_size;
2198 if (len == 0)
2199 return;
2200 size = read(s->fd_in, buf, len);
pbrook188157f2006-11-01 01:44:16 +00002201 if (size == 0) {
2202 /* FD has been closed. Remove it from the active list. */
2203 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2204 return;
2205 }
bellard7c9d8e02005-11-15 22:16:05 +00002206 if (size > 0) {
pbrooke5b0bc42007-01-27 23:46:43 +00002207 qemu_chr_read(chr, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00002208 }
2209}
2210
pbrooke5b0bc42007-01-27 23:46:43 +00002211static void fd_chr_update_read_handler(CharDriverState *chr)
bellard82c643f2004-07-14 17:28:13 +00002212{
2213 FDCharDriver *s = chr->opaque;
2214
bellardf8d179e2005-11-08 22:30:36 +00002215 if (s->fd_in >= 0) {
2216 if (nographic && s->fd_in == 0) {
bellardf8d179e2005-11-08 22:30:36 +00002217 } else {
ths5fafdf22007-09-16 21:08:06 +00002218 qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
bellard7c9d8e02005-11-15 22:16:05 +00002219 fd_chr_read, NULL, chr);
bellardf8d179e2005-11-08 22:30:36 +00002220 }
bellard0824d6f2003-06-24 13:42:40 +00002221 }
2222}
2223
balroga11d0702008-01-19 13:00:43 +00002224static void fd_chr_close(struct CharDriverState *chr)
2225{
2226 FDCharDriver *s = chr->opaque;
2227
2228 if (s->fd_in >= 0) {
2229 if (nographic && s->fd_in == 0) {
2230 } else {
2231 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2232 }
2233 }
2234
2235 qemu_free(s);
2236}
2237
bellard82c643f2004-07-14 17:28:13 +00002238/* open a character device to a unix fd */
ths52f61fd2006-12-22 21:20:52 +00002239static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
bellard82c643f2004-07-14 17:28:13 +00002240{
2241 CharDriverState *chr;
2242 FDCharDriver *s;
2243
2244 chr = qemu_mallocz(sizeof(CharDriverState));
2245 if (!chr)
2246 return NULL;
2247 s = qemu_mallocz(sizeof(FDCharDriver));
2248 if (!s) {
2249 free(chr);
2250 return NULL;
2251 }
2252 s->fd_in = fd_in;
2253 s->fd_out = fd_out;
2254 chr->opaque = s;
2255 chr->chr_write = fd_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00002256 chr->chr_update_read_handler = fd_chr_update_read_handler;
balroga11d0702008-01-19 13:00:43 +00002257 chr->chr_close = fd_chr_close;
ths86e94de2007-01-05 22:01:59 +00002258
2259 qemu_chr_reset(chr);
2260
bellard82c643f2004-07-14 17:28:13 +00002261 return chr;
2262}
2263
ths52f61fd2006-12-22 21:20:52 +00002264static CharDriverState *qemu_chr_open_file_out(const char *file_out)
bellardf8d179e2005-11-08 22:30:36 +00002265{
2266 int fd_out;
2267
balrogaeb30be2007-07-02 15:03:13 +00002268 TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
bellardf8d179e2005-11-08 22:30:36 +00002269 if (fd_out < 0)
2270 return NULL;
2271 return qemu_chr_open_fd(-1, fd_out);
2272}
2273
ths52f61fd2006-12-22 21:20:52 +00002274static CharDriverState *qemu_chr_open_pipe(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002275{
thsc26c1c42006-12-22 19:25:31 +00002276 int fd_in, fd_out;
2277 char filename_in[256], filename_out[256];
bellardf8d179e2005-11-08 22:30:36 +00002278
thsc26c1c42006-12-22 19:25:31 +00002279 snprintf(filename_in, 256, "%s.in", filename);
2280 snprintf(filename_out, 256, "%s.out", filename);
balrogaeb30be2007-07-02 15:03:13 +00002281 TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2282 TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002283 if (fd_in < 0 || fd_out < 0) {
2284 if (fd_in >= 0)
2285 close(fd_in);
2286 if (fd_out >= 0)
2287 close(fd_out);
balrogaeb30be2007-07-02 15:03:13 +00002288 TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002289 if (fd_in < 0)
2290 return NULL;
2291 }
2292 return qemu_chr_open_fd(fd_in, fd_out);
bellardf8d179e2005-11-08 22:30:36 +00002293}
2294
2295
bellard82c643f2004-07-14 17:28:13 +00002296/* for STDIO, we handle the case where several clients use it
2297 (nographic mode) */
2298
bellardaa0bc6b2005-09-03 15:28:58 +00002299#define TERM_FIFO_MAX_SIZE 1
2300
bellardaa0bc6b2005-09-03 15:28:58 +00002301static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
bellard1dce7c32006-07-13 23:20:22 +00002302static int term_fifo_size;
bellard82c643f2004-07-14 17:28:13 +00002303
bellard7c9d8e02005-11-15 22:16:05 +00002304static int stdio_read_poll(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002305{
ths20d8a3e2007-02-18 17:04:49 +00002306 CharDriverState *chr = opaque;
bellardaa0bc6b2005-09-03 15:28:58 +00002307
ths20d8a3e2007-02-18 17:04:49 +00002308 /* try to flush the queue if needed */
2309 if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2310 qemu_chr_read(chr, term_fifo, 1);
2311 term_fifo_size = 0;
bellardaa0bc6b2005-09-03 15:28:58 +00002312 }
ths20d8a3e2007-02-18 17:04:49 +00002313 /* see if we can absorb more chars */
2314 if (term_fifo_size == 0)
2315 return 1;
2316 else
2317 return 0;
bellard82c643f2004-07-14 17:28:13 +00002318}
2319
bellard7c9d8e02005-11-15 22:16:05 +00002320static void stdio_read(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002321{
bellard7c9d8e02005-11-15 22:16:05 +00002322 int size;
2323 uint8_t buf[1];
ths20d8a3e2007-02-18 17:04:49 +00002324 CharDriverState *chr = opaque;
2325
bellard7c9d8e02005-11-15 22:16:05 +00002326 size = read(0, buf, 1);
pbrook519945d2006-09-10 14:39:54 +00002327 if (size == 0) {
2328 /* stdin has been closed. Remove it from the active list. */
2329 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2330 return;
2331 }
ths20d8a3e2007-02-18 17:04:49 +00002332 if (size > 0) {
2333 if (qemu_chr_can_read(chr) > 0) {
2334 qemu_chr_read(chr, buf, 1);
2335 } else if (term_fifo_size == 0) {
2336 term_fifo[term_fifo_size++] = buf[0];
bellard1dce7c32006-07-13 23:20:22 +00002337 }
bellard1dce7c32006-07-13 23:20:22 +00002338 }
2339}
2340
bellard8d11df92004-08-24 21:13:40 +00002341/* init terminal so that we can grab keys */
2342static struct termios oldtty;
2343static int old_fd0_flags;
balroga11d0702008-01-19 13:00:43 +00002344static int term_atexit_done;
bellard8d11df92004-08-24 21:13:40 +00002345
2346static void term_exit(void)
2347{
2348 tcsetattr (0, TCSANOW, &oldtty);
2349 fcntl(0, F_SETFL, old_fd0_flags);
2350}
2351
2352static void term_init(void)
2353{
2354 struct termios tty;
2355
2356 tcgetattr (0, &tty);
2357 oldtty = tty;
2358 old_fd0_flags = fcntl(0, F_GETFL);
2359
2360 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2361 |INLCR|IGNCR|ICRNL|IXON);
2362 tty.c_oflag |= OPOST;
2363 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2364 /* if graphical mode, we allow Ctrl-C handling */
2365 if (nographic)
2366 tty.c_lflag &= ~ISIG;
2367 tty.c_cflag &= ~(CSIZE|PARENB);
2368 tty.c_cflag |= CS8;
2369 tty.c_cc[VMIN] = 1;
2370 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +00002371
bellard8d11df92004-08-24 21:13:40 +00002372 tcsetattr (0, TCSANOW, &tty);
2373
balroga11d0702008-01-19 13:00:43 +00002374 if (!term_atexit_done++)
2375 atexit(term_exit);
bellard8d11df92004-08-24 21:13:40 +00002376
2377 fcntl(0, F_SETFL, O_NONBLOCK);
2378}
2379
balroga11d0702008-01-19 13:00:43 +00002380static void qemu_chr_close_stdio(struct CharDriverState *chr)
2381{
2382 term_exit();
2383 stdio_nb_clients--;
2384 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2385 fd_chr_close(chr);
2386}
2387
ths52f61fd2006-12-22 21:20:52 +00002388static CharDriverState *qemu_chr_open_stdio(void)
bellard82c643f2004-07-14 17:28:13 +00002389{
2390 CharDriverState *chr;
2391
ths20d8a3e2007-02-18 17:04:49 +00002392 if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2393 return NULL;
2394 chr = qemu_chr_open_fd(0, 1);
balroga11d0702008-01-19 13:00:43 +00002395 chr->chr_close = qemu_chr_close_stdio;
ths20d8a3e2007-02-18 17:04:49 +00002396 qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2397 stdio_nb_clients++;
2398 term_init();
2399
bellard82c643f2004-07-14 17:28:13 +00002400 return chr;
2401}
2402
aurel3264b7b732008-05-05 10:05:31 +00002403#ifdef __sun__
2404/* Once Solaris has openpty(), this is going to be removed. */
2405int openpty(int *amaster, int *aslave, char *name,
2406 struct termios *termp, struct winsize *winp)
2407{
2408 const char *slave;
2409 int mfd = -1, sfd = -1;
2410
2411 *amaster = *aslave = -1;
2412
2413 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
2414 if (mfd < 0)
2415 goto err;
2416
2417 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
2418 goto err;
2419
2420 if ((slave = ptsname(mfd)) == NULL)
2421 goto err;
2422
2423 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
2424 goto err;
2425
2426 if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
2427 (termp != NULL && tcgetattr(sfd, termp) < 0))
2428 goto err;
2429
2430 if (amaster)
2431 *amaster = mfd;
2432 if (aslave)
2433 *aslave = sfd;
2434 if (winp)
2435 ioctl(sfd, TIOCSWINSZ, winp);
2436
2437 return 0;
2438
2439err:
2440 if (sfd != -1)
2441 close(sfd);
2442 close(mfd);
2443 return -1;
2444}
2445
2446void cfmakeraw (struct termios *termios_p)
2447{
2448 termios_p->c_iflag &=
2449 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2450 termios_p->c_oflag &= ~OPOST;
2451 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2452 termios_p->c_cflag &= ~(CSIZE|PARENB);
2453 termios_p->c_cflag |= CS8;
2454
2455 termios_p->c_cc[VMIN] = 0;
2456 termios_p->c_cc[VTIME] = 0;
2457}
2458#endif
2459
blueswir19892fbf2008-08-24 10:34:20 +00002460#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
2461 || defined(__NetBSD__) || defined(__OpenBSD__)
aliguori279e6942008-07-28 18:55:32 +00002462
2463typedef struct {
2464 int fd;
2465 int connected;
2466 int polling;
2467 int read_bytes;
2468 QEMUTimer *timer;
2469} PtyCharDriver;
2470
2471static void pty_chr_update_read_handler(CharDriverState *chr);
2472static void pty_chr_state(CharDriverState *chr, int connected);
2473
2474static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2475{
2476 PtyCharDriver *s = chr->opaque;
2477
2478 if (!s->connected) {
2479 /* guest sends data, check for (re-)connect */
2480 pty_chr_update_read_handler(chr);
2481 return 0;
2482 }
2483 return unix_write(s->fd, buf, len);
2484}
2485
2486static int pty_chr_read_poll(void *opaque)
2487{
2488 CharDriverState *chr = opaque;
2489 PtyCharDriver *s = chr->opaque;
2490
2491 s->read_bytes = qemu_chr_can_read(chr);
2492 return s->read_bytes;
2493}
2494
2495static void pty_chr_read(void *opaque)
2496{
2497 CharDriverState *chr = opaque;
2498 PtyCharDriver *s = chr->opaque;
2499 int size, len;
2500 uint8_t buf[1024];
2501
2502 len = sizeof(buf);
2503 if (len > s->read_bytes)
2504 len = s->read_bytes;
2505 if (len == 0)
2506 return;
2507 size = read(s->fd, buf, len);
2508 if ((size == -1 && errno == EIO) ||
2509 (size == 0)) {
2510 pty_chr_state(chr, 0);
2511 return;
2512 }
2513 if (size > 0) {
2514 pty_chr_state(chr, 1);
2515 qemu_chr_read(chr, buf, size);
2516 }
2517}
2518
2519static void pty_chr_update_read_handler(CharDriverState *chr)
2520{
2521 PtyCharDriver *s = chr->opaque;
2522
2523 qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
2524 pty_chr_read, NULL, chr);
2525 s->polling = 1;
2526 /*
2527 * Short timeout here: just need wait long enougth that qemu makes
2528 * it through the poll loop once. When reconnected we want a
2529 * short timeout so we notice it almost instantly. Otherwise
2530 * read() gives us -EIO instantly, making pty_chr_state() reset the
2531 * timeout to the normal (much longer) poll interval before the
2532 * timer triggers.
2533 */
2534 qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
2535}
2536
2537static void pty_chr_state(CharDriverState *chr, int connected)
2538{
2539 PtyCharDriver *s = chr->opaque;
2540
2541 if (!connected) {
2542 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
2543 s->connected = 0;
2544 s->polling = 0;
2545 /* (re-)connect poll interval for idle guests: once per second.
2546 * We check more frequently in case the guests sends data to
2547 * the virtual device linked to our pty. */
2548 qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
2549 } else {
2550 if (!s->connected)
2551 qemu_chr_reset(chr);
2552 s->connected = 1;
2553 }
2554}
2555
blueswir18fcd3692008-08-17 20:26:25 +00002556static void pty_chr_timer(void *opaque)
aliguori279e6942008-07-28 18:55:32 +00002557{
2558 struct CharDriverState *chr = opaque;
2559 PtyCharDriver *s = chr->opaque;
2560
2561 if (s->connected)
2562 return;
2563 if (s->polling) {
2564 /* If we arrive here without polling being cleared due
2565 * read returning -EIO, then we are (re-)connected */
2566 pty_chr_state(chr, 1);
2567 return;
2568 }
2569
2570 /* Next poll ... */
2571 pty_chr_update_read_handler(chr);
2572}
2573
2574static void pty_chr_close(struct CharDriverState *chr)
2575{
2576 PtyCharDriver *s = chr->opaque;
2577
2578 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
2579 close(s->fd);
2580 qemu_free(s);
2581}
2582
ths52f61fd2006-12-22 21:20:52 +00002583static CharDriverState *qemu_chr_open_pty(void)
bellard82c643f2004-07-14 17:28:13 +00002584{
aliguori279e6942008-07-28 18:55:32 +00002585 CharDriverState *chr;
2586 PtyCharDriver *s;
bellard91fc2112005-12-18 19:09:37 +00002587 struct termios tty;
aliguori279e6942008-07-28 18:55:32 +00002588 int slave_fd;
blueswir19892fbf2008-08-24 10:34:20 +00002589#if defined(__OpenBSD__)
2590 char pty_name[PATH_MAX];
2591#define q_ptsname(x) pty_name
2592#else
2593 char *pty_name = NULL;
2594#define q_ptsname(x) ptsname(x)
2595#endif
ths3b46e622007-09-17 08:09:54 +00002596
aliguori279e6942008-07-28 18:55:32 +00002597 chr = qemu_mallocz(sizeof(CharDriverState));
2598 if (!chr)
2599 return NULL;
2600 s = qemu_mallocz(sizeof(PtyCharDriver));
2601 if (!s) {
2602 qemu_free(chr);
2603 return NULL;
2604 }
2605
blueswir19892fbf2008-08-24 10:34:20 +00002606 if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
bellard82c643f2004-07-14 17:28:13 +00002607 return NULL;
2608 }
ths3b46e622007-09-17 08:09:54 +00002609
aurel3264b7b732008-05-05 10:05:31 +00002610 /* Set raw attributes on the pty. */
2611 cfmakeraw(&tty);
2612 tcsetattr(slave_fd, TCSAFLUSH, &tty);
aliguori279e6942008-07-28 18:55:32 +00002613 close(slave_fd);
bellard91fc2112005-12-18 19:09:37 +00002614
blueswir19892fbf2008-08-24 10:34:20 +00002615 fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
aliguori279e6942008-07-28 18:55:32 +00002616
2617 chr->opaque = s;
2618 chr->chr_write = pty_chr_write;
2619 chr->chr_update_read_handler = pty_chr_update_read_handler;
2620 chr->chr_close = pty_chr_close;
2621
2622 s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
2623
2624 return chr;
bellard82c643f2004-07-14 17:28:13 +00002625}
bellardf8d179e2005-11-08 22:30:36 +00002626
ths5fafdf22007-09-16 21:08:06 +00002627static void tty_serial_init(int fd, int speed,
bellardf8d179e2005-11-08 22:30:36 +00002628 int parity, int data_bits, int stop_bits)
2629{
2630 struct termios tty;
2631 speed_t spd;
2632
bellarde57a8c02005-11-10 23:58:52 +00002633#if 0
ths5fafdf22007-09-16 21:08:06 +00002634 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
bellarde57a8c02005-11-10 23:58:52 +00002635 speed, parity, data_bits, stop_bits);
2636#endif
2637 tcgetattr (fd, &tty);
bellardf8d179e2005-11-08 22:30:36 +00002638
balroga7954212008-01-14 03:41:02 +00002639#define MARGIN 1.1
2640 if (speed <= 50 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002641 spd = B50;
balroga7954212008-01-14 03:41:02 +00002642 else if (speed <= 75 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002643 spd = B75;
balroga7954212008-01-14 03:41:02 +00002644 else if (speed <= 300 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002645 spd = B300;
balroga7954212008-01-14 03:41:02 +00002646 else if (speed <= 600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002647 spd = B600;
balroga7954212008-01-14 03:41:02 +00002648 else if (speed <= 1200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002649 spd = B1200;
balroga7954212008-01-14 03:41:02 +00002650 else if (speed <= 2400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002651 spd = B2400;
balroga7954212008-01-14 03:41:02 +00002652 else if (speed <= 4800 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002653 spd = B4800;
balroga7954212008-01-14 03:41:02 +00002654 else if (speed <= 9600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002655 spd = B9600;
balroga7954212008-01-14 03:41:02 +00002656 else if (speed <= 19200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002657 spd = B19200;
balroga7954212008-01-14 03:41:02 +00002658 else if (speed <= 38400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002659 spd = B38400;
balroga7954212008-01-14 03:41:02 +00002660 else if (speed <= 57600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002661 spd = B57600;
balroga7954212008-01-14 03:41:02 +00002662 else if (speed <= 115200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002663 spd = B115200;
balroga7954212008-01-14 03:41:02 +00002664 else
2665 spd = B115200;
bellardf8d179e2005-11-08 22:30:36 +00002666
2667 cfsetispeed(&tty, spd);
2668 cfsetospeed(&tty, spd);
2669
2670 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2671 |INLCR|IGNCR|ICRNL|IXON);
2672 tty.c_oflag |= OPOST;
2673 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
bellard094eed62006-09-09 11:10:18 +00002674 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
bellardf8d179e2005-11-08 22:30:36 +00002675 switch(data_bits) {
2676 default:
2677 case 8:
2678 tty.c_cflag |= CS8;
2679 break;
2680 case 7:
2681 tty.c_cflag |= CS7;
2682 break;
2683 case 6:
2684 tty.c_cflag |= CS6;
2685 break;
2686 case 5:
2687 tty.c_cflag |= CS5;
2688 break;
2689 }
2690 switch(parity) {
2691 default:
2692 case 'N':
2693 break;
2694 case 'E':
2695 tty.c_cflag |= PARENB;
2696 break;
2697 case 'O':
2698 tty.c_cflag |= PARENB | PARODD;
2699 break;
2700 }
bellard094eed62006-09-09 11:10:18 +00002701 if (stop_bits == 2)
2702 tty.c_cflag |= CSTOPB;
ths3b46e622007-09-17 08:09:54 +00002703
bellardf8d179e2005-11-08 22:30:36 +00002704 tcsetattr (fd, TCSANOW, &tty);
2705}
2706
bellarde57a8c02005-11-10 23:58:52 +00002707static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00002708{
2709 FDCharDriver *s = chr->opaque;
ths3b46e622007-09-17 08:09:54 +00002710
bellarde57a8c02005-11-10 23:58:52 +00002711 switch(cmd) {
2712 case CHR_IOCTL_SERIAL_SET_PARAMS:
2713 {
2714 QEMUSerialSetParams *ssp = arg;
ths5fafdf22007-09-16 21:08:06 +00002715 tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
bellarde57a8c02005-11-10 23:58:52 +00002716 ssp->data_bits, ssp->stop_bits);
2717 }
2718 break;
2719 case CHR_IOCTL_SERIAL_SET_BREAK:
2720 {
2721 int enable = *(int *)arg;
2722 if (enable)
2723 tcsendbreak(s->fd_in, 1);
2724 }
2725 break;
aliguori81174da2008-08-11 14:17:04 +00002726 case CHR_IOCTL_SERIAL_GET_TIOCM:
2727 {
2728 int sarg = 0;
2729 int *targ = (int *)arg;
2730 ioctl(s->fd_in, TIOCMGET, &sarg);
2731 *targ = 0;
2732 if (sarg | TIOCM_CTS)
2733 *targ |= CHR_TIOCM_CTS;
2734 if (sarg | TIOCM_CAR)
2735 *targ |= CHR_TIOCM_CAR;
2736 if (sarg | TIOCM_DSR)
2737 *targ |= CHR_TIOCM_DSR;
2738 if (sarg | TIOCM_RI)
2739 *targ |= CHR_TIOCM_RI;
2740 if (sarg | TIOCM_DTR)
2741 *targ |= CHR_TIOCM_DTR;
2742 if (sarg | TIOCM_RTS)
2743 *targ |= CHR_TIOCM_RTS;
2744 }
2745 break;
2746 case CHR_IOCTL_SERIAL_SET_TIOCM:
2747 {
2748 int sarg = *(int *)arg;
2749 int targ = 0;
2750 if (sarg | CHR_TIOCM_DTR)
2751 targ |= TIOCM_DTR;
2752 if (sarg | CHR_TIOCM_RTS)
2753 targ |= TIOCM_RTS;
2754 ioctl(s->fd_in, TIOCMSET, &targ);
2755 }
2756 break;
bellarde57a8c02005-11-10 23:58:52 +00002757 default:
2758 return -ENOTSUP;
2759 }
2760 return 0;
bellardf8d179e2005-11-08 22:30:36 +00002761}
2762
ths52f61fd2006-12-22 21:20:52 +00002763static CharDriverState *qemu_chr_open_tty(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002764{
2765 CharDriverState *chr;
2766 int fd;
2767
balrogaeb30be2007-07-02 15:03:13 +00002768 TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
bellardf8d179e2005-11-08 22:30:36 +00002769 tty_serial_init(fd, 115200, 'N', 8, 1);
2770 chr = qemu_chr_open_fd(fd, fd);
balrogaeb30be2007-07-02 15:03:13 +00002771 if (!chr) {
2772 close(fd);
bellardf8d179e2005-11-08 22:30:36 +00002773 return NULL;
balrogaeb30be2007-07-02 15:03:13 +00002774 }
bellarde57a8c02005-11-10 23:58:52 +00002775 chr->chr_ioctl = tty_serial_ioctl;
ths86e94de2007-01-05 22:01:59 +00002776 qemu_chr_reset(chr);
bellarde57a8c02005-11-10 23:58:52 +00002777 return chr;
2778}
thsaec62502007-06-25 11:48:07 +00002779#else /* ! __linux__ && ! __sun__ */
2780static CharDriverState *qemu_chr_open_pty(void)
2781{
2782 return NULL;
2783}
2784#endif /* __linux__ || __sun__ */
bellarde57a8c02005-11-10 23:58:52 +00002785
thsaec62502007-06-25 11:48:07 +00002786#if defined(__linux__)
ths5867c882007-02-17 23:44:43 +00002787typedef struct {
2788 int fd;
2789 int mode;
2790} ParallelCharDriver;
2791
2792static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2793{
2794 if (s->mode != mode) {
2795 int m = mode;
2796 if (ioctl(s->fd, PPSETMODE, &m) < 0)
2797 return 0;
2798 s->mode = mode;
2799 }
2800 return 1;
2801}
2802
bellarde57a8c02005-11-10 23:58:52 +00002803static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2804{
ths5867c882007-02-17 23:44:43 +00002805 ParallelCharDriver *drv = chr->opaque;
2806 int fd = drv->fd;
bellarde57a8c02005-11-10 23:58:52 +00002807 uint8_t b;
2808
2809 switch(cmd) {
2810 case CHR_IOCTL_PP_READ_DATA:
2811 if (ioctl(fd, PPRDATA, &b) < 0)
2812 return -ENOTSUP;
2813 *(uint8_t *)arg = b;
2814 break;
2815 case CHR_IOCTL_PP_WRITE_DATA:
2816 b = *(uint8_t *)arg;
2817 if (ioctl(fd, PPWDATA, &b) < 0)
2818 return -ENOTSUP;
2819 break;
2820 case CHR_IOCTL_PP_READ_CONTROL:
2821 if (ioctl(fd, PPRCONTROL, &b) < 0)
2822 return -ENOTSUP;
ths5867c882007-02-17 23:44:43 +00002823 /* Linux gives only the lowest bits, and no way to know data
2824 direction! For better compatibility set the fixed upper
2825 bits. */
2826 *(uint8_t *)arg = b | 0xc0;
bellarde57a8c02005-11-10 23:58:52 +00002827 break;
2828 case CHR_IOCTL_PP_WRITE_CONTROL:
2829 b = *(uint8_t *)arg;
2830 if (ioctl(fd, PPWCONTROL, &b) < 0)
2831 return -ENOTSUP;
2832 break;
2833 case CHR_IOCTL_PP_READ_STATUS:
2834 if (ioctl(fd, PPRSTATUS, &b) < 0)
2835 return -ENOTSUP;
2836 *(uint8_t *)arg = b;
2837 break;
aurel32563e3c62008-08-22 08:57:09 +00002838 case CHR_IOCTL_PP_DATA_DIR:
2839 if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
2840 return -ENOTSUP;
2841 break;
ths5867c882007-02-17 23:44:43 +00002842 case CHR_IOCTL_PP_EPP_READ_ADDR:
2843 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2844 struct ParallelIOArg *parg = arg;
2845 int n = read(fd, parg->buffer, parg->count);
2846 if (n != parg->count) {
2847 return -EIO;
2848 }
2849 }
2850 break;
2851 case CHR_IOCTL_PP_EPP_READ:
2852 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2853 struct ParallelIOArg *parg = arg;
2854 int n = read(fd, parg->buffer, parg->count);
2855 if (n != parg->count) {
2856 return -EIO;
2857 }
2858 }
2859 break;
2860 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2861 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2862 struct ParallelIOArg *parg = arg;
2863 int n = write(fd, parg->buffer, parg->count);
2864 if (n != parg->count) {
2865 return -EIO;
2866 }
2867 }
2868 break;
2869 case CHR_IOCTL_PP_EPP_WRITE:
2870 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2871 struct ParallelIOArg *parg = arg;
2872 int n = write(fd, parg->buffer, parg->count);
2873 if (n != parg->count) {
2874 return -EIO;
2875 }
2876 }
2877 break;
bellarde57a8c02005-11-10 23:58:52 +00002878 default:
2879 return -ENOTSUP;
2880 }
2881 return 0;
2882}
2883
ths5867c882007-02-17 23:44:43 +00002884static void pp_close(CharDriverState *chr)
2885{
2886 ParallelCharDriver *drv = chr->opaque;
2887 int fd = drv->fd;
2888
2889 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2890 ioctl(fd, PPRELEASE);
2891 close(fd);
2892 qemu_free(drv);
2893}
2894
ths52f61fd2006-12-22 21:20:52 +00002895static CharDriverState *qemu_chr_open_pp(const char *filename)
bellarde57a8c02005-11-10 23:58:52 +00002896{
2897 CharDriverState *chr;
ths5867c882007-02-17 23:44:43 +00002898 ParallelCharDriver *drv;
bellarde57a8c02005-11-10 23:58:52 +00002899 int fd;
2900
balrogaeb30be2007-07-02 15:03:13 +00002901 TFR(fd = open(filename, O_RDWR));
bellarde57a8c02005-11-10 23:58:52 +00002902 if (fd < 0)
2903 return NULL;
2904
2905 if (ioctl(fd, PPCLAIM) < 0) {
2906 close(fd);
2907 return NULL;
2908 }
2909
ths5867c882007-02-17 23:44:43 +00002910 drv = qemu_mallocz(sizeof(ParallelCharDriver));
2911 if (!drv) {
bellarde57a8c02005-11-10 23:58:52 +00002912 close(fd);
2913 return NULL;
2914 }
ths5867c882007-02-17 23:44:43 +00002915 drv->fd = fd;
2916 drv->mode = IEEE1284_MODE_COMPAT;
2917
2918 chr = qemu_mallocz(sizeof(CharDriverState));
2919 if (!chr) {
2920 qemu_free(drv);
2921 close(fd);
2922 return NULL;
2923 }
bellarde57a8c02005-11-10 23:58:52 +00002924 chr->chr_write = null_chr_write;
bellarde57a8c02005-11-10 23:58:52 +00002925 chr->chr_ioctl = pp_ioctl;
ths5867c882007-02-17 23:44:43 +00002926 chr->chr_close = pp_close;
2927 chr->opaque = drv;
ths86e94de2007-01-05 22:01:59 +00002928
2929 qemu_chr_reset(chr);
2930
bellardf8d179e2005-11-08 22:30:36 +00002931 return chr;
2932}
thsaec62502007-06-25 11:48:07 +00002933#endif /* __linux__ */
bellardf8d179e2005-11-08 22:30:36 +00002934
thsaec62502007-06-25 11:48:07 +00002935#else /* _WIN32 */
bellard67b915a2004-03-31 23:37:16 +00002936
bellardf3311102006-04-12 20:21:17 +00002937typedef struct {
bellardf3311102006-04-12 20:21:17 +00002938 int max_size;
2939 HANDLE hcom, hrecv, hsend;
2940 OVERLAPPED orecv, osend;
2941 BOOL fpipe;
2942 DWORD len;
2943} WinCharState;
2944
2945#define NSENDBUF 2048
2946#define NRECVBUF 2048
2947#define MAXCONNECT 1
2948#define NTIMEOUT 5000
2949
2950static int win_chr_poll(void *opaque);
2951static int win_chr_pipe_poll(void *opaque);
2952
ths087f4ae2007-02-10 21:50:42 +00002953static void win_chr_close(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002954{
ths087f4ae2007-02-10 21:50:42 +00002955 WinCharState *s = chr->opaque;
2956
bellardf3311102006-04-12 20:21:17 +00002957 if (s->hsend) {
2958 CloseHandle(s->hsend);
2959 s->hsend = NULL;
2960 }
2961 if (s->hrecv) {
2962 CloseHandle(s->hrecv);
2963 s->hrecv = NULL;
2964 }
2965 if (s->hcom) {
2966 CloseHandle(s->hcom);
2967 s->hcom = NULL;
2968 }
2969 if (s->fpipe)
ths087f4ae2007-02-10 21:50:42 +00002970 qemu_del_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002971 else
ths087f4ae2007-02-10 21:50:42 +00002972 qemu_del_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002973}
2974
ths087f4ae2007-02-10 21:50:42 +00002975static int win_chr_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00002976{
2977 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002978 COMMCONFIG comcfg;
2979 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2980 COMSTAT comstat;
2981 DWORD size;
2982 DWORD err;
ths3b46e622007-09-17 08:09:54 +00002983
bellardf3311102006-04-12 20:21:17 +00002984 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2985 if (!s->hsend) {
2986 fprintf(stderr, "Failed CreateEvent\n");
2987 goto fail;
2988 }
2989 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2990 if (!s->hrecv) {
2991 fprintf(stderr, "Failed CreateEvent\n");
2992 goto fail;
2993 }
2994
2995 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2996 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2997 if (s->hcom == INVALID_HANDLE_VALUE) {
2998 fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2999 s->hcom = NULL;
3000 goto fail;
3001 }
ths3b46e622007-09-17 08:09:54 +00003002
bellardf3311102006-04-12 20:21:17 +00003003 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
3004 fprintf(stderr, "Failed SetupComm\n");
3005 goto fail;
3006 }
ths3b46e622007-09-17 08:09:54 +00003007
bellardf3311102006-04-12 20:21:17 +00003008 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
3009 size = sizeof(COMMCONFIG);
3010 GetDefaultCommConfig(filename, &comcfg, &size);
3011 comcfg.dcb.DCBlength = sizeof(DCB);
3012 CommConfigDialog(filename, NULL, &comcfg);
3013
3014 if (!SetCommState(s->hcom, &comcfg.dcb)) {
3015 fprintf(stderr, "Failed SetCommState\n");
3016 goto fail;
3017 }
3018
3019 if (!SetCommMask(s->hcom, EV_ERR)) {
3020 fprintf(stderr, "Failed SetCommMask\n");
3021 goto fail;
3022 }
3023
3024 cto.ReadIntervalTimeout = MAXDWORD;
3025 if (!SetCommTimeouts(s->hcom, &cto)) {
3026 fprintf(stderr, "Failed SetCommTimeouts\n");
3027 goto fail;
3028 }
ths3b46e622007-09-17 08:09:54 +00003029
bellardf3311102006-04-12 20:21:17 +00003030 if (!ClearCommError(s->hcom, &err, &comstat)) {
3031 fprintf(stderr, "Failed ClearCommError\n");
3032 goto fail;
3033 }
ths087f4ae2007-02-10 21:50:42 +00003034 qemu_add_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00003035 return 0;
3036
3037 fail:
ths087f4ae2007-02-10 21:50:42 +00003038 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00003039 return -1;
3040}
3041
3042static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
3043{
3044 WinCharState *s = chr->opaque;
3045 DWORD len, ret, size, err;
3046
3047 len = len1;
3048 ZeroMemory(&s->osend, sizeof(s->osend));
3049 s->osend.hEvent = s->hsend;
3050 while (len > 0) {
3051 if (s->hsend)
3052 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
3053 else
3054 ret = WriteFile(s->hcom, buf, len, &size, NULL);
3055 if (!ret) {
3056 err = GetLastError();
3057 if (err == ERROR_IO_PENDING) {
3058 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
3059 if (ret) {
3060 buf += size;
3061 len -= size;
3062 } else {
3063 break;
3064 }
3065 } else {
3066 break;
3067 }
3068 } else {
3069 buf += size;
3070 len -= size;
3071 }
3072 }
3073 return len1 - len;
3074}
3075
ths087f4ae2007-02-10 21:50:42 +00003076static int win_chr_read_poll(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003077{
ths087f4ae2007-02-10 21:50:42 +00003078 WinCharState *s = chr->opaque;
3079
3080 s->max_size = qemu_chr_can_read(chr);
bellardf3311102006-04-12 20:21:17 +00003081 return s->max_size;
3082}
pbrooke5b0bc42007-01-27 23:46:43 +00003083
ths087f4ae2007-02-10 21:50:42 +00003084static void win_chr_readfile(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003085{
ths087f4ae2007-02-10 21:50:42 +00003086 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003087 int ret, err;
3088 uint8_t buf[1024];
3089 DWORD size;
ths3b46e622007-09-17 08:09:54 +00003090
bellardf3311102006-04-12 20:21:17 +00003091 ZeroMemory(&s->orecv, sizeof(s->orecv));
3092 s->orecv.hEvent = s->hrecv;
3093 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
3094 if (!ret) {
3095 err = GetLastError();
3096 if (err == ERROR_IO_PENDING) {
3097 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
3098 }
3099 }
3100
3101 if (size > 0) {
ths087f4ae2007-02-10 21:50:42 +00003102 qemu_chr_read(chr, buf, size);
bellardf3311102006-04-12 20:21:17 +00003103 }
3104}
3105
ths087f4ae2007-02-10 21:50:42 +00003106static void win_chr_read(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003107{
ths087f4ae2007-02-10 21:50:42 +00003108 WinCharState *s = chr->opaque;
3109
bellardf3311102006-04-12 20:21:17 +00003110 if (s->len > s->max_size)
3111 s->len = s->max_size;
3112 if (s->len == 0)
3113 return;
ths3b46e622007-09-17 08:09:54 +00003114
ths087f4ae2007-02-10 21:50:42 +00003115 win_chr_readfile(chr);
bellardf3311102006-04-12 20:21:17 +00003116}
3117
3118static int win_chr_poll(void *opaque)
3119{
ths087f4ae2007-02-10 21:50:42 +00003120 CharDriverState *chr = opaque;
3121 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003122 COMSTAT status;
3123 DWORD comerr;
ths3b46e622007-09-17 08:09:54 +00003124
bellardf3311102006-04-12 20:21:17 +00003125 ClearCommError(s->hcom, &comerr, &status);
3126 if (status.cbInQue > 0) {
3127 s->len = status.cbInQue;
ths087f4ae2007-02-10 21:50:42 +00003128 win_chr_read_poll(chr);
3129 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00003130 return 1;
3131 }
3132 return 0;
3133}
3134
ths52f61fd2006-12-22 21:20:52 +00003135static CharDriverState *qemu_chr_open_win(const char *filename)
bellardf3311102006-04-12 20:21:17 +00003136{
3137 CharDriverState *chr;
3138 WinCharState *s;
ths3b46e622007-09-17 08:09:54 +00003139
bellardf3311102006-04-12 20:21:17 +00003140 chr = qemu_mallocz(sizeof(CharDriverState));
3141 if (!chr)
3142 return NULL;
3143 s = qemu_mallocz(sizeof(WinCharState));
3144 if (!s) {
3145 free(chr);
3146 return NULL;
3147 }
3148 chr->opaque = s;
3149 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00003150 chr->chr_close = win_chr_close;
3151
ths087f4ae2007-02-10 21:50:42 +00003152 if (win_chr_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00003153 free(s);
3154 free(chr);
3155 return NULL;
3156 }
ths86e94de2007-01-05 22:01:59 +00003157 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003158 return chr;
3159}
3160
3161static int win_chr_pipe_poll(void *opaque)
3162{
ths087f4ae2007-02-10 21:50:42 +00003163 CharDriverState *chr = opaque;
3164 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003165 DWORD size;
3166
3167 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
3168 if (size > 0) {
3169 s->len = size;
ths087f4ae2007-02-10 21:50:42 +00003170 win_chr_read_poll(chr);
3171 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00003172 return 1;
3173 }
3174 return 0;
3175}
3176
ths087f4ae2007-02-10 21:50:42 +00003177static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00003178{
ths087f4ae2007-02-10 21:50:42 +00003179 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003180 OVERLAPPED ov;
3181 int ret;
3182 DWORD size;
3183 char openname[256];
ths3b46e622007-09-17 08:09:54 +00003184
bellardf3311102006-04-12 20:21:17 +00003185 s->fpipe = TRUE;
3186
3187 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
3188 if (!s->hsend) {
3189 fprintf(stderr, "Failed CreateEvent\n");
3190 goto fail;
3191 }
3192 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
3193 if (!s->hrecv) {
3194 fprintf(stderr, "Failed CreateEvent\n");
3195 goto fail;
3196 }
ths3b46e622007-09-17 08:09:54 +00003197
bellardf3311102006-04-12 20:21:17 +00003198 snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
3199 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
3200 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
3201 PIPE_WAIT,
3202 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
3203 if (s->hcom == INVALID_HANDLE_VALUE) {
3204 fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
3205 s->hcom = NULL;
3206 goto fail;
3207 }
3208
3209 ZeroMemory(&ov, sizeof(ov));
3210 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
3211 ret = ConnectNamedPipe(s->hcom, &ov);
3212 if (ret) {
3213 fprintf(stderr, "Failed ConnectNamedPipe\n");
3214 goto fail;
3215 }
3216
3217 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
3218 if (!ret) {
3219 fprintf(stderr, "Failed GetOverlappedResult\n");
3220 if (ov.hEvent) {
3221 CloseHandle(ov.hEvent);
3222 ov.hEvent = NULL;
3223 }
3224 goto fail;
3225 }
3226
3227 if (ov.hEvent) {
3228 CloseHandle(ov.hEvent);
3229 ov.hEvent = NULL;
3230 }
ths087f4ae2007-02-10 21:50:42 +00003231 qemu_add_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00003232 return 0;
3233
3234 fail:
ths087f4ae2007-02-10 21:50:42 +00003235 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00003236 return -1;
3237}
3238
3239
ths52f61fd2006-12-22 21:20:52 +00003240static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
bellardf3311102006-04-12 20:21:17 +00003241{
3242 CharDriverState *chr;
3243 WinCharState *s;
3244
3245 chr = qemu_mallocz(sizeof(CharDriverState));
3246 if (!chr)
3247 return NULL;
3248 s = qemu_mallocz(sizeof(WinCharState));
3249 if (!s) {
3250 free(chr);
3251 return NULL;
3252 }
3253 chr->opaque = s;
3254 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00003255 chr->chr_close = win_chr_close;
ths3b46e622007-09-17 08:09:54 +00003256
ths087f4ae2007-02-10 21:50:42 +00003257 if (win_chr_pipe_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00003258 free(s);
3259 free(chr);
3260 return NULL;
3261 }
ths86e94de2007-01-05 22:01:59 +00003262 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003263 return chr;
3264}
3265
ths52f61fd2006-12-22 21:20:52 +00003266static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
bellardf3311102006-04-12 20:21:17 +00003267{
3268 CharDriverState *chr;
3269 WinCharState *s;
3270
3271 chr = qemu_mallocz(sizeof(CharDriverState));
3272 if (!chr)
3273 return NULL;
3274 s = qemu_mallocz(sizeof(WinCharState));
3275 if (!s) {
3276 free(chr);
3277 return NULL;
3278 }
3279 s->hcom = fd_out;
3280 chr->opaque = s;
3281 chr->chr_write = win_chr_write;
ths86e94de2007-01-05 22:01:59 +00003282 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003283 return chr;
3284}
ths72d46472007-05-13 14:54:54 +00003285
3286static CharDriverState *qemu_chr_open_win_con(const char *filename)
3287{
3288 return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
3289}
3290
ths52f61fd2006-12-22 21:20:52 +00003291static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
bellardf3311102006-04-12 20:21:17 +00003292{
3293 HANDLE fd_out;
ths3b46e622007-09-17 08:09:54 +00003294
bellardf3311102006-04-12 20:21:17 +00003295 fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3296 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3297 if (fd_out == INVALID_HANDLE_VALUE)
3298 return NULL;
3299
3300 return qemu_chr_open_win_file(fd_out);
3301}
thsaec62502007-06-25 11:48:07 +00003302#endif /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003303
bellard0bab00f2006-06-25 14:49:44 +00003304/***********************************************************/
3305/* UDP Net console */
3306
3307typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003308 int fd;
3309 struct sockaddr_in daddr;
ths60fe76f2007-12-16 03:02:09 +00003310 uint8_t buf[1024];
bellard0bab00f2006-06-25 14:49:44 +00003311 int bufcnt;
3312 int bufptr;
3313 int max_size;
3314} NetCharDriver;
3315
3316static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3317{
3318 NetCharDriver *s = chr->opaque;
3319
3320 return sendto(s->fd, buf, len, 0,
3321 (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
3322}
3323
3324static int udp_chr_read_poll(void *opaque)
3325{
3326 CharDriverState *chr = opaque;
3327 NetCharDriver *s = chr->opaque;
3328
pbrooke5b0bc42007-01-27 23:46:43 +00003329 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003330
3331 /* If there were any stray characters in the queue process them
3332 * first
3333 */
3334 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003335 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003336 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003337 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003338 }
3339 return s->max_size;
3340}
3341
3342static void udp_chr_read(void *opaque)
3343{
3344 CharDriverState *chr = opaque;
3345 NetCharDriver *s = chr->opaque;
3346
3347 if (s->max_size == 0)
3348 return;
3349 s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
3350 s->bufptr = s->bufcnt;
3351 if (s->bufcnt <= 0)
3352 return;
3353
3354 s->bufptr = 0;
3355 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003356 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003357 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003358 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003359 }
3360}
3361
pbrooke5b0bc42007-01-27 23:46:43 +00003362static void udp_chr_update_read_handler(CharDriverState *chr)
bellard0bab00f2006-06-25 14:49:44 +00003363{
3364 NetCharDriver *s = chr->opaque;
3365
3366 if (s->fd >= 0) {
bellard0bab00f2006-06-25 14:49:44 +00003367 qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
3368 udp_chr_read, NULL, chr);
3369 }
3370}
3371
3372int parse_host_port(struct sockaddr_in *saddr, const char *str);
ths52f61fd2006-12-22 21:20:52 +00003373#ifndef _WIN32
3374static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3375#endif
bellard951f1352006-06-27 21:02:43 +00003376int parse_host_src_port(struct sockaddr_in *haddr,
3377 struct sockaddr_in *saddr,
3378 const char *str);
bellard0bab00f2006-06-25 14:49:44 +00003379
ths52f61fd2006-12-22 21:20:52 +00003380static CharDriverState *qemu_chr_open_udp(const char *def)
bellard0bab00f2006-06-25 14:49:44 +00003381{
3382 CharDriverState *chr = NULL;
3383 NetCharDriver *s = NULL;
3384 int fd = -1;
bellard951f1352006-06-27 21:02:43 +00003385 struct sockaddr_in saddr;
bellard0bab00f2006-06-25 14:49:44 +00003386
3387 chr = qemu_mallocz(sizeof(CharDriverState));
3388 if (!chr)
3389 goto return_err;
3390 s = qemu_mallocz(sizeof(NetCharDriver));
3391 if (!s)
3392 goto return_err;
3393
3394 fd = socket(PF_INET, SOCK_DGRAM, 0);
3395 if (fd < 0) {
3396 perror("socket(PF_INET, SOCK_DGRAM)");
3397 goto return_err;
3398 }
3399
bellard951f1352006-06-27 21:02:43 +00003400 if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
3401 printf("Could not parse: %s\n", def);
3402 goto return_err;
bellard0bab00f2006-06-25 14:49:44 +00003403 }
3404
bellard951f1352006-06-27 21:02:43 +00003405 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
bellard0bab00f2006-06-25 14:49:44 +00003406 {
3407 perror("bind");
3408 goto return_err;
3409 }
3410
3411 s->fd = fd;
3412 s->bufcnt = 0;
3413 s->bufptr = 0;
3414 chr->opaque = s;
3415 chr->chr_write = udp_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00003416 chr->chr_update_read_handler = udp_chr_update_read_handler;
bellard0bab00f2006-06-25 14:49:44 +00003417 return chr;
3418
3419return_err:
3420 if (chr)
3421 free(chr);
3422 if (s)
3423 free(s);
3424 if (fd >= 0)
3425 closesocket(fd);
3426 return NULL;
3427}
3428
3429/***********************************************************/
3430/* TCP Net console */
3431
3432typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003433 int fd, listen_fd;
3434 int connected;
3435 int max_size;
bellard951f1352006-06-27 21:02:43 +00003436 int do_telnetopt;
pbrooke5b0bc42007-01-27 23:46:43 +00003437 int do_nodelay;
thsffd843b2006-12-21 19:46:43 +00003438 int is_unix;
bellard0bab00f2006-06-25 14:49:44 +00003439} TCPCharDriver;
3440
3441static void tcp_chr_accept(void *opaque);
3442
3443static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3444{
3445 TCPCharDriver *s = chr->opaque;
3446 if (s->connected) {
3447 return send_all(s->fd, buf, len);
3448 } else {
3449 /* XXX: indicate an error ? */
3450 return len;
3451 }
3452}
3453
3454static int tcp_chr_read_poll(void *opaque)
3455{
3456 CharDriverState *chr = opaque;
3457 TCPCharDriver *s = chr->opaque;
3458 if (!s->connected)
3459 return 0;
pbrooke5b0bc42007-01-27 23:46:43 +00003460 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003461 return s->max_size;
3462}
3463
bellard951f1352006-06-27 21:02:43 +00003464#define IAC 255
3465#define IAC_BREAK 243
3466static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
3467 TCPCharDriver *s,
ths60fe76f2007-12-16 03:02:09 +00003468 uint8_t *buf, int *size)
bellard951f1352006-06-27 21:02:43 +00003469{
3470 /* Handle any telnet client's basic IAC options to satisfy char by
3471 * char mode with no echo. All IAC options will be removed from
3472 * the buf and the do_telnetopt variable will be used to track the
3473 * state of the width of the IAC information.
3474 *
3475 * IAC commands come in sets of 3 bytes with the exception of the
3476 * "IAC BREAK" command and the double IAC.
3477 */
3478
3479 int i;
3480 int j = 0;
3481
3482 for (i = 0; i < *size; i++) {
3483 if (s->do_telnetopt > 1) {
3484 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3485 /* Double IAC means send an IAC */
3486 if (j != i)
3487 buf[j] = buf[i];
3488 j++;
3489 s->do_telnetopt = 1;
3490 } else {
3491 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3492 /* Handle IAC break commands by sending a serial break */
pbrooke5b0bc42007-01-27 23:46:43 +00003493 qemu_chr_event(chr, CHR_EVENT_BREAK);
bellard951f1352006-06-27 21:02:43 +00003494 s->do_telnetopt++;
3495 }
3496 s->do_telnetopt++;
3497 }
3498 if (s->do_telnetopt >= 4) {
3499 s->do_telnetopt = 1;
3500 }
3501 } else {
3502 if ((unsigned char)buf[i] == IAC) {
3503 s->do_telnetopt = 2;
3504 } else {
3505 if (j != i)
3506 buf[j] = buf[i];
3507 j++;
3508 }
3509 }
3510 }
3511 *size = j;
3512}
3513
bellard0bab00f2006-06-25 14:49:44 +00003514static void tcp_chr_read(void *opaque)
3515{
3516 CharDriverState *chr = opaque;
3517 TCPCharDriver *s = chr->opaque;
3518 uint8_t buf[1024];
3519 int len, size;
3520
3521 if (!s->connected || s->max_size <= 0)
3522 return;
3523 len = sizeof(buf);
3524 if (len > s->max_size)
3525 len = s->max_size;
3526 size = recv(s->fd, buf, len, 0);
3527 if (size == 0) {
3528 /* connection closed */
3529 s->connected = 0;
3530 if (s->listen_fd >= 0) {
3531 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3532 }
3533 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3534 closesocket(s->fd);
3535 s->fd = -1;
3536 } else if (size > 0) {
bellard951f1352006-06-27 21:02:43 +00003537 if (s->do_telnetopt)
3538 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3539 if (size > 0)
pbrooke5b0bc42007-01-27 23:46:43 +00003540 qemu_chr_read(chr, buf, size);
bellard0bab00f2006-06-25 14:49:44 +00003541 }
3542}
3543
bellard0bab00f2006-06-25 14:49:44 +00003544static void tcp_chr_connect(void *opaque)
3545{
3546 CharDriverState *chr = opaque;
3547 TCPCharDriver *s = chr->opaque;
3548
3549 s->connected = 1;
3550 qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3551 tcp_chr_read, NULL, chr);
ths86e94de2007-01-05 22:01:59 +00003552 qemu_chr_reset(chr);
bellard0bab00f2006-06-25 14:49:44 +00003553}
3554
bellard951f1352006-06-27 21:02:43 +00003555#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3556static void tcp_chr_telnet_init(int fd)
3557{
3558 char buf[3];
3559 /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3560 IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
3561 send(fd, (char *)buf, 3, 0);
3562 IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
3563 send(fd, (char *)buf, 3, 0);
3564 IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
3565 send(fd, (char *)buf, 3, 0);
3566 IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
3567 send(fd, (char *)buf, 3, 0);
3568}
3569
pbrookf7499982007-01-28 00:10:01 +00003570static void socket_set_nodelay(int fd)
3571{
3572 int val = 1;
3573 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3574}
3575
bellard0bab00f2006-06-25 14:49:44 +00003576static void tcp_chr_accept(void *opaque)
3577{
3578 CharDriverState *chr = opaque;
3579 TCPCharDriver *s = chr->opaque;
3580 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003581#ifndef _WIN32
3582 struct sockaddr_un uaddr;
3583#endif
3584 struct sockaddr *addr;
bellard0bab00f2006-06-25 14:49:44 +00003585 socklen_t len;
3586 int fd;
3587
3588 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003589#ifndef _WIN32
3590 if (s->is_unix) {
3591 len = sizeof(uaddr);
3592 addr = (struct sockaddr *)&uaddr;
3593 } else
3594#endif
3595 {
3596 len = sizeof(saddr);
3597 addr = (struct sockaddr *)&saddr;
3598 }
3599 fd = accept(s->listen_fd, addr, &len);
bellard0bab00f2006-06-25 14:49:44 +00003600 if (fd < 0 && errno != EINTR) {
3601 return;
3602 } else if (fd >= 0) {
bellard951f1352006-06-27 21:02:43 +00003603 if (s->do_telnetopt)
3604 tcp_chr_telnet_init(fd);
bellard0bab00f2006-06-25 14:49:44 +00003605 break;
3606 }
3607 }
3608 socket_set_nonblock(fd);
pbrookf7499982007-01-28 00:10:01 +00003609 if (s->do_nodelay)
3610 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003611 s->fd = fd;
3612 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3613 tcp_chr_connect(chr);
3614}
3615
3616static void tcp_chr_close(CharDriverState *chr)
3617{
3618 TCPCharDriver *s = chr->opaque;
3619 if (s->fd >= 0)
3620 closesocket(s->fd);
3621 if (s->listen_fd >= 0)
3622 closesocket(s->listen_fd);
3623 qemu_free(s);
3624}
3625
ths5fafdf22007-09-16 21:08:06 +00003626static CharDriverState *qemu_chr_open_tcp(const char *host_str,
thsffd843b2006-12-21 19:46:43 +00003627 int is_telnet,
3628 int is_unix)
bellard0bab00f2006-06-25 14:49:44 +00003629{
3630 CharDriverState *chr = NULL;
3631 TCPCharDriver *s = NULL;
3632 int fd = -1, ret, err, val;
bellard951f1352006-06-27 21:02:43 +00003633 int is_listen = 0;
3634 int is_waitconnect = 1;
pbrookf7499982007-01-28 00:10:01 +00003635 int do_nodelay = 0;
bellard951f1352006-06-27 21:02:43 +00003636 const char *ptr;
bellard0bab00f2006-06-25 14:49:44 +00003637 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003638#ifndef _WIN32
3639 struct sockaddr_un uaddr;
3640#endif
3641 struct sockaddr *addr;
3642 socklen_t addrlen;
bellard0bab00f2006-06-25 14:49:44 +00003643
thsffd843b2006-12-21 19:46:43 +00003644#ifndef _WIN32
3645 if (is_unix) {
3646 addr = (struct sockaddr *)&uaddr;
3647 addrlen = sizeof(uaddr);
3648 if (parse_unix_path(&uaddr, host_str) < 0)
3649 goto fail;
3650 } else
3651#endif
3652 {
3653 addr = (struct sockaddr *)&saddr;
3654 addrlen = sizeof(saddr);
3655 if (parse_host_port(&saddr, host_str) < 0)
3656 goto fail;
3657 }
bellard0bab00f2006-06-25 14:49:44 +00003658
bellard951f1352006-06-27 21:02:43 +00003659 ptr = host_str;
3660 while((ptr = strchr(ptr,','))) {
3661 ptr++;
3662 if (!strncmp(ptr,"server",6)) {
3663 is_listen = 1;
3664 } else if (!strncmp(ptr,"nowait",6)) {
3665 is_waitconnect = 0;
pbrookf7499982007-01-28 00:10:01 +00003666 } else if (!strncmp(ptr,"nodelay",6)) {
3667 do_nodelay = 1;
bellard951f1352006-06-27 21:02:43 +00003668 } else {
3669 printf("Unknown option: %s\n", ptr);
3670 goto fail;
3671 }
3672 }
3673 if (!is_listen)
3674 is_waitconnect = 0;
3675
bellard0bab00f2006-06-25 14:49:44 +00003676 chr = qemu_mallocz(sizeof(CharDriverState));
3677 if (!chr)
3678 goto fail;
3679 s = qemu_mallocz(sizeof(TCPCharDriver));
3680 if (!s)
3681 goto fail;
thsffd843b2006-12-21 19:46:43 +00003682
3683#ifndef _WIN32
3684 if (is_unix)
3685 fd = socket(PF_UNIX, SOCK_STREAM, 0);
3686 else
3687#endif
3688 fd = socket(PF_INET, SOCK_STREAM, 0);
ths5fafdf22007-09-16 21:08:06 +00003689
3690 if (fd < 0)
bellard0bab00f2006-06-25 14:49:44 +00003691 goto fail;
bellard951f1352006-06-27 21:02:43 +00003692
3693 if (!is_waitconnect)
3694 socket_set_nonblock(fd);
bellard0bab00f2006-06-25 14:49:44 +00003695
3696 s->connected = 0;
3697 s->fd = -1;
3698 s->listen_fd = -1;
thsffd843b2006-12-21 19:46:43 +00003699 s->is_unix = is_unix;
pbrookf7499982007-01-28 00:10:01 +00003700 s->do_nodelay = do_nodelay && !is_unix;
thsffd843b2006-12-21 19:46:43 +00003701
3702 chr->opaque = s;
3703 chr->chr_write = tcp_chr_write;
thsffd843b2006-12-21 19:46:43 +00003704 chr->chr_close = tcp_chr_close;
3705
bellard0bab00f2006-06-25 14:49:44 +00003706 if (is_listen) {
3707 /* allow fast reuse */
thsffd843b2006-12-21 19:46:43 +00003708#ifndef _WIN32
3709 if (is_unix) {
3710 char path[109];
bellardae45d362008-06-11 09:44:44 +00003711 pstrcpy(path, sizeof(path), uaddr.sun_path);
thsffd843b2006-12-21 19:46:43 +00003712 unlink(path);
3713 } else
3714#endif
3715 {
3716 val = 1;
3717 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3718 }
ths3b46e622007-09-17 08:09:54 +00003719
thsffd843b2006-12-21 19:46:43 +00003720 ret = bind(fd, addr, addrlen);
3721 if (ret < 0)
bellard0bab00f2006-06-25 14:49:44 +00003722 goto fail;
thsffd843b2006-12-21 19:46:43 +00003723
bellard0bab00f2006-06-25 14:49:44 +00003724 ret = listen(fd, 0);
3725 if (ret < 0)
3726 goto fail;
thsffd843b2006-12-21 19:46:43 +00003727
bellard0bab00f2006-06-25 14:49:44 +00003728 s->listen_fd = fd;
3729 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
bellard951f1352006-06-27 21:02:43 +00003730 if (is_telnet)
3731 s->do_telnetopt = 1;
bellard0bab00f2006-06-25 14:49:44 +00003732 } else {
3733 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003734 ret = connect(fd, addr, addrlen);
bellard0bab00f2006-06-25 14:49:44 +00003735 if (ret < 0) {
3736 err = socket_error();
3737 if (err == EINTR || err == EWOULDBLOCK) {
3738 } else if (err == EINPROGRESS) {
3739 break;
thsf5b12262007-03-25 15:58:03 +00003740#ifdef _WIN32
3741 } else if (err == WSAEALREADY) {
3742 break;
3743#endif
bellard0bab00f2006-06-25 14:49:44 +00003744 } else {
3745 goto fail;
3746 }
3747 } else {
3748 s->connected = 1;
3749 break;
3750 }
3751 }
3752 s->fd = fd;
pbrookf7499982007-01-28 00:10:01 +00003753 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003754 if (s->connected)
3755 tcp_chr_connect(chr);
3756 else
3757 qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3758 }
ths3b46e622007-09-17 08:09:54 +00003759
bellard951f1352006-06-27 21:02:43 +00003760 if (is_listen && is_waitconnect) {
3761 printf("QEMU waiting for connection on: %s\n", host_str);
3762 tcp_chr_accept(chr);
3763 socket_set_nonblock(s->listen_fd);
3764 }
3765
bellard0bab00f2006-06-25 14:49:44 +00003766 return chr;
3767 fail:
3768 if (fd >= 0)
3769 closesocket(fd);
3770 qemu_free(s);
3771 qemu_free(chr);
3772 return NULL;
3773}
3774
bellard82c643f2004-07-14 17:28:13 +00003775CharDriverState *qemu_chr_open(const char *filename)
3776{
bellardf8d179e2005-11-08 22:30:36 +00003777 const char *p;
bellardfd1dff42006-02-01 21:29:26 +00003778
bellard82c643f2004-07-14 17:28:13 +00003779 if (!strcmp(filename, "vc")) {
thsaf3a9032007-07-11 23:14:59 +00003780 return text_console_init(&display_state, 0);
3781 } else if (strstart(filename, "vc:", &p)) {
3782 return text_console_init(&display_state, p);
bellard82c643f2004-07-14 17:28:13 +00003783 } else if (!strcmp(filename, "null")) {
3784 return qemu_chr_open_null();
ths5fafdf22007-09-16 21:08:06 +00003785 } else
bellard0bab00f2006-06-25 14:49:44 +00003786 if (strstart(filename, "tcp:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003787 return qemu_chr_open_tcp(p, 0, 0);
bellard0bab00f2006-06-25 14:49:44 +00003788 } else
bellard951f1352006-06-27 21:02:43 +00003789 if (strstart(filename, "telnet:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003790 return qemu_chr_open_tcp(p, 1, 0);
bellard0bab00f2006-06-25 14:49:44 +00003791 } else
3792 if (strstart(filename, "udp:", &p)) {
3793 return qemu_chr_open_udp(p);
3794 } else
ths20d8a3e2007-02-18 17:04:49 +00003795 if (strstart(filename, "mon:", &p)) {
3796 CharDriverState *drv = qemu_chr_open(p);
3797 if (drv) {
3798 drv = qemu_chr_open_mux(drv);
3799 monitor_init(drv, !nographic);
3800 return drv;
3801 }
3802 printf("Unable to open driver: %s\n", p);
3803 return 0;
3804 } else
bellard76647282005-11-27 19:10:42 +00003805#ifndef _WIN32
thsffd843b2006-12-21 19:46:43 +00003806 if (strstart(filename, "unix:", &p)) {
3807 return qemu_chr_open_tcp(p, 0, 1);
3808 } else if (strstart(filename, "file:", &p)) {
bellardf8d179e2005-11-08 22:30:36 +00003809 return qemu_chr_open_file_out(p);
3810 } else if (strstart(filename, "pipe:", &p)) {
3811 return qemu_chr_open_pipe(p);
bellard76647282005-11-27 19:10:42 +00003812 } else if (!strcmp(filename, "pty")) {
bellard82c643f2004-07-14 17:28:13 +00003813 return qemu_chr_open_pty();
3814 } else if (!strcmp(filename, "stdio")) {
3815 return qemu_chr_open_stdio();
ths5fafdf22007-09-16 21:08:06 +00003816 } else
bellardf8d179e2005-11-08 22:30:36 +00003817#if defined(__linux__)
bellarde57a8c02005-11-10 23:58:52 +00003818 if (strstart(filename, "/dev/parport", NULL)) {
3819 return qemu_chr_open_pp(filename);
ths5fafdf22007-09-16 21:08:06 +00003820 } else
thsaec62502007-06-25 11:48:07 +00003821#endif
blueswir19892fbf2008-08-24 10:34:20 +00003822#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
3823 || defined(__NetBSD__) || defined(__OpenBSD__)
bellardf8d179e2005-11-08 22:30:36 +00003824 if (strstart(filename, "/dev/", NULL)) {
3825 return qemu_chr_open_tty(filename);
ths3fda3882007-06-28 15:14:49 +00003826 } else
3827#endif
thsaec62502007-06-25 11:48:07 +00003828#else /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003829 if (strstart(filename, "COM", NULL)) {
3830 return qemu_chr_open_win(filename);
3831 } else
3832 if (strstart(filename, "pipe:", &p)) {
3833 return qemu_chr_open_win_pipe(p);
3834 } else
ths72d46472007-05-13 14:54:54 +00003835 if (strstart(filename, "con:", NULL)) {
3836 return qemu_chr_open_win_con(filename);
3837 } else
bellardf3311102006-04-12 20:21:17 +00003838 if (strstart(filename, "file:", &p)) {
3839 return qemu_chr_open_win_file_out(p);
aurel322e4d9fb2008-04-08 06:01:02 +00003840 } else
3841#endif
3842#ifdef CONFIG_BRLAPI
3843 if (!strcmp(filename, "braille")) {
3844 return chr_baum_init();
3845 } else
bellardf3311102006-04-12 20:21:17 +00003846#endif
bellard82c643f2004-07-14 17:28:13 +00003847 {
3848 return NULL;
3849 }
3850}
3851
bellardf3311102006-04-12 20:21:17 +00003852void qemu_chr_close(CharDriverState *chr)
3853{
3854 if (chr->chr_close)
3855 chr->chr_close(chr);
balroga11d0702008-01-19 13:00:43 +00003856 qemu_free(chr);
bellardf3311102006-04-12 20:21:17 +00003857}
3858
bellardf1510b22003-06-25 00:07:40 +00003859/***********************************************************/
bellard7c9d8e02005-11-15 22:16:05 +00003860/* network device redirectors */
bellardf1510b22003-06-25 00:07:40 +00003861
j_mayer3f4afa12007-11-19 01:05:22 +00003862__attribute__ (( unused ))
pbrook9596ebb2007-11-18 01:44:38 +00003863static void hex_dump(FILE *f, const uint8_t *buf, int size)
bellard67b915a2004-03-31 23:37:16 +00003864{
bellardc20709a2004-04-21 23:27:19 +00003865 int len, i, j, c;
3866
3867 for(i=0;i<size;i+=16) {
3868 len = size - i;
3869 if (len > 16)
3870 len = 16;
3871 fprintf(f, "%08x ", i);
3872 for(j=0;j<16;j++) {
3873 if (j < len)
3874 fprintf(f, " %02x", buf[i+j]);
3875 else
3876 fprintf(f, " ");
3877 }
3878 fprintf(f, " ");
3879 for(j=0;j<len;j++) {
3880 c = buf[i+j];
3881 if (c < ' ' || c > '~')
3882 c = '.';
3883 fprintf(f, "%c", c);
3884 }
3885 fprintf(f, "\n");
3886 }
3887}
3888
bellard7c9d8e02005-11-15 22:16:05 +00003889static int parse_macaddr(uint8_t *macaddr, const char *p)
bellardc20709a2004-04-21 23:27:19 +00003890{
bellard7c9d8e02005-11-15 22:16:05 +00003891 int i;
balrog76ea08f2007-12-16 11:48:54 +00003892 char *last_char;
3893 long int offset;
3894
3895 errno = 0;
3896 offset = strtol(p, &last_char, 0);
3897 if (0 == errno && '\0' == *last_char &&
3898 offset >= 0 && offset <= 0xFFFFFF) {
3899 macaddr[3] = (offset & 0xFF0000) >> 16;
3900 macaddr[4] = (offset & 0xFF00) >> 8;
3901 macaddr[5] = offset & 0xFF;
3902 return 0;
3903 } else {
3904 for(i = 0; i < 6; i++) {
3905 macaddr[i] = strtol(p, (char **)&p, 16);
3906 if (i == 5) {
3907 if (*p != '\0')
3908 return -1;
3909 } else {
3910 if (*p != ':' && *p != '-')
3911 return -1;
3912 p++;
3913 }
bellard7c9d8e02005-11-15 22:16:05 +00003914 }
balrog76ea08f2007-12-16 11:48:54 +00003915 return 0;
bellardc20709a2004-04-21 23:27:19 +00003916 }
balrog76ea08f2007-12-16 11:48:54 +00003917
3918 return -1;
bellardc20709a2004-04-21 23:27:19 +00003919}
3920
bellard9bf05442004-08-25 22:12:49 +00003921static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3922{
3923 const char *p, *p1;
3924 int len;
3925 p = *pp;
3926 p1 = strchr(p, sep);
3927 if (!p1)
3928 return -1;
3929 len = p1 - p;
3930 p1++;
3931 if (buf_size > 0) {
3932 if (len > buf_size - 1)
3933 len = buf_size - 1;
3934 memcpy(buf, p, len);
3935 buf[len] = '\0';
3936 }
3937 *pp = p1;
3938 return 0;
3939}
3940
bellard951f1352006-06-27 21:02:43 +00003941int parse_host_src_port(struct sockaddr_in *haddr,
3942 struct sockaddr_in *saddr,
3943 const char *input_str)
3944{
3945 char *str = strdup(input_str);
3946 char *host_str = str;
3947 char *src_str;
blueswir17ccfb2e2008-09-14 06:45:34 +00003948 const char *src_str2;
bellard951f1352006-06-27 21:02:43 +00003949 char *ptr;
3950
3951 /*
3952 * Chop off any extra arguments at the end of the string which
3953 * would start with a comma, then fill in the src port information
3954 * if it was provided else use the "any address" and "any port".
3955 */
3956 if ((ptr = strchr(str,',')))
3957 *ptr = '\0';
3958
3959 if ((src_str = strchr(input_str,'@'))) {
3960 *src_str = '\0';
3961 src_str++;
3962 }
3963
3964 if (parse_host_port(haddr, host_str) < 0)
3965 goto fail;
3966
blueswir17ccfb2e2008-09-14 06:45:34 +00003967 src_str2 = src_str;
bellard951f1352006-06-27 21:02:43 +00003968 if (!src_str || *src_str == '\0')
blueswir17ccfb2e2008-09-14 06:45:34 +00003969 src_str2 = ":0";
bellard951f1352006-06-27 21:02:43 +00003970
blueswir17ccfb2e2008-09-14 06:45:34 +00003971 if (parse_host_port(saddr, src_str2) < 0)
bellard951f1352006-06-27 21:02:43 +00003972 goto fail;
3973
3974 free(str);
3975 return(0);
3976
3977fail:
3978 free(str);
3979 return -1;
3980}
3981
bellard7c9d8e02005-11-15 22:16:05 +00003982int parse_host_port(struct sockaddr_in *saddr, const char *str)
3983{
3984 char buf[512];
3985 struct hostent *he;
3986 const char *p, *r;
3987 int port;
3988
3989 p = str;
3990 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3991 return -1;
3992 saddr->sin_family = AF_INET;
3993 if (buf[0] == '\0') {
3994 saddr->sin_addr.s_addr = 0;
3995 } else {
3996 if (isdigit(buf[0])) {
3997 if (!inet_aton(buf, &saddr->sin_addr))
3998 return -1;
3999 } else {
bellard7c9d8e02005-11-15 22:16:05 +00004000 if ((he = gethostbyname(buf)) == NULL)
4001 return - 1;
4002 saddr->sin_addr = *(struct in_addr *)he->h_addr;
bellard7c9d8e02005-11-15 22:16:05 +00004003 }
4004 }
4005 port = strtol(p, (char **)&r, 0);
4006 if (r == p)
4007 return -1;
4008 saddr->sin_port = htons(port);
4009 return 0;
4010}
4011
ths52f61fd2006-12-22 21:20:52 +00004012#ifndef _WIN32
4013static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
thsffd843b2006-12-21 19:46:43 +00004014{
4015 const char *p;
4016 int len;
4017
4018 len = MIN(108, strlen(str));
4019 p = strchr(str, ',');
4020 if (p)
4021 len = MIN(len, p - str);
4022
4023 memset(uaddr, 0, sizeof(*uaddr));
4024
4025 uaddr->sun_family = AF_UNIX;
4026 memcpy(uaddr->sun_path, str, len);
4027
4028 return 0;
4029}
ths52f61fd2006-12-22 21:20:52 +00004030#endif
thsffd843b2006-12-21 19:46:43 +00004031
bellard7c9d8e02005-11-15 22:16:05 +00004032/* find or alloc a new VLAN */
4033VLANState *qemu_find_vlan(int id)
4034{
4035 VLANState **pvlan, *vlan;
4036 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4037 if (vlan->id == id)
4038 return vlan;
4039 }
4040 vlan = qemu_mallocz(sizeof(VLANState));
4041 if (!vlan)
4042 return NULL;
4043 vlan->id = id;
4044 vlan->next = NULL;
4045 pvlan = &first_vlan;
4046 while (*pvlan != NULL)
4047 pvlan = &(*pvlan)->next;
4048 *pvlan = vlan;
4049 return vlan;
4050}
4051
4052VLANClientState *qemu_new_vlan_client(VLANState *vlan,
pbrookd861b052006-02-04 22:15:28 +00004053 IOReadHandler *fd_read,
4054 IOCanRWHandler *fd_can_read,
4055 void *opaque)
bellard7c9d8e02005-11-15 22:16:05 +00004056{
4057 VLANClientState *vc, **pvc;
4058 vc = qemu_mallocz(sizeof(VLANClientState));
4059 if (!vc)
4060 return NULL;
4061 vc->fd_read = fd_read;
pbrookd861b052006-02-04 22:15:28 +00004062 vc->fd_can_read = fd_can_read;
bellard7c9d8e02005-11-15 22:16:05 +00004063 vc->opaque = opaque;
4064 vc->vlan = vlan;
4065
4066 vc->next = NULL;
4067 pvc = &vlan->first_client;
4068 while (*pvc != NULL)
4069 pvc = &(*pvc)->next;
4070 *pvc = vc;
4071 return vc;
4072}
4073
balrogdcf414d2008-07-17 21:00:05 +00004074void qemu_del_vlan_client(VLANClientState *vc)
4075{
4076 VLANClientState **pvc = &vc->vlan->first_client;
4077
4078 while (*pvc != NULL)
4079 if (*pvc == vc) {
4080 *pvc = vc->next;
4081 free(vc);
4082 break;
4083 } else
4084 pvc = &(*pvc)->next;
4085}
4086
pbrookd861b052006-02-04 22:15:28 +00004087int qemu_can_send_packet(VLANClientState *vc1)
4088{
4089 VLANState *vlan = vc1->vlan;
4090 VLANClientState *vc;
4091
4092 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
4093 if (vc != vc1) {
balrogfbd17112007-07-02 13:31:53 +00004094 if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
4095 return 1;
pbrookd861b052006-02-04 22:15:28 +00004096 }
4097 }
balrogfbd17112007-07-02 13:31:53 +00004098 return 0;
pbrookd861b052006-02-04 22:15:28 +00004099}
4100
bellard7c9d8e02005-11-15 22:16:05 +00004101void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
4102{
4103 VLANState *vlan = vc1->vlan;
4104 VLANClientState *vc;
4105
4106#if 0
4107 printf("vlan %d send:\n", vlan->id);
4108 hex_dump(stdout, buf, size);
4109#endif
4110 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
4111 if (vc != vc1) {
4112 vc->fd_read(vc->opaque, buf, size);
4113 }
4114 }
4115}
4116
4117#if defined(CONFIG_SLIRP)
4118
4119/* slirp network adapter */
4120
4121static int slirp_inited;
4122static VLANClientState *slirp_vc;
4123
4124int slirp_can_output(void)
4125{
pbrook3b7f5d42006-02-10 17:34:02 +00004126 return !slirp_vc || qemu_can_send_packet(slirp_vc);
bellard7c9d8e02005-11-15 22:16:05 +00004127}
4128
4129void slirp_output(const uint8_t *pkt, int pkt_len)
4130{
4131#if 0
4132 printf("slirp output:\n");
4133 hex_dump(stdout, pkt, pkt_len);
4134#endif
pbrook3b7f5d42006-02-10 17:34:02 +00004135 if (!slirp_vc)
4136 return;
bellard7c9d8e02005-11-15 22:16:05 +00004137 qemu_send_packet(slirp_vc, pkt, pkt_len);
4138}
4139
4140static void slirp_receive(void *opaque, const uint8_t *buf, int size)
4141{
4142#if 0
4143 printf("slirp input:\n");
4144 hex_dump(stdout, buf, size);
4145#endif
4146 slirp_input(buf, size);
4147}
4148
4149static int net_slirp_init(VLANState *vlan)
4150{
4151 if (!slirp_inited) {
4152 slirp_inited = 1;
4153 slirp_init();
4154 }
ths5fafdf22007-09-16 21:08:06 +00004155 slirp_vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00004156 slirp_receive, NULL, NULL);
bellard7c9d8e02005-11-15 22:16:05 +00004157 snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
4158 return 0;
4159}
4160
bellard9bf05442004-08-25 22:12:49 +00004161static void net_slirp_redir(const char *redir_str)
4162{
4163 int is_udp;
4164 char buf[256], *r;
4165 const char *p;
4166 struct in_addr guest_addr;
4167 int host_port, guest_port;
ths3b46e622007-09-17 08:09:54 +00004168
bellard9bf05442004-08-25 22:12:49 +00004169 if (!slirp_inited) {
4170 slirp_inited = 1;
4171 slirp_init();
4172 }
4173
4174 p = redir_str;
4175 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4176 goto fail;
4177 if (!strcmp(buf, "tcp")) {
4178 is_udp = 0;
4179 } else if (!strcmp(buf, "udp")) {
4180 is_udp = 1;
4181 } else {
4182 goto fail;
4183 }
4184
4185 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4186 goto fail;
4187 host_port = strtol(buf, &r, 0);
4188 if (r == buf)
4189 goto fail;
4190
4191 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4192 goto fail;
4193 if (buf[0] == '\0') {
4194 pstrcpy(buf, sizeof(buf), "10.0.2.15");
4195 }
4196 if (!inet_aton(buf, &guest_addr))
4197 goto fail;
ths3b46e622007-09-17 08:09:54 +00004198
bellard9bf05442004-08-25 22:12:49 +00004199 guest_port = strtol(p, &r, 0);
4200 if (r == p)
4201 goto fail;
ths3b46e622007-09-17 08:09:54 +00004202
bellard9bf05442004-08-25 22:12:49 +00004203 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
4204 fprintf(stderr, "qemu: could not set up redirection\n");
4205 exit(1);
4206 }
4207 return;
4208 fail:
4209 fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
4210 exit(1);
4211}
ths3b46e622007-09-17 08:09:54 +00004212
bellardc94c8d62004-09-13 21:37:34 +00004213#ifndef _WIN32
4214
bellard9d728e82004-09-05 23:09:03 +00004215char smb_dir[1024];
4216
balrog044fae82008-01-14 03:11:16 +00004217static void erase_dir(char *dir_name)
bellard9d728e82004-09-05 23:09:03 +00004218{
4219 DIR *d;
4220 struct dirent *de;
4221 char filename[1024];
4222
4223 /* erase all the files in the directory */
balrog044fae82008-01-14 03:11:16 +00004224 if ((d = opendir(dir_name)) != 0) {
4225 for(;;) {
4226 de = readdir(d);
4227 if (!de)
4228 break;
4229 if (strcmp(de->d_name, ".") != 0 &&
4230 strcmp(de->d_name, "..") != 0) {
4231 snprintf(filename, sizeof(filename), "%s/%s",
4232 smb_dir, de->d_name);
4233 if (unlink(filename) != 0) /* is it a directory? */
4234 erase_dir(filename);
4235 }
bellard9d728e82004-09-05 23:09:03 +00004236 }
balrog044fae82008-01-14 03:11:16 +00004237 closedir(d);
4238 rmdir(dir_name);
bellard9d728e82004-09-05 23:09:03 +00004239 }
balrog044fae82008-01-14 03:11:16 +00004240}
4241
4242/* automatic user mode samba server configuration */
4243static void smb_exit(void)
4244{
4245 erase_dir(smb_dir);
bellard9d728e82004-09-05 23:09:03 +00004246}
4247
4248/* automatic user mode samba server configuration */
pbrook9596ebb2007-11-18 01:44:38 +00004249static void net_slirp_smb(const char *exported_dir)
bellard9d728e82004-09-05 23:09:03 +00004250{
4251 char smb_conf[1024];
4252 char smb_cmdline[1024];
4253 FILE *f;
4254
4255 if (!slirp_inited) {
4256 slirp_inited = 1;
4257 slirp_init();
4258 }
4259
4260 /* XXX: better tmp dir construction */
4261 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
4262 if (mkdir(smb_dir, 0700) < 0) {
4263 fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
4264 exit(1);
4265 }
4266 snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
ths3b46e622007-09-17 08:09:54 +00004267
bellard9d728e82004-09-05 23:09:03 +00004268 f = fopen(smb_conf, "w");
4269 if (!f) {
4270 fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
4271 exit(1);
4272 }
ths5fafdf22007-09-16 21:08:06 +00004273 fprintf(f,
bellard9d728e82004-09-05 23:09:03 +00004274 "[global]\n"
bellard157777e2005-03-01 21:28:45 +00004275 "private dir=%s\n"
4276 "smb ports=0\n"
4277 "socket address=127.0.0.1\n"
bellard9d728e82004-09-05 23:09:03 +00004278 "pid directory=%s\n"
4279 "lock directory=%s\n"
4280 "log file=%s/log.smbd\n"
4281 "smb passwd file=%s/smbpasswd\n"
bellard03ffbb62004-09-06 00:14:04 +00004282 "security = share\n"
bellard9d728e82004-09-05 23:09:03 +00004283 "[qemu]\n"
4284 "path=%s\n"
4285 "read only=no\n"
4286 "guest ok=yes\n",
4287 smb_dir,
4288 smb_dir,
4289 smb_dir,
4290 smb_dir,
bellard157777e2005-03-01 21:28:45 +00004291 smb_dir,
bellard9d728e82004-09-05 23:09:03 +00004292 exported_dir
4293 );
4294 fclose(f);
4295 atexit(smb_exit);
4296
pbrooka14d6c82006-12-23 15:37:33 +00004297 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
4298 SMBD_COMMAND, smb_conf);
ths3b46e622007-09-17 08:09:54 +00004299
bellard9d728e82004-09-05 23:09:03 +00004300 slirp_add_exec(0, smb_cmdline, 4, 139);
4301}
bellard9bf05442004-08-25 22:12:49 +00004302
bellardc94c8d62004-09-13 21:37:34 +00004303#endif /* !defined(_WIN32) */
blueswir131a60e22007-10-26 18:42:59 +00004304void do_info_slirp(void)
4305{
4306 slirp_stats();
4307}
bellardc94c8d62004-09-13 21:37:34 +00004308
bellardc20709a2004-04-21 23:27:19 +00004309#endif /* CONFIG_SLIRP */
4310
4311#if !defined(_WIN32)
bellard7c9d8e02005-11-15 22:16:05 +00004312
4313typedef struct TAPState {
4314 VLANClientState *vc;
4315 int fd;
thsb46a8902007-10-21 23:20:45 +00004316 char down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00004317} TAPState;
4318
4319static void tap_receive(void *opaque, const uint8_t *buf, int size)
4320{
4321 TAPState *s = opaque;
4322 int ret;
4323 for(;;) {
4324 ret = write(s->fd, buf, size);
4325 if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
4326 } else {
4327 break;
4328 }
4329 }
4330}
4331
4332static void tap_send(void *opaque)
4333{
4334 TAPState *s = opaque;
4335 uint8_t buf[4096];
4336 int size;
4337
thsd5d10bc2007-02-17 22:54:49 +00004338#ifdef __sun__
4339 struct strbuf sbuf;
4340 int f = 0;
4341 sbuf.maxlen = sizeof(buf);
4342 sbuf.buf = buf;
4343 size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
4344#else
bellard7c9d8e02005-11-15 22:16:05 +00004345 size = read(s->fd, buf, sizeof(buf));
thsd5d10bc2007-02-17 22:54:49 +00004346#endif
bellard7c9d8e02005-11-15 22:16:05 +00004347 if (size > 0) {
4348 qemu_send_packet(s->vc, buf, size);
4349 }
4350}
4351
4352/* fd support */
4353
4354static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
4355{
4356 TAPState *s;
4357
4358 s = qemu_mallocz(sizeof(TAPState));
4359 if (!s)
4360 return NULL;
4361 s->fd = fd;
pbrookd861b052006-02-04 22:15:28 +00004362 s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004363 qemu_set_fd_handler(s->fd, tap_send, NULL, s);
4364 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
4365 return s;
4366}
4367
ths5c40d2b2007-06-23 16:03:36 +00004368#if defined (_BSD) || defined (__FreeBSD_kernel__)
bellard7c9d8e02005-11-15 22:16:05 +00004369static int tap_open(char *ifname, int ifname_size)
bellard7d3505c2004-05-12 19:32:15 +00004370{
4371 int fd;
4372 char *dev;
4373 struct stat s;
bellard67b915a2004-03-31 23:37:16 +00004374
balrogaeb30be2007-07-02 15:03:13 +00004375 TFR(fd = open("/dev/tap", O_RDWR));
bellard7d3505c2004-05-12 19:32:15 +00004376 if (fd < 0) {
4377 fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
4378 return -1;
4379 }
4380
4381 fstat(fd, &s);
4382 dev = devname(s.st_rdev, S_IFCHR);
4383 pstrcpy(ifname, ifname_size, dev);
4384
4385 fcntl(fd, F_SETFL, O_NONBLOCK);
4386 return fd;
4387}
bellardec530c82006-04-25 22:36:06 +00004388#elif defined(__sun__)
thsd5d10bc2007-02-17 22:54:49 +00004389#define TUNNEWPPA (('T'<<16) | 0x0001)
ths5fafdf22007-09-16 21:08:06 +00004390/*
4391 * Allocate TAP device, returns opened fd.
thsd5d10bc2007-02-17 22:54:49 +00004392 * Stores dev name in the first arg(must be large enough).
ths3b46e622007-09-17 08:09:54 +00004393 */
blueswir1363a37d2008-08-21 17:58:08 +00004394int tap_alloc(char *dev, size_t dev_size)
thsd5d10bc2007-02-17 22:54:49 +00004395{
4396 int tap_fd, if_fd, ppa = -1;
4397 static int ip_fd = 0;
4398 char *ptr;
4399
4400 static int arp_fd = 0;
4401 int ip_muxid, arp_muxid;
4402 struct strioctl strioc_if, strioc_ppa;
4403 int link_type = I_PLINK;;
4404 struct lifreq ifr;
4405 char actual_name[32] = "";
4406
4407 memset(&ifr, 0x0, sizeof(ifr));
4408
4409 if( *dev ){
ths5fafdf22007-09-16 21:08:06 +00004410 ptr = dev;
4411 while( *ptr && !isdigit((int)*ptr) ) ptr++;
thsd5d10bc2007-02-17 22:54:49 +00004412 ppa = atoi(ptr);
4413 }
4414
4415 /* Check if IP device was opened */
4416 if( ip_fd )
4417 close(ip_fd);
4418
balrogaeb30be2007-07-02 15:03:13 +00004419 TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
4420 if (ip_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004421 syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
4422 return -1;
4423 }
4424
balrogaeb30be2007-07-02 15:03:13 +00004425 TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
4426 if (tap_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004427 syslog(LOG_ERR, "Can't open /dev/tap");
4428 return -1;
4429 }
4430
4431 /* Assign a new PPA and get its unit number. */
4432 strioc_ppa.ic_cmd = TUNNEWPPA;
4433 strioc_ppa.ic_timout = 0;
4434 strioc_ppa.ic_len = sizeof(ppa);
4435 strioc_ppa.ic_dp = (char *)&ppa;
4436 if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
4437 syslog (LOG_ERR, "Can't assign new interface");
4438
balrogaeb30be2007-07-02 15:03:13 +00004439 TFR(if_fd = open("/dev/tap", O_RDWR, 0));
4440 if (if_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004441 syslog(LOG_ERR, "Can't open /dev/tap (2)");
4442 return -1;
4443 }
4444 if(ioctl(if_fd, I_PUSH, "ip") < 0){
4445 syslog(LOG_ERR, "Can't push IP module");
4446 return -1;
4447 }
4448
4449 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
4450 syslog(LOG_ERR, "Can't get flags\n");
4451
4452 snprintf (actual_name, 32, "tap%d", ppa);
4453 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4454
4455 ifr.lifr_ppa = ppa;
4456 /* Assign ppa according to the unit number returned by tun device */
4457
4458 if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
4459 syslog (LOG_ERR, "Can't set PPA %d", ppa);
4460 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
4461 syslog (LOG_ERR, "Can't get flags\n");
4462 /* Push arp module to if_fd */
4463 if (ioctl (if_fd, I_PUSH, "arp") < 0)
4464 syslog (LOG_ERR, "Can't push ARP module (2)");
4465
4466 /* Push arp module to ip_fd */
4467 if (ioctl (ip_fd, I_POP, NULL) < 0)
4468 syslog (LOG_ERR, "I_POP failed\n");
4469 if (ioctl (ip_fd, I_PUSH, "arp") < 0)
4470 syslog (LOG_ERR, "Can't push ARP module (3)\n");
4471 /* Open arp_fd */
balrogaeb30be2007-07-02 15:03:13 +00004472 TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
4473 if (arp_fd < 0)
thsd5d10bc2007-02-17 22:54:49 +00004474 syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
4475
4476 /* Set ifname to arp */
4477 strioc_if.ic_cmd = SIOCSLIFNAME;
4478 strioc_if.ic_timout = 0;
4479 strioc_if.ic_len = sizeof(ifr);
4480 strioc_if.ic_dp = (char *)&ifr;
4481 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
4482 syslog (LOG_ERR, "Can't set ifname to arp\n");
4483 }
4484
4485 if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
4486 syslog(LOG_ERR, "Can't link TAP device to IP");
4487 return -1;
4488 }
4489
4490 if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
4491 syslog (LOG_ERR, "Can't link TAP device to ARP");
4492
4493 close (if_fd);
4494
4495 memset(&ifr, 0x0, sizeof(ifr));
4496 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4497 ifr.lifr_ip_muxid = ip_muxid;
4498 ifr.lifr_arp_muxid = arp_muxid;
4499
4500 if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
4501 {
4502 ioctl (ip_fd, I_PUNLINK , arp_muxid);
4503 ioctl (ip_fd, I_PUNLINK, ip_muxid);
4504 syslog (LOG_ERR, "Can't set multiplexor id");
4505 }
4506
blueswir1363a37d2008-08-21 17:58:08 +00004507 snprintf(dev, dev_size, "tap%d", ppa);
thsd5d10bc2007-02-17 22:54:49 +00004508 return tap_fd;
4509}
4510
bellardec530c82006-04-25 22:36:06 +00004511static int tap_open(char *ifname, int ifname_size)
4512{
thsd5d10bc2007-02-17 22:54:49 +00004513 char dev[10]="";
4514 int fd;
blueswir1363a37d2008-08-21 17:58:08 +00004515 if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
thsd5d10bc2007-02-17 22:54:49 +00004516 fprintf(stderr, "Cannot allocate TAP device\n");
4517 return -1;
4518 }
4519 pstrcpy(ifname, ifname_size, dev);
4520 fcntl(fd, F_SETFL, O_NONBLOCK);
4521 return fd;
bellardec530c82006-04-25 22:36:06 +00004522}
bellard7d3505c2004-05-12 19:32:15 +00004523#else
bellard7c9d8e02005-11-15 22:16:05 +00004524static int tap_open(char *ifname, int ifname_size)
bellardf1510b22003-06-25 00:07:40 +00004525{
4526 struct ifreq ifr;
bellardc4b1fcc2004-03-14 21:44:30 +00004527 int fd, ret;
ths3b46e622007-09-17 08:09:54 +00004528
balrogaeb30be2007-07-02 15:03:13 +00004529 TFR(fd = open("/dev/net/tun", O_RDWR));
bellardf1510b22003-06-25 00:07:40 +00004530 if (fd < 0) {
4531 fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4532 return -1;
4533 }
4534 memset(&ifr, 0, sizeof(ifr));
4535 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
bellard7c9d8e02005-11-15 22:16:05 +00004536 if (ifname[0] != '\0')
4537 pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4538 else
4539 pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
bellardf1510b22003-06-25 00:07:40 +00004540 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4541 if (ret != 0) {
4542 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4543 close(fd);
4544 return -1;
4545 }
bellardc4b1fcc2004-03-14 21:44:30 +00004546 pstrcpy(ifname, ifname_size, ifr.ifr_name);
bellardf1510b22003-06-25 00:07:40 +00004547 fcntl(fd, F_SETFL, O_NONBLOCK);
bellardc4b1fcc2004-03-14 21:44:30 +00004548 return fd;
4549}
bellard7d3505c2004-05-12 19:32:15 +00004550#endif
bellardf1510b22003-06-25 00:07:40 +00004551
thsb46a8902007-10-21 23:20:45 +00004552static int launch_script(const char *setup_script, const char *ifname, int fd)
bellardc4b1fcc2004-03-14 21:44:30 +00004553{
thsb46a8902007-10-21 23:20:45 +00004554 int pid, status;
bellardc20709a2004-04-21 23:27:19 +00004555 char *args[3];
4556 char **parg;
4557
thsb46a8902007-10-21 23:20:45 +00004558 /* try to launch network script */
bellard7c9d8e02005-11-15 22:16:05 +00004559 pid = fork();
4560 if (pid >= 0) {
4561 if (pid == 0) {
ths50d3eea2007-03-19 16:36:43 +00004562 int open_max = sysconf (_SC_OPEN_MAX), i;
4563 for (i = 0; i < open_max; i++)
4564 if (i != STDIN_FILENO &&
4565 i != STDOUT_FILENO &&
4566 i != STDERR_FILENO &&
4567 i != fd)
4568 close(i);
4569
bellard7c9d8e02005-11-15 22:16:05 +00004570 parg = args;
4571 *parg++ = (char *)setup_script;
thsb46a8902007-10-21 23:20:45 +00004572 *parg++ = (char *)ifname;
bellard7c9d8e02005-11-15 22:16:05 +00004573 *parg++ = NULL;
4574 execv(setup_script, args);
bellard4a389402005-11-26 20:10:07 +00004575 _exit(1);
bellard7c9d8e02005-11-15 22:16:05 +00004576 }
4577 while (waitpid(pid, &status, 0) != pid);
4578 if (!WIFEXITED(status) ||
4579 WEXITSTATUS(status) != 0) {
4580 fprintf(stderr, "%s: could not launch network script\n",
4581 setup_script);
4582 return -1;
4583 }
bellardc20709a2004-04-21 23:27:19 +00004584 }
thsb46a8902007-10-21 23:20:45 +00004585 return 0;
4586}
4587
4588static int net_tap_init(VLANState *vlan, const char *ifname1,
4589 const char *setup_script, const char *down_script)
4590{
4591 TAPState *s;
4592 int fd;
4593 char ifname[128];
4594
4595 if (ifname1 != NULL)
4596 pstrcpy(ifname, sizeof(ifname), ifname1);
4597 else
4598 ifname[0] = '\0';
4599 TFR(fd = tap_open(ifname, sizeof(ifname)));
4600 if (fd < 0)
4601 return -1;
4602
4603 if (!setup_script || !strcmp(setup_script, "no"))
4604 setup_script = "";
4605 if (setup_script[0] != '\0') {
4606 if (launch_script(setup_script, ifname, fd))
4607 return -1;
bellardc20709a2004-04-21 23:27:19 +00004608 }
bellard7c9d8e02005-11-15 22:16:05 +00004609 s = net_tap_fd_init(vlan, fd);
4610 if (!s)
4611 return -1;
ths5fafdf22007-09-16 21:08:06 +00004612 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
bellard7c9d8e02005-11-15 22:16:05 +00004613 "tap: ifname=%s setup_script=%s", ifname, setup_script);
thsb46a8902007-10-21 23:20:45 +00004614 if (down_script && strcmp(down_script, "no"))
4615 snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
bellardc20709a2004-04-21 23:27:19 +00004616 return 0;
4617}
4618
bellardfd1dff42006-02-01 21:29:26 +00004619#endif /* !_WIN32 */
4620
ths8a16d272008-07-19 09:56:24 +00004621#if defined(CONFIG_VDE)
4622typedef struct VDEState {
4623 VLANClientState *vc;
4624 VDECONN *vde;
4625} VDEState;
4626
4627static void vde_to_qemu(void *opaque)
4628{
4629 VDEState *s = opaque;
4630 uint8_t buf[4096];
4631 int size;
4632
4633 size = vde_recv(s->vde, buf, sizeof(buf), 0);
4634 if (size > 0) {
4635 qemu_send_packet(s->vc, buf, size);
4636 }
4637}
4638
4639static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
4640{
4641 VDEState *s = opaque;
4642 int ret;
4643 for(;;) {
4644 ret = vde_send(s->vde, buf, size, 0);
4645 if (ret < 0 && errno == EINTR) {
4646 } else {
4647 break;
4648 }
4649 }
4650}
4651
4652static int net_vde_init(VLANState *vlan, const char *sock, int port,
4653 const char *group, int mode)
4654{
4655 VDEState *s;
4656 char *init_group = strlen(group) ? (char *)group : NULL;
4657 char *init_sock = strlen(sock) ? (char *)sock : NULL;
4658
4659 struct vde_open_args args = {
4660 .port = port,
4661 .group = init_group,
4662 .mode = mode,
4663 };
4664
4665 s = qemu_mallocz(sizeof(VDEState));
4666 if (!s)
4667 return -1;
4668 s->vde = vde_open(init_sock, "QEMU", &args);
4669 if (!s->vde){
4670 free(s);
4671 return -1;
4672 }
4673 s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
4674 qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
4675 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
4676 sock, vde_datafd(s->vde));
4677 return 0;
4678}
4679#endif
4680
bellard7c9d8e02005-11-15 22:16:05 +00004681/* network connection */
4682typedef struct NetSocketState {
4683 VLANClientState *vc;
4684 int fd;
4685 int state; /* 0 = getting length, 1 = getting data */
4686 int index;
4687 int packet_len;
4688 uint8_t buf[4096];
bellard3d830452005-12-18 16:36:49 +00004689 struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
bellard7c9d8e02005-11-15 22:16:05 +00004690} NetSocketState;
4691
4692typedef struct NetSocketListenState {
4693 VLANState *vlan;
4694 int fd;
4695} NetSocketListenState;
4696
4697/* XXX: we consider we can send the whole packet without blocking */
4698static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
bellardc20709a2004-04-21 23:27:19 +00004699{
bellard7c9d8e02005-11-15 22:16:05 +00004700 NetSocketState *s = opaque;
4701 uint32_t len;
4702 len = htonl(size);
4703
bellardfd1dff42006-02-01 21:29:26 +00004704 send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4705 send_all(s->fd, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00004706}
4707
bellard3d830452005-12-18 16:36:49 +00004708static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4709{
4710 NetSocketState *s = opaque;
ths5fafdf22007-09-16 21:08:06 +00004711 sendto(s->fd, buf, size, 0,
bellard3d830452005-12-18 16:36:49 +00004712 (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4713}
4714
bellard7c9d8e02005-11-15 22:16:05 +00004715static void net_socket_send(void *opaque)
4716{
4717 NetSocketState *s = opaque;
bellardfd1dff42006-02-01 21:29:26 +00004718 int l, size, err;
bellard7c9d8e02005-11-15 22:16:05 +00004719 uint8_t buf1[4096];
4720 const uint8_t *buf;
4721
bellardfd1dff42006-02-01 21:29:26 +00004722 size = recv(s->fd, buf1, sizeof(buf1), 0);
4723 if (size < 0) {
4724 err = socket_error();
ths5fafdf22007-09-16 21:08:06 +00004725 if (err != EWOULDBLOCK)
bellardfd1dff42006-02-01 21:29:26 +00004726 goto eoc;
4727 } else if (size == 0) {
bellard7c9d8e02005-11-15 22:16:05 +00004728 /* end of connection */
bellardfd1dff42006-02-01 21:29:26 +00004729 eoc:
bellard7c9d8e02005-11-15 22:16:05 +00004730 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
bellardfd1dff42006-02-01 21:29:26 +00004731 closesocket(s->fd);
bellard7c9d8e02005-11-15 22:16:05 +00004732 return;
4733 }
4734 buf = buf1;
4735 while (size > 0) {
4736 /* reassemble a packet from the network */
4737 switch(s->state) {
4738 case 0:
4739 l = 4 - s->index;
4740 if (l > size)
4741 l = size;
4742 memcpy(s->buf + s->index, buf, l);
4743 buf += l;
4744 size -= l;
4745 s->index += l;
4746 if (s->index == 4) {
4747 /* got length */
4748 s->packet_len = ntohl(*(uint32_t *)s->buf);
4749 s->index = 0;
4750 s->state = 1;
4751 }
4752 break;
4753 case 1:
4754 l = s->packet_len - s->index;
4755 if (l > size)
4756 l = size;
4757 memcpy(s->buf + s->index, buf, l);
4758 s->index += l;
4759 buf += l;
4760 size -= l;
4761 if (s->index >= s->packet_len) {
4762 qemu_send_packet(s->vc, s->buf, s->packet_len);
4763 s->index = 0;
4764 s->state = 0;
4765 }
4766 break;
4767 }
4768 }
4769}
4770
bellard3d830452005-12-18 16:36:49 +00004771static void net_socket_send_dgram(void *opaque)
4772{
4773 NetSocketState *s = opaque;
4774 int size;
4775
4776 size = recv(s->fd, s->buf, sizeof(s->buf), 0);
ths5fafdf22007-09-16 21:08:06 +00004777 if (size < 0)
bellard3d830452005-12-18 16:36:49 +00004778 return;
4779 if (size == 0) {
4780 /* end of connection */
4781 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4782 return;
4783 }
4784 qemu_send_packet(s->vc, s->buf, size);
4785}
4786
4787static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4788{
4789 struct ip_mreq imr;
4790 int fd;
4791 int val, ret;
4792 if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4793 fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
ths5fafdf22007-09-16 21:08:06 +00004794 inet_ntoa(mcastaddr->sin_addr),
bellardfd1dff42006-02-01 21:29:26 +00004795 (int)ntohl(mcastaddr->sin_addr.s_addr));
bellard3d830452005-12-18 16:36:49 +00004796 return -1;
4797
4798 }
4799 fd = socket(PF_INET, SOCK_DGRAM, 0);
4800 if (fd < 0) {
4801 perror("socket(PF_INET, SOCK_DGRAM)");
4802 return -1;
4803 }
4804
bellardfd1dff42006-02-01 21:29:26 +00004805 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004806 ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
bellardfd1dff42006-02-01 21:29:26 +00004807 (const char *)&val, sizeof(val));
4808 if (ret < 0) {
4809 perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4810 goto fail;
4811 }
4812
4813 ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4814 if (ret < 0) {
4815 perror("bind");
4816 goto fail;
4817 }
ths3b46e622007-09-17 08:09:54 +00004818
bellard3d830452005-12-18 16:36:49 +00004819 /* Add host to multicast group */
4820 imr.imr_multiaddr = mcastaddr->sin_addr;
4821 imr.imr_interface.s_addr = htonl(INADDR_ANY);
4822
ths5fafdf22007-09-16 21:08:06 +00004823 ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
bellardfd1dff42006-02-01 21:29:26 +00004824 (const char *)&imr, sizeof(struct ip_mreq));
bellard3d830452005-12-18 16:36:49 +00004825 if (ret < 0) {
4826 perror("setsockopt(IP_ADD_MEMBERSHIP)");
4827 goto fail;
4828 }
4829
4830 /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4831 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004832 ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
bellardfd1dff42006-02-01 21:29:26 +00004833 (const char *)&val, sizeof(val));
bellard3d830452005-12-18 16:36:49 +00004834 if (ret < 0) {
4835 perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4836 goto fail;
4837 }
4838
bellardfd1dff42006-02-01 21:29:26 +00004839 socket_set_nonblock(fd);
bellard3d830452005-12-18 16:36:49 +00004840 return fd;
4841fail:
ths5fafdf22007-09-16 21:08:06 +00004842 if (fd >= 0)
bellard0bab00f2006-06-25 14:49:44 +00004843 closesocket(fd);
bellard3d830452005-12-18 16:36:49 +00004844 return -1;
4845}
4846
ths5fafdf22007-09-16 21:08:06 +00004847static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004848 int is_connected)
4849{
4850 struct sockaddr_in saddr;
4851 int newfd;
4852 socklen_t saddr_len;
4853 NetSocketState *s;
4854
4855 /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
ths5fafdf22007-09-16 21:08:06 +00004856 * Because this may be "shared" socket from a "master" process, datagrams would be recv()
bellard3d830452005-12-18 16:36:49 +00004857 * by ONLY ONE process: we must "clone" this dgram socket --jjo
4858 */
4859
4860 if (is_connected) {
4861 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4862 /* must be bound */
4863 if (saddr.sin_addr.s_addr==0) {
4864 fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4865 fd);
4866 return NULL;
4867 }
4868 /* clone dgram socket */
4869 newfd = net_socket_mcast_create(&saddr);
4870 if (newfd < 0) {
4871 /* error already reported by net_socket_mcast_create() */
4872 close(fd);
4873 return NULL;
4874 }
4875 /* clone newfd to fd, close newfd */
4876 dup2(newfd, fd);
4877 close(newfd);
ths5fafdf22007-09-16 21:08:06 +00004878
bellard3d830452005-12-18 16:36:49 +00004879 } else {
4880 fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4881 fd, strerror(errno));
4882 return NULL;
4883 }
4884 }
4885
4886 s = qemu_mallocz(sizeof(NetSocketState));
4887 if (!s)
4888 return NULL;
4889 s->fd = fd;
4890
pbrookd861b052006-02-04 22:15:28 +00004891 s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
bellard3d830452005-12-18 16:36:49 +00004892 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4893
4894 /* mcast: save bound address as dst */
4895 if (is_connected) s->dgram_dst=saddr;
4896
4897 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004898 "socket: fd=%d (%s mcast=%s:%d)",
bellard3d830452005-12-18 16:36:49 +00004899 fd, is_connected? "cloned" : "",
4900 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4901 return s;
4902}
4903
bellard7c9d8e02005-11-15 22:16:05 +00004904static void net_socket_connect(void *opaque)
4905{
4906 NetSocketState *s = opaque;
4907 qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4908}
4909
ths5fafdf22007-09-16 21:08:06 +00004910static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
bellard7c9d8e02005-11-15 22:16:05 +00004911 int is_connected)
4912{
4913 NetSocketState *s;
4914 s = qemu_mallocz(sizeof(NetSocketState));
4915 if (!s)
4916 return NULL;
4917 s->fd = fd;
ths5fafdf22007-09-16 21:08:06 +00004918 s->vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00004919 net_socket_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004920 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4921 "socket: fd=%d", fd);
4922 if (is_connected) {
4923 net_socket_connect(s);
4924 } else {
4925 qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4926 }
4927 return s;
4928}
4929
ths5fafdf22007-09-16 21:08:06 +00004930static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004931 int is_connected)
4932{
4933 int so_type=-1, optlen=sizeof(so_type);
4934
ths69b34972007-12-17 03:15:52 +00004935 if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
4936 (socklen_t *)&optlen)< 0) {
ths931f03e2007-04-28 20:49:36 +00004937 fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
bellard3d830452005-12-18 16:36:49 +00004938 return NULL;
4939 }
4940 switch(so_type) {
4941 case SOCK_DGRAM:
4942 return net_socket_fd_init_dgram(vlan, fd, is_connected);
4943 case SOCK_STREAM:
4944 return net_socket_fd_init_stream(vlan, fd, is_connected);
4945 default:
4946 /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4947 fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4948 return net_socket_fd_init_stream(vlan, fd, is_connected);
4949 }
4950 return NULL;
4951}
4952
bellard7c9d8e02005-11-15 22:16:05 +00004953static void net_socket_accept(void *opaque)
4954{
ths3b46e622007-09-17 08:09:54 +00004955 NetSocketListenState *s = opaque;
bellard7c9d8e02005-11-15 22:16:05 +00004956 NetSocketState *s1;
4957 struct sockaddr_in saddr;
4958 socklen_t len;
4959 int fd;
4960
4961 for(;;) {
4962 len = sizeof(saddr);
4963 fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4964 if (fd < 0 && errno != EINTR) {
4965 return;
4966 } else if (fd >= 0) {
4967 break;
4968 }
4969 }
ths5fafdf22007-09-16 21:08:06 +00004970 s1 = net_socket_fd_init(s->vlan, fd, 1);
bellard7c9d8e02005-11-15 22:16:05 +00004971 if (!s1) {
bellard0bab00f2006-06-25 14:49:44 +00004972 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004973 } else {
4974 snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004975 "socket: connection from %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00004976 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4977 }
4978}
4979
4980static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4981{
4982 NetSocketListenState *s;
4983 int fd, val, ret;
4984 struct sockaddr_in saddr;
4985
4986 if (parse_host_port(&saddr, host_str) < 0)
4987 return -1;
ths3b46e622007-09-17 08:09:54 +00004988
bellard7c9d8e02005-11-15 22:16:05 +00004989 s = qemu_mallocz(sizeof(NetSocketListenState));
4990 if (!s)
4991 return -1;
4992
4993 fd = socket(PF_INET, SOCK_STREAM, 0);
4994 if (fd < 0) {
4995 perror("socket");
4996 return -1;
4997 }
bellardfd1dff42006-02-01 21:29:26 +00004998 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004999
5000 /* allow fast reuse */
5001 val = 1;
bellardfd1dff42006-02-01 21:29:26 +00005002 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
ths3b46e622007-09-17 08:09:54 +00005003
bellard7c9d8e02005-11-15 22:16:05 +00005004 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
5005 if (ret < 0) {
5006 perror("bind");
5007 return -1;
5008 }
5009 ret = listen(fd, 0);
5010 if (ret < 0) {
5011 perror("listen");
5012 return -1;
5013 }
5014 s->vlan = vlan;
5015 s->fd = fd;
5016 qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
5017 return 0;
5018}
5019
5020static int net_socket_connect_init(VLANState *vlan, const char *host_str)
5021{
5022 NetSocketState *s;
bellardfd1dff42006-02-01 21:29:26 +00005023 int fd, connected, ret, err;
bellard7c9d8e02005-11-15 22:16:05 +00005024 struct sockaddr_in saddr;
5025
5026 if (parse_host_port(&saddr, host_str) < 0)
5027 return -1;
5028
5029 fd = socket(PF_INET, SOCK_STREAM, 0);
5030 if (fd < 0) {
5031 perror("socket");
5032 return -1;
5033 }
bellardfd1dff42006-02-01 21:29:26 +00005034 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00005035
5036 connected = 0;
5037 for(;;) {
5038 ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
5039 if (ret < 0) {
bellardfd1dff42006-02-01 21:29:26 +00005040 err = socket_error();
5041 if (err == EINTR || err == EWOULDBLOCK) {
5042 } else if (err == EINPROGRESS) {
bellard7c9d8e02005-11-15 22:16:05 +00005043 break;
thsf5b12262007-03-25 15:58:03 +00005044#ifdef _WIN32
5045 } else if (err == WSAEALREADY) {
5046 break;
5047#endif
bellard7c9d8e02005-11-15 22:16:05 +00005048 } else {
5049 perror("connect");
bellardfd1dff42006-02-01 21:29:26 +00005050 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00005051 return -1;
5052 }
5053 } else {
5054 connected = 1;
5055 break;
5056 }
5057 }
5058 s = net_socket_fd_init(vlan, fd, connected);
5059 if (!s)
5060 return -1;
5061 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00005062 "socket: connect to %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00005063 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
bellardc20709a2004-04-21 23:27:19 +00005064 return 0;
5065}
5066
bellard3d830452005-12-18 16:36:49 +00005067static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
5068{
5069 NetSocketState *s;
5070 int fd;
5071 struct sockaddr_in saddr;
5072
5073 if (parse_host_port(&saddr, host_str) < 0)
5074 return -1;
5075
5076
5077 fd = net_socket_mcast_create(&saddr);
5078 if (fd < 0)
5079 return -1;
5080
5081 s = net_socket_fd_init(vlan, fd, 0);
5082 if (!s)
5083 return -1;
5084
5085 s->dgram_dst = saddr;
ths3b46e622007-09-17 08:09:54 +00005086
bellard3d830452005-12-18 16:36:49 +00005087 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00005088 "socket: mcast=%s:%d",
bellard3d830452005-12-18 16:36:49 +00005089 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
5090 return 0;
5091
5092}
5093
balrog609497a2008-01-14 02:56:53 +00005094static const char *get_opt_name(char *buf, int buf_size, const char *p)
thse4bcb142007-12-02 04:51:10 +00005095{
5096 char *q;
thse4bcb142007-12-02 04:51:10 +00005097
balrog609497a2008-01-14 02:56:53 +00005098 q = buf;
5099 while (*p != '\0' && *p != '=') {
5100 if (q && (q - buf) < buf_size - 1)
5101 *q++ = *p;
5102 p++;
5103 }
5104 if (q)
5105 *q = '\0';
5106
5107 return p;
5108}
5109
5110static const char *get_opt_value(char *buf, int buf_size, const char *p)
5111{
5112 char *q;
5113
thse4bcb142007-12-02 04:51:10 +00005114 q = buf;
5115 while (*p != '\0') {
balrog609497a2008-01-14 02:56:53 +00005116 if (*p == ',') {
5117 if (*(p + 1) != ',')
thse4bcb142007-12-02 04:51:10 +00005118 break;
thse4bcb142007-12-02 04:51:10 +00005119 p++;
balrog609497a2008-01-14 02:56:53 +00005120 }
thse4bcb142007-12-02 04:51:10 +00005121 if (q && (q - buf) < buf_size - 1)
5122 *q++ = *p;
5123 p++;
5124 }
5125 if (q)
5126 *q = '\0';
5127
5128 return p;
5129}
5130
bellard7c9d8e02005-11-15 22:16:05 +00005131static int get_param_value(char *buf, int buf_size,
5132 const char *tag, const char *str)
5133{
5134 const char *p;
bellard7c9d8e02005-11-15 22:16:05 +00005135 char option[128];
5136
5137 p = str;
5138 for(;;) {
balrog609497a2008-01-14 02:56:53 +00005139 p = get_opt_name(option, sizeof(option), p);
bellard7c9d8e02005-11-15 22:16:05 +00005140 if (*p != '=')
5141 break;
5142 p++;
5143 if (!strcmp(tag, option)) {
balrog609497a2008-01-14 02:56:53 +00005144 (void)get_opt_value(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00005145 return strlen(buf);
bellard7c9d8e02005-11-15 22:16:05 +00005146 } else {
balrog609497a2008-01-14 02:56:53 +00005147 p = get_opt_value(NULL, 0, p);
bellard7c9d8e02005-11-15 22:16:05 +00005148 }
5149 if (*p != ',')
5150 break;
5151 p++;
5152 }
5153 return 0;
5154}
5155
thse4bcb142007-12-02 04:51:10 +00005156static int check_params(char *buf, int buf_size,
blueswir17ccfb2e2008-09-14 06:45:34 +00005157 const char * const *params, const char *str)
thse4bcb142007-12-02 04:51:10 +00005158{
5159 const char *p;
5160 int i;
5161
5162 p = str;
5163 for(;;) {
balrog609497a2008-01-14 02:56:53 +00005164 p = get_opt_name(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00005165 if (*p != '=')
5166 return -1;
5167 p++;
5168 for(i = 0; params[i] != NULL; i++)
5169 if (!strcmp(params[i], buf))
5170 break;
5171 if (params[i] == NULL)
5172 return -1;
balrog609497a2008-01-14 02:56:53 +00005173 p = get_opt_value(NULL, 0, p);
thse4bcb142007-12-02 04:51:10 +00005174 if (*p != ',')
5175 break;
5176 p++;
5177 }
5178 return 0;
5179}
5180
balrog9ad97e62008-07-29 13:16:31 +00005181static int net_client_init(const char *device, const char *p)
bellard7c9d8e02005-11-15 22:16:05 +00005182{
bellard7c9d8e02005-11-15 22:16:05 +00005183 char buf[1024];
5184 int vlan_id, ret;
5185 VLANState *vlan;
5186
bellard7c9d8e02005-11-15 22:16:05 +00005187 vlan_id = 0;
5188 if (get_param_value(buf, sizeof(buf), "vlan", p)) {
5189 vlan_id = strtol(buf, NULL, 0);
5190 }
5191 vlan = qemu_find_vlan(vlan_id);
5192 if (!vlan) {
5193 fprintf(stderr, "Could not create vlan %d\n", vlan_id);
5194 return -1;
5195 }
5196 if (!strcmp(device, "nic")) {
5197 NICInfo *nd;
5198 uint8_t *macaddr;
5199
5200 if (nb_nics >= MAX_NICS) {
5201 fprintf(stderr, "Too Many NICs\n");
5202 return -1;
5203 }
5204 nd = &nd_table[nb_nics];
5205 macaddr = nd->macaddr;
5206 macaddr[0] = 0x52;
5207 macaddr[1] = 0x54;
5208 macaddr[2] = 0x00;
5209 macaddr[3] = 0x12;
5210 macaddr[4] = 0x34;
5211 macaddr[5] = 0x56 + nb_nics;
5212
5213 if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
5214 if (parse_macaddr(macaddr, buf) < 0) {
5215 fprintf(stderr, "invalid syntax for ethernet address\n");
5216 return -1;
5217 }
5218 }
pbrooka41b2ff2006-02-05 04:14:41 +00005219 if (get_param_value(buf, sizeof(buf), "model", p)) {
5220 nd->model = strdup(buf);
5221 }
bellard7c9d8e02005-11-15 22:16:05 +00005222 nd->vlan = vlan;
5223 nb_nics++;
blueswir1833c7172007-05-27 19:36:43 +00005224 vlan->nb_guest_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005225 ret = 0;
5226 } else
5227 if (!strcmp(device, "none")) {
5228 /* does nothing. It is needed to signal that no network cards
5229 are wanted */
5230 ret = 0;
5231 } else
5232#ifdef CONFIG_SLIRP
5233 if (!strcmp(device, "user")) {
pbrook115defd2006-04-16 11:06:58 +00005234 if (get_param_value(buf, sizeof(buf), "hostname", p)) {
bellard3f423c92006-04-30 21:34:15 +00005235 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
pbrook115defd2006-04-16 11:06:58 +00005236 }
blueswir1833c7172007-05-27 19:36:43 +00005237 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005238 ret = net_slirp_init(vlan);
5239 } else
5240#endif
bellard7fb843f2006-02-01 23:06:55 +00005241#ifdef _WIN32
5242 if (!strcmp(device, "tap")) {
5243 char ifname[64];
5244 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
5245 fprintf(stderr, "tap: no interface name\n");
5246 return -1;
5247 }
blueswir1833c7172007-05-27 19:36:43 +00005248 vlan->nb_host_devs++;
bellard7fb843f2006-02-01 23:06:55 +00005249 ret = tap_win32_init(vlan, ifname);
5250 } else
5251#else
bellard7c9d8e02005-11-15 22:16:05 +00005252 if (!strcmp(device, "tap")) {
5253 char ifname[64];
thsb46a8902007-10-21 23:20:45 +00005254 char setup_script[1024], down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00005255 int fd;
pbrook4f010352007-05-28 02:29:59 +00005256 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005257 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
5258 fd = strtol(buf, NULL, 0);
pbrook64538cd2008-03-24 02:31:33 +00005259 fcntl(fd, F_SETFL, O_NONBLOCK);
bellard7c9d8e02005-11-15 22:16:05 +00005260 ret = -1;
5261 if (net_tap_fd_init(vlan, fd))
5262 ret = 0;
5263 } else {
bellardbf8c5342007-01-09 19:44:41 +00005264 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
5265 ifname[0] = '\0';
5266 }
bellard7c9d8e02005-11-15 22:16:05 +00005267 if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
5268 pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
5269 }
thsb46a8902007-10-21 23:20:45 +00005270 if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
5271 pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
5272 }
5273 ret = net_tap_init(vlan, ifname, setup_script, down_script);
bellard7c9d8e02005-11-15 22:16:05 +00005274 }
5275 } else
bellardfd1dff42006-02-01 21:29:26 +00005276#endif
bellard7c9d8e02005-11-15 22:16:05 +00005277 if (!strcmp(device, "socket")) {
5278 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
5279 int fd;
5280 fd = strtol(buf, NULL, 0);
5281 ret = -1;
5282 if (net_socket_fd_init(vlan, fd, 1))
5283 ret = 0;
5284 } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
5285 ret = net_socket_listen_init(vlan, buf);
5286 } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
5287 ret = net_socket_connect_init(vlan, buf);
bellard3d830452005-12-18 16:36:49 +00005288 } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
5289 ret = net_socket_mcast_init(vlan, buf);
bellard7c9d8e02005-11-15 22:16:05 +00005290 } else {
5291 fprintf(stderr, "Unknown socket options: %s\n", p);
5292 return -1;
5293 }
blueswir1833c7172007-05-27 19:36:43 +00005294 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005295 } else
ths8a16d272008-07-19 09:56:24 +00005296#ifdef CONFIG_VDE
5297 if (!strcmp(device, "vde")) {
5298 char vde_sock[1024], vde_group[512];
5299 int vde_port, vde_mode;
5300 vlan->nb_host_devs++;
5301 if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
5302 vde_sock[0] = '\0';
5303 }
5304 if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
5305 vde_port = strtol(buf, NULL, 10);
5306 } else {
5307 vde_port = 0;
5308 }
5309 if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
5310 vde_group[0] = '\0';
5311 }
5312 if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
5313 vde_mode = strtol(buf, NULL, 8);
5314 } else {
5315 vde_mode = 0700;
5316 }
5317 ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
5318 } else
5319#endif
bellard7c9d8e02005-11-15 22:16:05 +00005320 {
5321 fprintf(stderr, "Unknown network device: %s\n", device);
5322 return -1;
5323 }
5324 if (ret < 0) {
5325 fprintf(stderr, "Could not initialize device '%s'\n", device);
5326 }
ths3b46e622007-09-17 08:09:54 +00005327
bellard7c9d8e02005-11-15 22:16:05 +00005328 return ret;
5329}
5330
balrog9ad97e62008-07-29 13:16:31 +00005331static int net_client_parse(const char *str)
5332{
5333 const char *p;
5334 char *q;
5335 char device[64];
5336
5337 p = str;
5338 q = device;
5339 while (*p != '\0' && *p != ',') {
5340 if ((q - device) < sizeof(device) - 1)
5341 *q++ = *p;
5342 p++;
5343 }
5344 *q = '\0';
5345 if (*p == ',')
5346 p++;
5347
5348 return net_client_init(device, p);
5349}
5350
bellard7c9d8e02005-11-15 22:16:05 +00005351void do_info_network(void)
5352{
5353 VLANState *vlan;
5354 VLANClientState *vc;
5355
5356 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
5357 term_printf("VLAN %d devices:\n", vlan->id);
5358 for(vc = vlan->first_client; vc != NULL; vc = vc->next)
5359 term_printf(" %s\n", vc->info_str);
5360 }
5361}
ths42550fd2006-12-22 16:34:12 +00005362
balrog609497a2008-01-14 02:56:53 +00005363#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00005364#ifdef TARGET_PPC
5365#define CDROM_ALIAS "index=1,media=cdrom"
5366#else
5367#define CDROM_ALIAS "index=2,media=cdrom"
5368#endif
5369#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00005370#define PFLASH_ALIAS "if=pflash"
5371#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00005372#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00005373
balrog609497a2008-01-14 02:56:53 +00005374static int drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00005375{
5376 va_list ap;
5377
5378 if (nb_drives_opt >= MAX_DRIVES) {
5379 fprintf(stderr, "qemu: too many drives\n");
5380 exit(1);
5381 }
5382
balrog609497a2008-01-14 02:56:53 +00005383 drives_opt[nb_drives_opt].file = file;
thse4bcb142007-12-02 04:51:10 +00005384 va_start(ap, fmt);
balrog609497a2008-01-14 02:56:53 +00005385 vsnprintf(drives_opt[nb_drives_opt].opt,
5386 sizeof(drives_opt[0].opt), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00005387 va_end(ap);
5388
5389 return nb_drives_opt++;
5390}
5391
thsf60d39b2007-12-17 03:55:57 +00005392int drive_get_index(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00005393{
5394 int index;
5395
5396 /* seek interface, bus and unit */
5397
5398 for (index = 0; index < nb_drives; index++)
thsf60d39b2007-12-17 03:55:57 +00005399 if (drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005400 drives_table[index].bus == bus &&
5401 drives_table[index].unit == unit)
5402 return index;
5403
5404 return -1;
5405}
5406
thsf60d39b2007-12-17 03:55:57 +00005407int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00005408{
5409 int max_bus;
5410 int index;
5411
5412 max_bus = -1;
5413 for (index = 0; index < nb_drives; index++) {
thsf60d39b2007-12-17 03:55:57 +00005414 if(drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005415 drives_table[index].bus > max_bus)
5416 max_bus = drives_table[index].bus;
5417 }
5418 return max_bus;
5419}
5420
aurel32a1620fa2008-04-29 05:58:01 +00005421static void bdrv_format_print(void *opaque, const char *name)
5422{
5423 fprintf(stderr, " %s", name);
5424}
5425
balrog609497a2008-01-14 02:56:53 +00005426static int drive_init(struct drive_opt *arg, int snapshot,
5427 QEMUMachine *machine)
thse4bcb142007-12-02 04:51:10 +00005428{
5429 char buf[128];
5430 char file[1024];
balrogc8522bd2007-12-06 22:11:20 +00005431 char devname[128];
5432 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00005433 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00005434 enum { MEDIA_DISK, MEDIA_CDROM } media;
5435 int bus_id, unit_id;
5436 int cyls, heads, secs, translation;
5437 BlockDriverState *bdrv;
aurel321e72d3b2008-04-28 20:26:45 +00005438 BlockDriver *drv = NULL;
thse4bcb142007-12-02 04:51:10 +00005439 int max_devs;
5440 int index;
balrog33f00272007-12-24 14:33:24 +00005441 int cache;
5442 int bdrv_flags;
balrog609497a2008-01-14 02:56:53 +00005443 char *str = arg->opt;
blueswir17ccfb2e2008-09-14 06:45:34 +00005444 static const char * const params[] = { "bus", "unit", "if", "index",
5445 "cyls", "heads", "secs", "trans",
5446 "media", "snapshot", "file",
5447 "cache", "format", NULL };
thse4bcb142007-12-02 04:51:10 +00005448
5449 if (check_params(buf, sizeof(buf), params, str) < 0) {
balrogff993632008-02-10 13:21:25 +00005450 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
thse4bcb142007-12-02 04:51:10 +00005451 buf, str);
5452 return -1;
5453 }
5454
5455 file[0] = 0;
5456 cyls = heads = secs = 0;
5457 bus_id = 0;
5458 unit_id = -1;
5459 translation = BIOS_ATA_TRANSLATION_AUTO;
5460 index = -1;
balrog33f00272007-12-24 14:33:24 +00005461 cache = 1;
thse4bcb142007-12-02 04:51:10 +00005462
5463 if (!strcmp(machine->name, "realview") ||
5464 !strcmp(machine->name, "SS-5") ||
5465 !strcmp(machine->name, "SS-10") ||
5466 !strcmp(machine->name, "SS-600MP") ||
5467 !strcmp(machine->name, "versatilepb") ||
5468 !strcmp(machine->name, "versatileab")) {
thsf60d39b2007-12-17 03:55:57 +00005469 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005470 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00005471 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00005472 } else {
thsf60d39b2007-12-17 03:55:57 +00005473 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005474 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00005475 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00005476 }
5477 media = MEDIA_DISK;
5478
5479 /* extract parameters */
5480
5481 if (get_param_value(buf, sizeof(buf), "bus", str)) {
5482 bus_id = strtol(buf, NULL, 0);
5483 if (bus_id < 0) {
5484 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
5485 return -1;
5486 }
5487 }
5488
5489 if (get_param_value(buf, sizeof(buf), "unit", str)) {
5490 unit_id = strtol(buf, NULL, 0);
5491 if (unit_id < 0) {
5492 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
5493 return -1;
5494 }
5495 }
5496
5497 if (get_param_value(buf, sizeof(buf), "if", str)) {
bellardae45d362008-06-11 09:44:44 +00005498 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00005499 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00005500 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005501 max_devs = MAX_IDE_DEVS;
5502 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00005503 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005504 max_devs = MAX_SCSI_DEVS;
5505 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00005506 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00005507 max_devs = 0;
5508 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00005509 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00005510 max_devs = 0;
5511 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00005512 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00005513 max_devs = 0;
5514 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00005515 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00005516 max_devs = 0;
5517 } else {
5518 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
5519 return -1;
5520 }
5521 }
5522
5523 if (get_param_value(buf, sizeof(buf), "index", str)) {
5524 index = strtol(buf, NULL, 0);
5525 if (index < 0) {
5526 fprintf(stderr, "qemu: '%s' invalid index\n", str);
5527 return -1;
5528 }
5529 }
5530
5531 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
5532 cyls = strtol(buf, NULL, 0);
5533 }
5534
5535 if (get_param_value(buf, sizeof(buf), "heads", str)) {
5536 heads = strtol(buf, NULL, 0);
5537 }
5538
5539 if (get_param_value(buf, sizeof(buf), "secs", str)) {
5540 secs = strtol(buf, NULL, 0);
5541 }
5542
5543 if (cyls || heads || secs) {
5544 if (cyls < 1 || cyls > 16383) {
5545 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
5546 return -1;
5547 }
5548 if (heads < 1 || heads > 16) {
5549 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
5550 return -1;
5551 }
5552 if (secs < 1 || secs > 63) {
5553 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
5554 return -1;
5555 }
5556 }
5557
5558 if (get_param_value(buf, sizeof(buf), "trans", str)) {
5559 if (!cyls) {
5560 fprintf(stderr,
5561 "qemu: '%s' trans must be used with cyls,heads and secs\n",
5562 str);
5563 return -1;
5564 }
5565 if (!strcmp(buf, "none"))
5566 translation = BIOS_ATA_TRANSLATION_NONE;
5567 else if (!strcmp(buf, "lba"))
5568 translation = BIOS_ATA_TRANSLATION_LBA;
5569 else if (!strcmp(buf, "auto"))
5570 translation = BIOS_ATA_TRANSLATION_AUTO;
5571 else {
5572 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
5573 return -1;
5574 }
5575 }
5576
5577 if (get_param_value(buf, sizeof(buf), "media", str)) {
5578 if (!strcmp(buf, "disk")) {
5579 media = MEDIA_DISK;
5580 } else if (!strcmp(buf, "cdrom")) {
5581 if (cyls || secs || heads) {
5582 fprintf(stderr,
5583 "qemu: '%s' invalid physical CHS format\n", str);
5584 return -1;
5585 }
5586 media = MEDIA_CDROM;
5587 } else {
5588 fprintf(stderr, "qemu: '%s' invalid media\n", str);
5589 return -1;
5590 }
5591 }
5592
5593 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
5594 if (!strcmp(buf, "on"))
5595 snapshot = 1;
5596 else if (!strcmp(buf, "off"))
5597 snapshot = 0;
5598 else {
5599 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
5600 return -1;
5601 }
5602 }
5603
balrog33f00272007-12-24 14:33:24 +00005604 if (get_param_value(buf, sizeof(buf), "cache", str)) {
5605 if (!strcmp(buf, "off"))
5606 cache = 0;
5607 else if (!strcmp(buf, "on"))
5608 cache = 1;
5609 else {
5610 fprintf(stderr, "qemu: invalid cache option\n");
5611 return -1;
5612 }
5613 }
5614
aurel321e72d3b2008-04-28 20:26:45 +00005615 if (get_param_value(buf, sizeof(buf), "format", str)) {
aurel32a1620fa2008-04-29 05:58:01 +00005616 if (strcmp(buf, "?") == 0) {
5617 fprintf(stderr, "qemu: Supported formats:");
5618 bdrv_iterate_format(bdrv_format_print, NULL);
5619 fprintf(stderr, "\n");
5620 return -1;
5621 }
aurel321e72d3b2008-04-28 20:26:45 +00005622 drv = bdrv_find_format(buf);
5623 if (!drv) {
5624 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
5625 return -1;
5626 }
5627 }
5628
balrog609497a2008-01-14 02:56:53 +00005629 if (arg->file == NULL)
5630 get_param_value(file, sizeof(file), "file", str);
5631 else
5632 pstrcpy(file, sizeof(file), arg->file);
thse4bcb142007-12-02 04:51:10 +00005633
5634 /* compute bus and unit according index */
5635
5636 if (index != -1) {
5637 if (bus_id != 0 || unit_id != -1) {
5638 fprintf(stderr,
5639 "qemu: '%s' index cannot be used with bus and unit\n", str);
5640 return -1;
5641 }
5642 if (max_devs == 0)
5643 {
5644 unit_id = index;
5645 bus_id = 0;
5646 } else {
5647 unit_id = index % max_devs;
5648 bus_id = index / max_devs;
5649 }
5650 }
5651
5652 /* if user doesn't specify a unit_id,
5653 * try to find the first free
5654 */
5655
5656 if (unit_id == -1) {
5657 unit_id = 0;
thsf60d39b2007-12-17 03:55:57 +00005658 while (drive_get_index(type, bus_id, unit_id) != -1) {
thse4bcb142007-12-02 04:51:10 +00005659 unit_id++;
5660 if (max_devs && unit_id >= max_devs) {
5661 unit_id -= max_devs;
5662 bus_id++;
5663 }
5664 }
5665 }
5666
5667 /* check unit id */
5668
5669 if (max_devs && unit_id >= max_devs) {
5670 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
5671 str, unit_id, max_devs - 1);
5672 return -1;
5673 }
5674
5675 /*
5676 * ignore multiple definitions
5677 */
5678
thsf60d39b2007-12-17 03:55:57 +00005679 if (drive_get_index(type, bus_id, unit_id) != -1)
thse4bcb142007-12-02 04:51:10 +00005680 return 0;
5681
5682 /* init */
5683
thsf60d39b2007-12-17 03:55:57 +00005684 if (type == IF_IDE || type == IF_SCSI)
balrogc8522bd2007-12-06 22:11:20 +00005685 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
balroge6198a72007-12-24 13:58:47 +00005686 if (max_devs)
5687 snprintf(buf, sizeof(buf), "%s%i%s%i",
5688 devname, bus_id, mediastr, unit_id);
5689 else
5690 snprintf(buf, sizeof(buf), "%s%s%i",
5691 devname, mediastr, unit_id);
thse4bcb142007-12-02 04:51:10 +00005692 bdrv = bdrv_new(buf);
5693 drives_table[nb_drives].bdrv = bdrv;
thsf60d39b2007-12-17 03:55:57 +00005694 drives_table[nb_drives].type = type;
thse4bcb142007-12-02 04:51:10 +00005695 drives_table[nb_drives].bus = bus_id;
5696 drives_table[nb_drives].unit = unit_id;
5697 nb_drives++;
5698
thsf60d39b2007-12-17 03:55:57 +00005699 switch(type) {
thse4bcb142007-12-02 04:51:10 +00005700 case IF_IDE:
5701 case IF_SCSI:
5702 switch(media) {
5703 case MEDIA_DISK:
5704 if (cyls != 0) {
5705 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
5706 bdrv_set_translation_hint(bdrv, translation);
5707 }
5708 break;
5709 case MEDIA_CDROM:
5710 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
5711 break;
5712 }
5713 break;
5714 case IF_SD:
5715 /* FIXME: This isn't really a floppy, but it's a reasonable
5716 approximation. */
5717 case IF_FLOPPY:
5718 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
5719 break;
5720 case IF_PFLASH:
5721 case IF_MTD:
5722 break;
5723 }
5724 if (!file[0])
5725 return 0;
balrog33f00272007-12-24 14:33:24 +00005726 bdrv_flags = 0;
5727 if (snapshot)
5728 bdrv_flags |= BDRV_O_SNAPSHOT;
5729 if (!cache)
5730 bdrv_flags |= BDRV_O_DIRECT;
aliguori83ab7952008-08-19 14:44:22 +00005731 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
thse4bcb142007-12-02 04:51:10 +00005732 fprintf(stderr, "qemu: could not open disk image %s\n",
5733 file);
5734 return -1;
5735 }
5736 return 0;
5737}
5738
bellard330d0412003-07-26 18:11:40 +00005739/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00005740/* USB devices */
5741
pbrook0d92ed32006-05-21 16:30:15 +00005742static USBPort *used_usb_ports;
5743static USBPort *free_usb_ports;
5744
5745/* ??? Maybe change this to register a hub to keep track of the topology. */
5746void qemu_register_usb_port(USBPort *port, void *opaque, int index,
5747 usb_attachfn attach)
5748{
5749 port->opaque = opaque;
5750 port->index = index;
5751 port->attach = attach;
5752 port->next = free_usb_ports;
5753 free_usb_ports = port;
5754}
5755
aliguori4b096fc2008-08-21 19:28:55 +00005756int usb_device_add_dev(USBDevice *dev)
5757{
5758 USBPort *port;
5759
5760 /* Find a USB port to add the device to. */
5761 port = free_usb_ports;
5762 if (!port->next) {
5763 USBDevice *hub;
5764
5765 /* Create a new hub and chain it on. */
5766 free_usb_ports = NULL;
5767 port->next = used_usb_ports;
5768 used_usb_ports = port;
5769
5770 hub = usb_hub_init(VM_USB_HUB_SIZE);
5771 usb_attach(port, hub);
5772 port = free_usb_ports;
5773 }
5774
5775 free_usb_ports = port->next;
5776 port->next = used_usb_ports;
5777 used_usb_ports = port;
5778 usb_attach(port, dev);
5779 return 0;
5780}
5781
bellarda594cfb2005-11-06 16:13:29 +00005782static int usb_device_add(const char *devname)
5783{
5784 const char *p;
5785 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00005786
pbrook0d92ed32006-05-21 16:30:15 +00005787 if (!free_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005788 return -1;
5789
5790 if (strstart(devname, "host:", &p)) {
5791 dev = usb_host_device_open(p);
bellarda594cfb2005-11-06 16:13:29 +00005792 } else if (!strcmp(devname, "mouse")) {
5793 dev = usb_mouse_init();
bellard09b26c52006-04-12 21:09:08 +00005794 } else if (!strcmp(devname, "tablet")) {
balrog47b2d332007-06-22 08:16:00 +00005795 dev = usb_tablet_init();
5796 } else if (!strcmp(devname, "keyboard")) {
5797 dev = usb_keyboard_init();
pbrook2e5d83b2006-05-25 23:58:51 +00005798 } else if (strstart(devname, "disk:", &p)) {
5799 dev = usb_msd_init(p);
balrogf6d2a312007-06-10 19:21:04 +00005800 } else if (!strcmp(devname, "wacom-tablet")) {
5801 dev = usb_wacom_init();
balroga7954212008-01-14 03:41:02 +00005802 } else if (strstart(devname, "serial:", &p)) {
5803 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00005804#ifdef CONFIG_BRLAPI
5805 } else if (!strcmp(devname, "braille")) {
5806 dev = usb_baum_init();
5807#endif
balrog6c9f8862008-07-17 20:47:13 +00005808 } else if (strstart(devname, "net:", &p)) {
balrog9ad97e62008-07-29 13:16:31 +00005809 int nic = nb_nics;
balrog6c9f8862008-07-17 20:47:13 +00005810
balrog9ad97e62008-07-29 13:16:31 +00005811 if (net_client_init("nic", p) < 0)
balrog6c9f8862008-07-17 20:47:13 +00005812 return -1;
balrog9ad97e62008-07-29 13:16:31 +00005813 nd_table[nic].model = "usb";
5814 dev = usb_net_init(&nd_table[nic]);
bellarda594cfb2005-11-06 16:13:29 +00005815 } else {
5816 return -1;
5817 }
pbrook0d92ed32006-05-21 16:30:15 +00005818 if (!dev)
5819 return -1;
5820
aliguori4b096fc2008-08-21 19:28:55 +00005821 return usb_device_add_dev(dev);
bellarda594cfb2005-11-06 16:13:29 +00005822}
5823
aliguori1f3870a2008-08-21 19:27:48 +00005824int usb_device_del_addr(int bus_num, int addr)
bellarda594cfb2005-11-06 16:13:29 +00005825{
pbrook0d92ed32006-05-21 16:30:15 +00005826 USBPort *port;
5827 USBPort **lastp;
bellard059809e2006-07-19 18:06:15 +00005828 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00005829
pbrook0d92ed32006-05-21 16:30:15 +00005830 if (!used_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005831 return -1;
5832
bellarda594cfb2005-11-06 16:13:29 +00005833 if (bus_num != 0)
5834 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005835
5836 lastp = &used_usb_ports;
5837 port = used_usb_ports;
5838 while (port && port->dev->addr != addr) {
5839 lastp = &port->next;
5840 port = port->next;
bellarda594cfb2005-11-06 16:13:29 +00005841 }
pbrook0d92ed32006-05-21 16:30:15 +00005842
5843 if (!port)
bellarda594cfb2005-11-06 16:13:29 +00005844 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005845
bellard059809e2006-07-19 18:06:15 +00005846 dev = port->dev;
pbrook0d92ed32006-05-21 16:30:15 +00005847 *lastp = port->next;
5848 usb_attach(port, NULL);
bellard059809e2006-07-19 18:06:15 +00005849 dev->handle_destroy(dev);
pbrook0d92ed32006-05-21 16:30:15 +00005850 port->next = free_usb_ports;
5851 free_usb_ports = port;
bellarda594cfb2005-11-06 16:13:29 +00005852 return 0;
5853}
5854
aliguori1f3870a2008-08-21 19:27:48 +00005855static int usb_device_del(const char *devname)
5856{
5857 int bus_num, addr;
5858 const char *p;
5859
aliguori5d0c5752008-09-14 01:07:41 +00005860 if (strstart(devname, "host:", &p))
5861 return usb_host_device_close(p);
5862
aliguori1f3870a2008-08-21 19:27:48 +00005863 if (!used_usb_ports)
5864 return -1;
5865
5866 p = strchr(devname, '.');
5867 if (!p)
5868 return -1;
5869 bus_num = strtoul(devname, NULL, 0);
5870 addr = strtoul(p + 1, NULL, 0);
5871
5872 return usb_device_del_addr(bus_num, addr);
5873}
5874
bellarda594cfb2005-11-06 16:13:29 +00005875void do_usb_add(const char *devname)
5876{
aliguori4b096fc2008-08-21 19:28:55 +00005877 usb_device_add(devname);
bellarda594cfb2005-11-06 16:13:29 +00005878}
5879
5880void do_usb_del(const char *devname)
5881{
aliguori4b096fc2008-08-21 19:28:55 +00005882 usb_device_del(devname);
bellarda594cfb2005-11-06 16:13:29 +00005883}
5884
5885void usb_info(void)
5886{
5887 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00005888 USBPort *port;
bellarda594cfb2005-11-06 16:13:29 +00005889 const char *speed_str;
5890
pbrook0d92ed32006-05-21 16:30:15 +00005891 if (!usb_enabled) {
bellarda594cfb2005-11-06 16:13:29 +00005892 term_printf("USB support not enabled\n");
5893 return;
5894 }
5895
pbrook0d92ed32006-05-21 16:30:15 +00005896 for (port = used_usb_ports; port; port = port->next) {
5897 dev = port->dev;
5898 if (!dev)
5899 continue;
5900 switch(dev->speed) {
ths5fafdf22007-09-16 21:08:06 +00005901 case USB_SPEED_LOW:
5902 speed_str = "1.5";
pbrook0d92ed32006-05-21 16:30:15 +00005903 break;
ths5fafdf22007-09-16 21:08:06 +00005904 case USB_SPEED_FULL:
5905 speed_str = "12";
pbrook0d92ed32006-05-21 16:30:15 +00005906 break;
ths5fafdf22007-09-16 21:08:06 +00005907 case USB_SPEED_HIGH:
5908 speed_str = "480";
pbrook0d92ed32006-05-21 16:30:15 +00005909 break;
5910 default:
ths5fafdf22007-09-16 21:08:06 +00005911 speed_str = "?";
pbrook0d92ed32006-05-21 16:30:15 +00005912 break;
bellarda594cfb2005-11-06 16:13:29 +00005913 }
ths5fafdf22007-09-16 21:08:06 +00005914 term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
bellard1f6e24e2006-06-26 21:00:51 +00005915 0, dev->addr, speed_str, dev->devname);
bellarda594cfb2005-11-06 16:13:29 +00005916 }
5917}
5918
bellardf7cce892004-12-08 22:21:25 +00005919/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00005920/* PCMCIA/Cardbus */
5921
5922static struct pcmcia_socket_entry_s {
5923 struct pcmcia_socket_s *socket;
5924 struct pcmcia_socket_entry_s *next;
5925} *pcmcia_sockets = 0;
5926
5927void pcmcia_socket_register(struct pcmcia_socket_s *socket)
5928{
5929 struct pcmcia_socket_entry_s *entry;
5930
5931 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
5932 entry->socket = socket;
5933 entry->next = pcmcia_sockets;
5934 pcmcia_sockets = entry;
5935}
5936
5937void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
5938{
5939 struct pcmcia_socket_entry_s *entry, **ptr;
5940
5941 ptr = &pcmcia_sockets;
5942 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
5943 if (entry->socket == socket) {
5944 *ptr = entry->next;
5945 qemu_free(entry);
5946 }
5947}
5948
5949void pcmcia_info(void)
5950{
5951 struct pcmcia_socket_entry_s *iter;
5952 if (!pcmcia_sockets)
5953 term_printf("No PCMCIA sockets\n");
5954
5955 for (iter = pcmcia_sockets; iter; iter = iter->next)
5956 term_printf("%s: %s\n", iter->socket->slot_string,
5957 iter->socket->attached ? iter->socket->card_string :
5958 "Empty");
5959}
5960
5961/***********************************************************/
ths2ff89792007-06-21 23:34:19 +00005962/* dumb display */
5963
5964static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
5965{
5966}
5967
5968static void dumb_resize(DisplayState *ds, int w, int h)
5969{
5970}
5971
5972static void dumb_refresh(DisplayState *ds)
5973{
5974#if defined(CONFIG_SDL)
5975 vga_hw_update();
5976#endif
5977}
5978
5979static void dumb_display_init(DisplayState *ds)
5980{
5981 ds->data = NULL;
5982 ds->linesize = 0;
5983 ds->depth = 0;
5984 ds->dpy_update = dumb_update;
5985 ds->dpy_resize = dumb_resize;
5986 ds->dpy_refresh = dumb_refresh;
aliguoribcfad702008-08-21 20:08:55 +00005987 ds->gui_timer_interval = 500;
5988 ds->idle = 1;
ths2ff89792007-06-21 23:34:19 +00005989}
5990
5991/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00005992/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00005993
bellardc4b1fcc2004-03-14 21:44:30 +00005994#define MAX_IO_HANDLERS 64
5995
5996typedef struct IOHandlerRecord {
5997 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00005998 IOCanRWHandler *fd_read_poll;
5999 IOHandler *fd_read;
6000 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00006001 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00006002 void *opaque;
6003 /* temporary data */
6004 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00006005 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00006006} IOHandlerRecord;
6007
bellard8a7ddc32004-03-31 19:00:16 +00006008static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00006009
bellard7c9d8e02005-11-15 22:16:05 +00006010/* XXX: fd_read_poll should be suppressed, but an API change is
6011 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00006012int qemu_set_fd_handler2(int fd,
6013 IOCanRWHandler *fd_read_poll,
6014 IOHandler *fd_read,
6015 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00006016 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00006017{
bellard8a7ddc32004-03-31 19:00:16 +00006018 IOHandlerRecord **pioh, *ioh;
6019
bellard7c9d8e02005-11-15 22:16:05 +00006020 if (!fd_read && !fd_write) {
6021 pioh = &first_io_handler;
6022 for(;;) {
6023 ioh = *pioh;
6024 if (ioh == NULL)
6025 break;
6026 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00006027 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00006028 break;
6029 }
6030 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00006031 }
bellard7c9d8e02005-11-15 22:16:05 +00006032 } else {
6033 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6034 if (ioh->fd == fd)
6035 goto found;
6036 }
6037 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
6038 if (!ioh)
6039 return -1;
6040 ioh->next = first_io_handler;
6041 first_io_handler = ioh;
6042 found:
6043 ioh->fd = fd;
6044 ioh->fd_read_poll = fd_read_poll;
6045 ioh->fd_read = fd_read;
6046 ioh->fd_write = fd_write;
6047 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00006048 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00006049 }
bellard7c9d8e02005-11-15 22:16:05 +00006050 return 0;
6051}
6052
ths5fafdf22007-09-16 21:08:06 +00006053int qemu_set_fd_handler(int fd,
6054 IOHandler *fd_read,
6055 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00006056 void *opaque)
6057{
6058 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00006059}
6060
bellard8a7ddc32004-03-31 19:00:16 +00006061/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00006062/* Polling handling */
6063
6064typedef struct PollingEntry {
6065 PollingFunc *func;
6066 void *opaque;
6067 struct PollingEntry *next;
6068} PollingEntry;
6069
6070static PollingEntry *first_polling_entry;
6071
6072int qemu_add_polling_cb(PollingFunc *func, void *opaque)
6073{
6074 PollingEntry **ppe, *pe;
6075 pe = qemu_mallocz(sizeof(PollingEntry));
6076 if (!pe)
6077 return -1;
6078 pe->func = func;
6079 pe->opaque = opaque;
6080 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
6081 *ppe = pe;
6082 return 0;
6083}
6084
6085void qemu_del_polling_cb(PollingFunc *func, void *opaque)
6086{
6087 PollingEntry **ppe, *pe;
6088 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
6089 pe = *ppe;
6090 if (pe->func == func && pe->opaque == opaque) {
6091 *ppe = pe->next;
6092 qemu_free(pe);
6093 break;
6094 }
6095 }
6096}
6097
bellarda18e5242006-06-25 17:18:27 +00006098#ifdef _WIN32
6099/***********************************************************/
6100/* Wait objects support */
6101typedef struct WaitObjects {
6102 int num;
6103 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
6104 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
6105 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
6106} WaitObjects;
6107
6108static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00006109
bellarda18e5242006-06-25 17:18:27 +00006110int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
6111{
6112 WaitObjects *w = &wait_objects;
6113
6114 if (w->num >= MAXIMUM_WAIT_OBJECTS)
6115 return -1;
6116 w->events[w->num] = handle;
6117 w->func[w->num] = func;
6118 w->opaque[w->num] = opaque;
6119 w->num++;
6120 return 0;
6121}
6122
6123void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
6124{
6125 int i, found;
6126 WaitObjects *w = &wait_objects;
6127
6128 found = 0;
6129 for (i = 0; i < w->num; i++) {
6130 if (w->events[i] == handle)
6131 found = 1;
6132 if (found) {
6133 w->events[i] = w->events[i + 1];
6134 w->func[i] = w->func[i + 1];
6135 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00006136 }
bellarda18e5242006-06-25 17:18:27 +00006137 }
6138 if (found)
6139 w->num--;
6140}
6141#endif
6142
bellardf3311102006-04-12 20:21:17 +00006143/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006144/* savevm/loadvm support */
bellardb4608c02003-06-27 17:34:32 +00006145
bellardfaea38e2006-08-05 21:31:00 +00006146#define IO_BUF_SIZE 32768
6147
6148struct QEMUFile {
6149 FILE *outfile;
6150 BlockDriverState *bs;
6151 int is_file;
6152 int is_writable;
6153 int64_t base_offset;
6154 int64_t buf_offset; /* start of buffer when writing, end of buffer
6155 when reading */
6156 int buf_index;
6157 int buf_size; /* 0 when writing */
6158 uint8_t buf[IO_BUF_SIZE];
6159};
6160
6161QEMUFile *qemu_fopen(const char *filename, const char *mode)
6162{
6163 QEMUFile *f;
6164
6165 f = qemu_mallocz(sizeof(QEMUFile));
6166 if (!f)
6167 return NULL;
6168 if (!strcmp(mode, "wb")) {
6169 f->is_writable = 1;
6170 } else if (!strcmp(mode, "rb")) {
6171 f->is_writable = 0;
6172 } else {
6173 goto fail;
6174 }
6175 f->outfile = fopen(filename, mode);
6176 if (!f->outfile)
6177 goto fail;
6178 f->is_file = 1;
6179 return f;
6180 fail:
6181 if (f->outfile)
6182 fclose(f->outfile);
6183 qemu_free(f);
6184 return NULL;
6185}
6186
pbrook9596ebb2007-11-18 01:44:38 +00006187static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
bellardfaea38e2006-08-05 21:31:00 +00006188{
6189 QEMUFile *f;
6190
6191 f = qemu_mallocz(sizeof(QEMUFile));
6192 if (!f)
6193 return NULL;
6194 f->is_file = 0;
6195 f->bs = bs;
6196 f->is_writable = is_writable;
6197 f->base_offset = offset;
6198 return f;
6199}
6200
6201void qemu_fflush(QEMUFile *f)
6202{
6203 if (!f->is_writable)
6204 return;
6205 if (f->buf_index > 0) {
6206 if (f->is_file) {
6207 fseek(f->outfile, f->buf_offset, SEEK_SET);
6208 fwrite(f->buf, 1, f->buf_index, f->outfile);
6209 } else {
ths5fafdf22007-09-16 21:08:06 +00006210 bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00006211 f->buf, f->buf_index);
6212 }
6213 f->buf_offset += f->buf_index;
6214 f->buf_index = 0;
6215 }
6216}
6217
6218static void qemu_fill_buffer(QEMUFile *f)
6219{
6220 int len;
6221
6222 if (f->is_writable)
6223 return;
6224 if (f->is_file) {
6225 fseek(f->outfile, f->buf_offset, SEEK_SET);
6226 len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
6227 if (len < 0)
6228 len = 0;
6229 } else {
ths5fafdf22007-09-16 21:08:06 +00006230 len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00006231 f->buf, IO_BUF_SIZE);
6232 if (len < 0)
6233 len = 0;
6234 }
6235 f->buf_index = 0;
6236 f->buf_size = len;
6237 f->buf_offset += len;
6238}
6239
6240void qemu_fclose(QEMUFile *f)
6241{
6242 if (f->is_writable)
6243 qemu_fflush(f);
6244 if (f->is_file) {
6245 fclose(f->outfile);
6246 }
6247 qemu_free(f);
6248}
6249
bellard8a7ddc32004-03-31 19:00:16 +00006250void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
6251{
bellardfaea38e2006-08-05 21:31:00 +00006252 int l;
6253 while (size > 0) {
6254 l = IO_BUF_SIZE - f->buf_index;
6255 if (l > size)
6256 l = size;
6257 memcpy(f->buf + f->buf_index, buf, l);
6258 f->buf_index += l;
6259 buf += l;
6260 size -= l;
6261 if (f->buf_index >= IO_BUF_SIZE)
6262 qemu_fflush(f);
6263 }
bellard8a7ddc32004-03-31 19:00:16 +00006264}
6265
6266void qemu_put_byte(QEMUFile *f, int v)
6267{
bellardfaea38e2006-08-05 21:31:00 +00006268 f->buf[f->buf_index++] = v;
6269 if (f->buf_index >= IO_BUF_SIZE)
6270 qemu_fflush(f);
6271}
6272
6273int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
6274{
6275 int size, l;
6276
6277 size = size1;
6278 while (size > 0) {
6279 l = f->buf_size - f->buf_index;
6280 if (l == 0) {
6281 qemu_fill_buffer(f);
6282 l = f->buf_size - f->buf_index;
6283 if (l == 0)
6284 break;
6285 }
6286 if (l > size)
6287 l = size;
6288 memcpy(buf, f->buf + f->buf_index, l);
6289 f->buf_index += l;
6290 buf += l;
6291 size -= l;
6292 }
6293 return size1 - size;
6294}
6295
6296int qemu_get_byte(QEMUFile *f)
6297{
6298 if (f->buf_index >= f->buf_size) {
6299 qemu_fill_buffer(f);
6300 if (f->buf_index >= f->buf_size)
6301 return 0;
6302 }
6303 return f->buf[f->buf_index++];
6304}
6305
6306int64_t qemu_ftell(QEMUFile *f)
6307{
6308 return f->buf_offset - f->buf_size + f->buf_index;
6309}
6310
6311int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
6312{
6313 if (whence == SEEK_SET) {
6314 /* nothing to do */
6315 } else if (whence == SEEK_CUR) {
6316 pos += qemu_ftell(f);
6317 } else {
6318 /* SEEK_END not supported */
6319 return -1;
6320 }
6321 if (f->is_writable) {
6322 qemu_fflush(f);
6323 f->buf_offset = pos;
6324 } else {
6325 f->buf_offset = pos;
6326 f->buf_index = 0;
6327 f->buf_size = 0;
6328 }
6329 return pos;
bellard8a7ddc32004-03-31 19:00:16 +00006330}
6331
6332void qemu_put_be16(QEMUFile *f, unsigned int v)
6333{
6334 qemu_put_byte(f, v >> 8);
6335 qemu_put_byte(f, v);
6336}
6337
6338void qemu_put_be32(QEMUFile *f, unsigned int v)
6339{
6340 qemu_put_byte(f, v >> 24);
6341 qemu_put_byte(f, v >> 16);
6342 qemu_put_byte(f, v >> 8);
6343 qemu_put_byte(f, v);
6344}
6345
6346void qemu_put_be64(QEMUFile *f, uint64_t v)
6347{
6348 qemu_put_be32(f, v >> 32);
6349 qemu_put_be32(f, v);
6350}
6351
bellard8a7ddc32004-03-31 19:00:16 +00006352unsigned int qemu_get_be16(QEMUFile *f)
6353{
6354 unsigned int v;
6355 v = qemu_get_byte(f) << 8;
6356 v |= qemu_get_byte(f);
6357 return v;
6358}
6359
6360unsigned int qemu_get_be32(QEMUFile *f)
6361{
6362 unsigned int v;
6363 v = qemu_get_byte(f) << 24;
6364 v |= qemu_get_byte(f) << 16;
6365 v |= qemu_get_byte(f) << 8;
6366 v |= qemu_get_byte(f);
6367 return v;
6368}
6369
6370uint64_t qemu_get_be64(QEMUFile *f)
6371{
6372 uint64_t v;
6373 v = (uint64_t)qemu_get_be32(f) << 32;
6374 v |= qemu_get_be32(f);
6375 return v;
6376}
6377
bellard8a7ddc32004-03-31 19:00:16 +00006378typedef struct SaveStateEntry {
6379 char idstr[256];
6380 int instance_id;
6381 int version_id;
6382 SaveStateHandler *save_state;
6383 LoadStateHandler *load_state;
6384 void *opaque;
6385 struct SaveStateEntry *next;
6386} SaveStateEntry;
6387
6388static SaveStateEntry *first_se;
6389
pbrook18be5182008-07-01 21:31:54 +00006390/* TODO: Individual devices generally have very little idea about the rest
ths18fdb1c2008-07-18 18:02:34 +00006391 of the system, so instance_id should be removed/replaced.
6392 Meanwhile pass -1 as instance_id if you do not already have a clearly
6393 distinguishing id for all instances of your device class. */
ths5fafdf22007-09-16 21:08:06 +00006394int register_savevm(const char *idstr,
6395 int instance_id,
bellard8a7ddc32004-03-31 19:00:16 +00006396 int version_id,
6397 SaveStateHandler *save_state,
6398 LoadStateHandler *load_state,
6399 void *opaque)
6400{
6401 SaveStateEntry *se, **pse;
6402
6403 se = qemu_malloc(sizeof(SaveStateEntry));
6404 if (!se)
6405 return -1;
6406 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
pbrook18be5182008-07-01 21:31:54 +00006407 se->instance_id = (instance_id == -1) ? 0 : instance_id;
bellard8a7ddc32004-03-31 19:00:16 +00006408 se->version_id = version_id;
6409 se->save_state = save_state;
6410 se->load_state = load_state;
6411 se->opaque = opaque;
6412 se->next = NULL;
6413
6414 /* add at the end of list */
6415 pse = &first_se;
pbrook18be5182008-07-01 21:31:54 +00006416 while (*pse != NULL) {
6417 if (instance_id == -1
6418 && strcmp(se->idstr, (*pse)->idstr) == 0
6419 && se->instance_id <= (*pse)->instance_id)
6420 se->instance_id = (*pse)->instance_id + 1;
bellard8a7ddc32004-03-31 19:00:16 +00006421 pse = &(*pse)->next;
pbrook18be5182008-07-01 21:31:54 +00006422 }
bellard8a7ddc32004-03-31 19:00:16 +00006423 *pse = se;
6424 return 0;
6425}
6426
6427#define QEMU_VM_FILE_MAGIC 0x5145564d
bellardfaea38e2006-08-05 21:31:00 +00006428#define QEMU_VM_FILE_VERSION 0x00000002
bellard8a7ddc32004-03-31 19:00:16 +00006429
pbrook9596ebb2007-11-18 01:44:38 +00006430static int qemu_savevm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006431{
6432 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006433 int len, ret;
6434 int64_t cur_pos, len_pos, total_len_pos;
bellard313aa562003-08-10 21:52:11 +00006435
bellard8a7ddc32004-03-31 19:00:16 +00006436 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
6437 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
bellardfaea38e2006-08-05 21:31:00 +00006438 total_len_pos = qemu_ftell(f);
6439 qemu_put_be64(f, 0); /* total size */
bellard8a7ddc32004-03-31 19:00:16 +00006440
6441 for(se = first_se; se != NULL; se = se->next) {
aurel32d978c022008-06-18 22:10:21 +00006442 if (se->save_state == NULL)
6443 /* this one has a loader only, for backwards compatibility */
6444 continue;
6445
bellard8a7ddc32004-03-31 19:00:16 +00006446 /* ID string */
6447 len = strlen(se->idstr);
6448 qemu_put_byte(f, len);
thsffe8ab82007-12-16 03:16:05 +00006449 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006450
6451 qemu_put_be32(f, se->instance_id);
6452 qemu_put_be32(f, se->version_id);
6453
6454 /* record size: filled later */
bellardfaea38e2006-08-05 21:31:00 +00006455 len_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006456 qemu_put_be32(f, 0);
bellard8a7ddc32004-03-31 19:00:16 +00006457 se->save_state(f, se->opaque);
6458
6459 /* fill record size */
bellardfaea38e2006-08-05 21:31:00 +00006460 cur_pos = qemu_ftell(f);
6461 len = cur_pos - len_pos - 4;
6462 qemu_fseek(f, len_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006463 qemu_put_be32(f, len);
bellardfaea38e2006-08-05 21:31:00 +00006464 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006465 }
bellardfaea38e2006-08-05 21:31:00 +00006466 cur_pos = qemu_ftell(f);
6467 qemu_fseek(f, total_len_pos, SEEK_SET);
6468 qemu_put_be64(f, cur_pos - total_len_pos - 8);
6469 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006470
bellard8a7ddc32004-03-31 19:00:16 +00006471 ret = 0;
bellard8a7ddc32004-03-31 19:00:16 +00006472 return ret;
6473}
6474
6475static SaveStateEntry *find_se(const char *idstr, int instance_id)
6476{
6477 SaveStateEntry *se;
6478
6479 for(se = first_se; se != NULL; se = se->next) {
ths5fafdf22007-09-16 21:08:06 +00006480 if (!strcmp(se->idstr, idstr) &&
bellard8a7ddc32004-03-31 19:00:16 +00006481 instance_id == se->instance_id)
6482 return se;
6483 }
6484 return NULL;
6485}
6486
pbrook9596ebb2007-11-18 01:44:38 +00006487static int qemu_loadvm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006488{
6489 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006490 int len, ret, instance_id, record_len, version_id;
6491 int64_t total_len, end_pos, cur_pos;
bellard8a7ddc32004-03-31 19:00:16 +00006492 unsigned int v;
6493 char idstr[256];
ths3b46e622007-09-17 08:09:54 +00006494
bellard8a7ddc32004-03-31 19:00:16 +00006495 v = qemu_get_be32(f);
6496 if (v != QEMU_VM_FILE_MAGIC)
6497 goto fail;
6498 v = qemu_get_be32(f);
6499 if (v != QEMU_VM_FILE_VERSION) {
6500 fail:
bellard8a7ddc32004-03-31 19:00:16 +00006501 ret = -1;
6502 goto the_end;
6503 }
bellardfaea38e2006-08-05 21:31:00 +00006504 total_len = qemu_get_be64(f);
6505 end_pos = total_len + qemu_ftell(f);
bellardb4608c02003-06-27 17:34:32 +00006506 for(;;) {
bellardfaea38e2006-08-05 21:31:00 +00006507 if (qemu_ftell(f) >= end_pos)
bellard8a7ddc32004-03-31 19:00:16 +00006508 break;
bellardfaea38e2006-08-05 21:31:00 +00006509 len = qemu_get_byte(f);
thsffe8ab82007-12-16 03:16:05 +00006510 qemu_get_buffer(f, (uint8_t *)idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006511 idstr[len] = '\0';
6512 instance_id = qemu_get_be32(f);
6513 version_id = qemu_get_be32(f);
6514 record_len = qemu_get_be32(f);
6515#if 0
ths5fafdf22007-09-16 21:08:06 +00006516 printf("idstr=%s instance=0x%x version=%d len=%d\n",
bellard8a7ddc32004-03-31 19:00:16 +00006517 idstr, instance_id, version_id, record_len);
bellardc45886d2004-01-05 00:02:06 +00006518#endif
bellardfaea38e2006-08-05 21:31:00 +00006519 cur_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006520 se = find_se(idstr, instance_id);
6521 if (!se) {
ths5fafdf22007-09-16 21:08:06 +00006522 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
bellard8a7ddc32004-03-31 19:00:16 +00006523 instance_id, idstr);
6524 } else {
6525 ret = se->load_state(f, se->opaque, version_id);
6526 if (ret < 0) {
ths5fafdf22007-09-16 21:08:06 +00006527 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
bellard8a7ddc32004-03-31 19:00:16 +00006528 instance_id, idstr);
6529 }
bellard34865132003-10-05 14:28:56 +00006530 }
bellard8a7ddc32004-03-31 19:00:16 +00006531 /* always seek to exact end of record */
6532 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
6533 }
bellard8a7ddc32004-03-31 19:00:16 +00006534 ret = 0;
6535 the_end:
bellardfaea38e2006-08-05 21:31:00 +00006536 return ret;
6537}
6538
6539/* device can contain snapshots */
6540static int bdrv_can_snapshot(BlockDriverState *bs)
6541{
6542 return (bs &&
6543 !bdrv_is_removable(bs) &&
6544 !bdrv_is_read_only(bs));
6545}
6546
6547/* device must be snapshots in order to have a reliable snapshot */
6548static int bdrv_has_snapshot(BlockDriverState *bs)
6549{
6550 return (bs &&
6551 !bdrv_is_removable(bs) &&
6552 !bdrv_is_read_only(bs));
6553}
6554
6555static BlockDriverState *get_bs_snapshots(void)
6556{
6557 BlockDriverState *bs;
6558 int i;
6559
6560 if (bs_snapshots)
6561 return bs_snapshots;
thse4bcb142007-12-02 04:51:10 +00006562 for(i = 0; i <= nb_drives; i++) {
6563 bs = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006564 if (bdrv_can_snapshot(bs))
6565 goto ok;
6566 }
6567 return NULL;
6568 ok:
6569 bs_snapshots = bs;
6570 return bs;
6571}
6572
6573static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
6574 const char *name)
6575{
6576 QEMUSnapshotInfo *sn_tab, *sn;
6577 int nb_sns, i, ret;
ths3b46e622007-09-17 08:09:54 +00006578
bellardfaea38e2006-08-05 21:31:00 +00006579 ret = -ENOENT;
6580 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6581 if (nb_sns < 0)
6582 return ret;
6583 for(i = 0; i < nb_sns; i++) {
6584 sn = &sn_tab[i];
6585 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
6586 *sn_info = *sn;
6587 ret = 0;
6588 break;
6589 }
6590 }
6591 qemu_free(sn_tab);
6592 return ret;
6593}
6594
6595void do_savevm(const char *name)
6596{
6597 BlockDriverState *bs, *bs1;
6598 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
6599 int must_delete, ret, i;
6600 BlockDriverInfo bdi1, *bdi = &bdi1;
6601 QEMUFile *f;
6602 int saved_vm_running;
bellard4c279bd2006-08-17 09:43:50 +00006603#ifdef _WIN32
6604 struct _timeb tb;
6605#else
bellardfaea38e2006-08-05 21:31:00 +00006606 struct timeval tv;
bellard4c279bd2006-08-17 09:43:50 +00006607#endif
bellardfaea38e2006-08-05 21:31:00 +00006608
6609 bs = get_bs_snapshots();
6610 if (!bs) {
6611 term_printf("No block device can accept snapshots\n");
6612 return;
6613 }
6614
pbrook6192bc32006-09-03 12:08:37 +00006615 /* ??? Should this occur after vm_stop? */
6616 qemu_aio_flush();
6617
bellardfaea38e2006-08-05 21:31:00 +00006618 saved_vm_running = vm_running;
6619 vm_stop(0);
ths3b46e622007-09-17 08:09:54 +00006620
bellardfaea38e2006-08-05 21:31:00 +00006621 must_delete = 0;
6622 if (name) {
6623 ret = bdrv_snapshot_find(bs, old_sn, name);
6624 if (ret >= 0) {
6625 must_delete = 1;
6626 }
6627 }
6628 memset(sn, 0, sizeof(*sn));
6629 if (must_delete) {
6630 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
6631 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
6632 } else {
6633 if (name)
6634 pstrcpy(sn->name, sizeof(sn->name), name);
6635 }
6636
6637 /* fill auxiliary fields */
bellard4c279bd2006-08-17 09:43:50 +00006638#ifdef _WIN32
6639 _ftime(&tb);
6640 sn->date_sec = tb.time;
6641 sn->date_nsec = tb.millitm * 1000000;
6642#else
bellardfaea38e2006-08-05 21:31:00 +00006643 gettimeofday(&tv, NULL);
6644 sn->date_sec = tv.tv_sec;
6645 sn->date_nsec = tv.tv_usec * 1000;
bellard4c279bd2006-08-17 09:43:50 +00006646#endif
bellardfaea38e2006-08-05 21:31:00 +00006647 sn->vm_clock_nsec = qemu_get_clock(vm_clock);
ths3b46e622007-09-17 08:09:54 +00006648
bellardfaea38e2006-08-05 21:31:00 +00006649 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6650 term_printf("Device %s does not support VM state snapshots\n",
6651 bdrv_get_device_name(bs));
6652 goto the_end;
6653 }
ths3b46e622007-09-17 08:09:54 +00006654
bellardfaea38e2006-08-05 21:31:00 +00006655 /* save the VM state */
6656 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
6657 if (!f) {
6658 term_printf("Could not open VM state file\n");
6659 goto the_end;
6660 }
6661 ret = qemu_savevm_state(f);
6662 sn->vm_state_size = qemu_ftell(f);
6663 qemu_fclose(f);
6664 if (ret < 0) {
6665 term_printf("Error %d while writing VM\n", ret);
6666 goto the_end;
6667 }
ths3b46e622007-09-17 08:09:54 +00006668
bellardfaea38e2006-08-05 21:31:00 +00006669 /* create the snapshots */
6670
thse4bcb142007-12-02 04:51:10 +00006671 for(i = 0; i < nb_drives; i++) {
6672 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006673 if (bdrv_has_snapshot(bs1)) {
6674 if (must_delete) {
6675 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
6676 if (ret < 0) {
6677 term_printf("Error while deleting snapshot on '%s'\n",
6678 bdrv_get_device_name(bs1));
6679 }
6680 }
6681 ret = bdrv_snapshot_create(bs1, sn);
6682 if (ret < 0) {
6683 term_printf("Error while creating snapshot on '%s'\n",
6684 bdrv_get_device_name(bs1));
6685 }
6686 }
6687 }
6688
6689 the_end:
bellard8a7ddc32004-03-31 19:00:16 +00006690 if (saved_vm_running)
6691 vm_start();
bellardfaea38e2006-08-05 21:31:00 +00006692}
6693
6694void do_loadvm(const char *name)
6695{
6696 BlockDriverState *bs, *bs1;
6697 BlockDriverInfo bdi1, *bdi = &bdi1;
6698 QEMUFile *f;
6699 int i, ret;
6700 int saved_vm_running;
6701
6702 bs = get_bs_snapshots();
6703 if (!bs) {
6704 term_printf("No block device supports snapshots\n");
6705 return;
6706 }
ths3b46e622007-09-17 08:09:54 +00006707
pbrook6192bc32006-09-03 12:08:37 +00006708 /* Flush all IO requests so they don't interfere with the new state. */
6709 qemu_aio_flush();
6710
bellardfaea38e2006-08-05 21:31:00 +00006711 saved_vm_running = vm_running;
6712 vm_stop(0);
6713
thse4bcb142007-12-02 04:51:10 +00006714 for(i = 0; i <= nb_drives; i++) {
6715 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006716 if (bdrv_has_snapshot(bs1)) {
6717 ret = bdrv_snapshot_goto(bs1, name);
6718 if (ret < 0) {
6719 if (bs != bs1)
6720 term_printf("Warning: ");
6721 switch(ret) {
6722 case -ENOTSUP:
6723 term_printf("Snapshots not supported on device '%s'\n",
6724 bdrv_get_device_name(bs1));
6725 break;
6726 case -ENOENT:
6727 term_printf("Could not find snapshot '%s' on device '%s'\n",
6728 name, bdrv_get_device_name(bs1));
6729 break;
6730 default:
6731 term_printf("Error %d while activating snapshot on '%s'\n",
6732 ret, bdrv_get_device_name(bs1));
6733 break;
6734 }
6735 /* fatal on snapshot block device */
6736 if (bs == bs1)
6737 goto the_end;
6738 }
6739 }
6740 }
6741
6742 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6743 term_printf("Device %s does not support VM state snapshots\n",
6744 bdrv_get_device_name(bs));
6745 return;
6746 }
ths3b46e622007-09-17 08:09:54 +00006747
bellardfaea38e2006-08-05 21:31:00 +00006748 /* restore the VM state */
6749 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
6750 if (!f) {
6751 term_printf("Could not open VM state file\n");
6752 goto the_end;
6753 }
6754 ret = qemu_loadvm_state(f);
6755 qemu_fclose(f);
6756 if (ret < 0) {
6757 term_printf("Error %d while loading VM state\n", ret);
6758 }
6759 the_end:
6760 if (saved_vm_running)
6761 vm_start();
6762}
6763
6764void do_delvm(const char *name)
6765{
6766 BlockDriverState *bs, *bs1;
6767 int i, ret;
6768
6769 bs = get_bs_snapshots();
6770 if (!bs) {
6771 term_printf("No block device supports snapshots\n");
6772 return;
6773 }
ths3b46e622007-09-17 08:09:54 +00006774
thse4bcb142007-12-02 04:51:10 +00006775 for(i = 0; i <= nb_drives; i++) {
6776 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006777 if (bdrv_has_snapshot(bs1)) {
6778 ret = bdrv_snapshot_delete(bs1, name);
6779 if (ret < 0) {
6780 if (ret == -ENOTSUP)
6781 term_printf("Snapshots not supported on device '%s'\n",
6782 bdrv_get_device_name(bs1));
6783 else
6784 term_printf("Error %d while deleting snapshot on '%s'\n",
6785 ret, bdrv_get_device_name(bs1));
6786 }
6787 }
6788 }
6789}
6790
6791void do_info_snapshots(void)
6792{
6793 BlockDriverState *bs, *bs1;
6794 QEMUSnapshotInfo *sn_tab, *sn;
6795 int nb_sns, i;
6796 char buf[256];
6797
6798 bs = get_bs_snapshots();
6799 if (!bs) {
6800 term_printf("No available block device supports snapshots\n");
6801 return;
6802 }
6803 term_printf("Snapshot devices:");
thse4bcb142007-12-02 04:51:10 +00006804 for(i = 0; i <= nb_drives; i++) {
6805 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006806 if (bdrv_has_snapshot(bs1)) {
6807 if (bs == bs1)
6808 term_printf(" %s", bdrv_get_device_name(bs1));
6809 }
6810 }
6811 term_printf("\n");
6812
6813 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6814 if (nb_sns < 0) {
6815 term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
6816 return;
6817 }
6818 term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
6819 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
6820 for(i = 0; i < nb_sns; i++) {
6821 sn = &sn_tab[i];
6822 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
6823 }
6824 qemu_free(sn_tab);
bellard8a7ddc32004-03-31 19:00:16 +00006825}
6826
6827/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006828/* ram save/restore */
6829
bellard8a7ddc32004-03-31 19:00:16 +00006830static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6831{
6832 int v;
6833
6834 v = qemu_get_byte(f);
6835 switch(v) {
6836 case 0:
6837 if (qemu_get_buffer(f, buf, len) != len)
6838 return -EIO;
6839 break;
6840 case 1:
6841 v = qemu_get_byte(f);
6842 memset(buf, v, len);
6843 break;
6844 default:
6845 return -EINVAL;
6846 }
6847 return 0;
6848}
6849
bellardc88676f2006-08-06 13:36:11 +00006850static int ram_load_v1(QEMUFile *f, void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00006851{
aurel3200f82b82008-04-27 21:12:55 +00006852 int ret;
6853 ram_addr_t i;
bellard8a7ddc32004-03-31 19:00:16 +00006854
bellard8a7ddc32004-03-31 19:00:16 +00006855 if (qemu_get_be32(f) != phys_ram_size)
6856 return -EINVAL;
6857 for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6858 ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6859 if (ret)
6860 return ret;
6861 }
6862 return 0;
6863}
6864
bellardc88676f2006-08-06 13:36:11 +00006865#define BDRV_HASH_BLOCK_SIZE 1024
6866#define IOBUF_SIZE 4096
6867#define RAM_CBLOCK_MAGIC 0xfabe
6868
6869typedef struct RamCompressState {
6870 z_stream zstream;
6871 QEMUFile *f;
6872 uint8_t buf[IOBUF_SIZE];
6873} RamCompressState;
6874
6875static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6876{
6877 int ret;
6878 memset(s, 0, sizeof(*s));
6879 s->f = f;
6880 ret = deflateInit2(&s->zstream, 1,
ths5fafdf22007-09-16 21:08:06 +00006881 Z_DEFLATED, 15,
bellardc88676f2006-08-06 13:36:11 +00006882 9, Z_DEFAULT_STRATEGY);
6883 if (ret != Z_OK)
6884 return -1;
6885 s->zstream.avail_out = IOBUF_SIZE;
6886 s->zstream.next_out = s->buf;
6887 return 0;
6888}
6889
6890static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6891{
6892 qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6893 qemu_put_be16(s->f, len);
6894 qemu_put_buffer(s->f, buf, len);
6895}
6896
6897static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6898{
6899 int ret;
6900
6901 s->zstream.avail_in = len;
6902 s->zstream.next_in = (uint8_t *)buf;
6903 while (s->zstream.avail_in > 0) {
6904 ret = deflate(&s->zstream, Z_NO_FLUSH);
6905 if (ret != Z_OK)
6906 return -1;
6907 if (s->zstream.avail_out == 0) {
6908 ram_put_cblock(s, s->buf, IOBUF_SIZE);
6909 s->zstream.avail_out = IOBUF_SIZE;
6910 s->zstream.next_out = s->buf;
6911 }
6912 }
6913 return 0;
6914}
6915
6916static void ram_compress_close(RamCompressState *s)
6917{
6918 int len, ret;
6919
6920 /* compress last bytes */
6921 for(;;) {
6922 ret = deflate(&s->zstream, Z_FINISH);
6923 if (ret == Z_OK || ret == Z_STREAM_END) {
6924 len = IOBUF_SIZE - s->zstream.avail_out;
6925 if (len > 0) {
6926 ram_put_cblock(s, s->buf, len);
6927 }
6928 s->zstream.avail_out = IOBUF_SIZE;
6929 s->zstream.next_out = s->buf;
6930 if (ret == Z_STREAM_END)
6931 break;
6932 } else {
6933 goto fail;
6934 }
6935 }
6936fail:
6937 deflateEnd(&s->zstream);
6938}
6939
6940typedef struct RamDecompressState {
6941 z_stream zstream;
6942 QEMUFile *f;
6943 uint8_t buf[IOBUF_SIZE];
6944} RamDecompressState;
6945
6946static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6947{
6948 int ret;
6949 memset(s, 0, sizeof(*s));
6950 s->f = f;
6951 ret = inflateInit(&s->zstream);
6952 if (ret != Z_OK)
6953 return -1;
6954 return 0;
6955}
6956
6957static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6958{
6959 int ret, clen;
6960
6961 s->zstream.avail_out = len;
6962 s->zstream.next_out = buf;
6963 while (s->zstream.avail_out > 0) {
6964 if (s->zstream.avail_in == 0) {
6965 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6966 return -1;
6967 clen = qemu_get_be16(s->f);
6968 if (clen > IOBUF_SIZE)
6969 return -1;
6970 qemu_get_buffer(s->f, s->buf, clen);
6971 s->zstream.avail_in = clen;
6972 s->zstream.next_in = s->buf;
6973 }
6974 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6975 if (ret != Z_OK && ret != Z_STREAM_END) {
6976 return -1;
6977 }
6978 }
6979 return 0;
6980}
6981
6982static void ram_decompress_close(RamDecompressState *s)
6983{
6984 inflateEnd(&s->zstream);
6985}
6986
6987static void ram_save(QEMUFile *f, void *opaque)
6988{
aurel3200f82b82008-04-27 21:12:55 +00006989 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00006990 RamCompressState s1, *s = &s1;
6991 uint8_t buf[10];
ths3b46e622007-09-17 08:09:54 +00006992
bellardc88676f2006-08-06 13:36:11 +00006993 qemu_put_be32(f, phys_ram_size);
6994 if (ram_compress_open(s, f) < 0)
6995 return;
6996 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6997#if 0
6998 if (tight_savevm_enabled) {
6999 int64_t sector_num;
7000 int j;
7001
7002 /* find if the memory block is available on a virtual
7003 block device */
7004 sector_num = -1;
thse4bcb142007-12-02 04:51:10 +00007005 for(j = 0; j < nb_drives; j++) {
7006 sector_num = bdrv_hash_find(drives_table[j].bdrv,
7007 phys_ram_base + i,
7008 BDRV_HASH_BLOCK_SIZE);
7009 if (sector_num >= 0)
7010 break;
bellardc88676f2006-08-06 13:36:11 +00007011 }
thse4bcb142007-12-02 04:51:10 +00007012 if (j == nb_drives)
bellardc88676f2006-08-06 13:36:11 +00007013 goto normal_compress;
7014 buf[0] = 1;
7015 buf[1] = j;
7016 cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
7017 ram_compress_buf(s, buf, 10);
ths5fafdf22007-09-16 21:08:06 +00007018 } else
bellardc88676f2006-08-06 13:36:11 +00007019#endif
7020 {
7021 // normal_compress:
7022 buf[0] = 0;
7023 ram_compress_buf(s, buf, 1);
7024 ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
7025 }
7026 }
7027 ram_compress_close(s);
7028}
7029
7030static int ram_load(QEMUFile *f, void *opaque, int version_id)
7031{
7032 RamDecompressState s1, *s = &s1;
7033 uint8_t buf[10];
aurel3200f82b82008-04-27 21:12:55 +00007034 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00007035
7036 if (version_id == 1)
7037 return ram_load_v1(f, opaque);
7038 if (version_id != 2)
7039 return -EINVAL;
7040 if (qemu_get_be32(f) != phys_ram_size)
7041 return -EINVAL;
7042 if (ram_decompress_open(s, f) < 0)
7043 return -EINVAL;
7044 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
7045 if (ram_decompress_buf(s, buf, 1) < 0) {
7046 fprintf(stderr, "Error while reading ram block header\n");
7047 goto error;
7048 }
7049 if (buf[0] == 0) {
7050 if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
aurel3200f82b82008-04-27 21:12:55 +00007051 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
bellardc88676f2006-08-06 13:36:11 +00007052 goto error;
7053 }
ths5fafdf22007-09-16 21:08:06 +00007054 } else
bellardc88676f2006-08-06 13:36:11 +00007055#if 0
7056 if (buf[0] == 1) {
7057 int bs_index;
7058 int64_t sector_num;
7059
7060 ram_decompress_buf(s, buf + 1, 9);
7061 bs_index = buf[1];
7062 sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
thse4bcb142007-12-02 04:51:10 +00007063 if (bs_index >= nb_drives) {
bellardc88676f2006-08-06 13:36:11 +00007064 fprintf(stderr, "Invalid block device index %d\n", bs_index);
7065 goto error;
7066 }
thse4bcb142007-12-02 04:51:10 +00007067 if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
7068 phys_ram_base + i,
bellardc88676f2006-08-06 13:36:11 +00007069 BDRV_HASH_BLOCK_SIZE / 512) < 0) {
ths5fafdf22007-09-16 21:08:06 +00007070 fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
bellardc88676f2006-08-06 13:36:11 +00007071 bs_index, sector_num);
7072 goto error;
7073 }
ths5fafdf22007-09-16 21:08:06 +00007074 } else
bellardc88676f2006-08-06 13:36:11 +00007075#endif
7076 {
7077 error:
7078 printf("Error block header\n");
7079 return -EINVAL;
7080 }
7081 }
7082 ram_decompress_close(s);
7083 return 0;
7084}
7085
bellard8a7ddc32004-03-31 19:00:16 +00007086/***********************************************************/
bellard83f64092006-08-01 16:21:11 +00007087/* bottom halves (can be seen as timers which expire ASAP) */
7088
7089struct QEMUBH {
7090 QEMUBHFunc *cb;
7091 void *opaque;
7092 int scheduled;
7093 QEMUBH *next;
7094};
7095
7096static QEMUBH *first_bh = NULL;
7097
7098QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
7099{
7100 QEMUBH *bh;
7101 bh = qemu_mallocz(sizeof(QEMUBH));
7102 if (!bh)
7103 return NULL;
7104 bh->cb = cb;
7105 bh->opaque = opaque;
7106 return bh;
7107}
7108
bellard6eb57332006-08-06 09:51:25 +00007109int qemu_bh_poll(void)
bellard83f64092006-08-01 16:21:11 +00007110{
7111 QEMUBH *bh, **pbh;
bellard6eb57332006-08-06 09:51:25 +00007112 int ret;
bellard83f64092006-08-01 16:21:11 +00007113
bellard6eb57332006-08-06 09:51:25 +00007114 ret = 0;
bellard83f64092006-08-01 16:21:11 +00007115 for(;;) {
7116 pbh = &first_bh;
7117 bh = *pbh;
7118 if (!bh)
7119 break;
bellard6eb57332006-08-06 09:51:25 +00007120 ret = 1;
bellard83f64092006-08-01 16:21:11 +00007121 *pbh = bh->next;
7122 bh->scheduled = 0;
7123 bh->cb(bh->opaque);
7124 }
bellard6eb57332006-08-06 09:51:25 +00007125 return ret;
bellard83f64092006-08-01 16:21:11 +00007126}
7127
7128void qemu_bh_schedule(QEMUBH *bh)
7129{
7130 CPUState *env = cpu_single_env;
7131 if (bh->scheduled)
7132 return;
7133 bh->scheduled = 1;
7134 bh->next = first_bh;
7135 first_bh = bh;
7136
7137 /* stop the currently executing CPU to execute the BH ASAP */
7138 if (env) {
7139 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
7140 }
7141}
7142
7143void qemu_bh_cancel(QEMUBH *bh)
7144{
7145 QEMUBH **pbh;
7146 if (bh->scheduled) {
7147 pbh = &first_bh;
7148 while (*pbh != bh)
7149 pbh = &(*pbh)->next;
7150 *pbh = bh->next;
7151 bh->scheduled = 0;
7152 }
7153}
7154
7155void qemu_bh_delete(QEMUBH *bh)
7156{
7157 qemu_bh_cancel(bh);
7158 qemu_free(bh);
7159}
7160
7161/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00007162/* machine registration */
7163
7164QEMUMachine *first_machine = NULL;
7165
7166int qemu_register_machine(QEMUMachine *m)
7167{
7168 QEMUMachine **pm;
7169 pm = &first_machine;
7170 while (*pm != NULL)
7171 pm = &(*pm)->next;
7172 m->next = NULL;
7173 *pm = m;
7174 return 0;
7175}
7176
pbrook9596ebb2007-11-18 01:44:38 +00007177static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00007178{
7179 QEMUMachine *m;
7180
7181 for(m = first_machine; m != NULL; m = m->next) {
7182 if (!strcmp(m->name, name))
7183 return m;
7184 }
7185 return NULL;
7186}
7187
7188/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00007189/* main execution loop */
7190
pbrook9596ebb2007-11-18 01:44:38 +00007191static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00007192{
ths740733b2007-06-08 01:57:56 +00007193 DisplayState *ds = opaque;
7194 ds->dpy_refresh(ds);
aurel32f442e082008-03-13 19:20:33 +00007195 qemu_mod_timer(ds->gui_timer,
7196 (ds->gui_timer_interval ?
7197 ds->gui_timer_interval :
7198 GUI_REFRESH_INTERVAL)
7199 + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00007200}
7201
bellard0bd48852005-11-11 00:00:47 +00007202struct vm_change_state_entry {
7203 VMChangeStateHandler *cb;
7204 void *opaque;
7205 LIST_ENTRY (vm_change_state_entry) entries;
7206};
7207
7208static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
7209
7210VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
7211 void *opaque)
7212{
7213 VMChangeStateEntry *e;
7214
7215 e = qemu_mallocz(sizeof (*e));
7216 if (!e)
7217 return NULL;
7218
7219 e->cb = cb;
7220 e->opaque = opaque;
7221 LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
7222 return e;
7223}
7224
7225void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
7226{
7227 LIST_REMOVE (e, entries);
7228 qemu_free (e);
7229}
7230
7231static void vm_state_notify(int running)
7232{
7233 VMChangeStateEntry *e;
7234
7235 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
7236 e->cb(e->opaque, running);
7237 }
7238}
7239
bellard8a7ddc32004-03-31 19:00:16 +00007240/* XXX: support several handlers */
bellard0bd48852005-11-11 00:00:47 +00007241static VMStopHandler *vm_stop_cb;
7242static void *vm_stop_opaque;
bellard8a7ddc32004-03-31 19:00:16 +00007243
7244int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
7245{
7246 vm_stop_cb = cb;
7247 vm_stop_opaque = opaque;
7248 return 0;
7249}
7250
7251void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
7252{
7253 vm_stop_cb = NULL;
7254}
7255
7256void vm_start(void)
7257{
7258 if (!vm_running) {
7259 cpu_enable_ticks();
7260 vm_running = 1;
bellard0bd48852005-11-11 00:00:47 +00007261 vm_state_notify(1);
thsefe75412007-08-24 01:36:32 +00007262 qemu_rearm_alarm_timer(alarm_timer);
bellard8a7ddc32004-03-31 19:00:16 +00007263 }
7264}
7265
ths5fafdf22007-09-16 21:08:06 +00007266void vm_stop(int reason)
bellard8a7ddc32004-03-31 19:00:16 +00007267{
7268 if (vm_running) {
7269 cpu_disable_ticks();
7270 vm_running = 0;
7271 if (reason != 0) {
7272 if (vm_stop_cb) {
7273 vm_stop_cb(vm_stop_opaque, reason);
7274 }
7275 }
bellard0bd48852005-11-11 00:00:47 +00007276 vm_state_notify(0);
bellard8a7ddc32004-03-31 19:00:16 +00007277 }
7278}
7279
bellardbb0c6722004-06-20 12:37:32 +00007280/* reset/shutdown handler */
7281
7282typedef struct QEMUResetEntry {
7283 QEMUResetHandler *func;
7284 void *opaque;
7285 struct QEMUResetEntry *next;
7286} QEMUResetEntry;
7287
7288static QEMUResetEntry *first_reset_entry;
7289static int reset_requested;
7290static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00007291static int powerdown_requested;
bellardbb0c6722004-06-20 12:37:32 +00007292
aurel32cf7a2fe2008-03-18 06:53:05 +00007293int qemu_shutdown_requested(void)
7294{
7295 int r = shutdown_requested;
7296 shutdown_requested = 0;
7297 return r;
7298}
7299
7300int qemu_reset_requested(void)
7301{
7302 int r = reset_requested;
7303 reset_requested = 0;
7304 return r;
7305}
7306
7307int qemu_powerdown_requested(void)
7308{
7309 int r = powerdown_requested;
7310 powerdown_requested = 0;
7311 return r;
7312}
7313
bellardbb0c6722004-06-20 12:37:32 +00007314void qemu_register_reset(QEMUResetHandler *func, void *opaque)
7315{
7316 QEMUResetEntry **pre, *re;
7317
7318 pre = &first_reset_entry;
7319 while (*pre != NULL)
7320 pre = &(*pre)->next;
7321 re = qemu_mallocz(sizeof(QEMUResetEntry));
7322 re->func = func;
7323 re->opaque = opaque;
7324 re->next = NULL;
7325 *pre = re;
7326}
7327
aurel32cf7a2fe2008-03-18 06:53:05 +00007328void qemu_system_reset(void)
bellardbb0c6722004-06-20 12:37:32 +00007329{
7330 QEMUResetEntry *re;
7331
7332 /* reset all devices */
7333 for(re = first_reset_entry; re != NULL; re = re->next) {
7334 re->func(re->opaque);
7335 }
7336}
7337
7338void qemu_system_reset_request(void)
7339{
bellardd1beab82006-10-02 19:44:22 +00007340 if (no_reboot) {
7341 shutdown_requested = 1;
7342 } else {
7343 reset_requested = 1;
7344 }
bellard6a00d602005-11-21 23:25:50 +00007345 if (cpu_single_env)
7346 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007347}
7348
7349void qemu_system_shutdown_request(void)
7350{
7351 shutdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007352 if (cpu_single_env)
7353 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007354}
7355
bellard34751872005-07-02 14:31:34 +00007356void qemu_system_powerdown_request(void)
7357{
7358 powerdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007359 if (cpu_single_env)
7360 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007361}
7362
bellard5905b2e2004-08-01 21:53:26 +00007363void main_loop_wait(int timeout)
bellard8a7ddc32004-03-31 19:00:16 +00007364{
thscafffd42007-02-28 21:59:44 +00007365 IOHandlerRecord *ioh;
bellarde0356492006-05-01 13:33:02 +00007366 fd_set rfds, wfds, xfds;
ths877cf882007-04-18 18:11:47 +00007367 int ret, nfds;
7368#ifdef _WIN32
7369 int ret2, i;
7370#endif
bellardfd1dff42006-02-01 21:29:26 +00007371 struct timeval tv;
bellardf3311102006-04-12 20:21:17 +00007372 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00007373
bellardf3311102006-04-12 20:21:17 +00007374
7375 /* XXX: need to suppress polling by better using win32 events */
7376 ret = 0;
7377 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
7378 ret |= pe->func(pe->opaque);
7379 }
bellard38e205a2004-04-06 19:29:17 +00007380#ifdef _WIN32
thse6b1e552007-04-18 17:56:02 +00007381 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00007382 int err;
7383 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00007384
bellarda18e5242006-06-25 17:18:27 +00007385 ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
7386 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
7387 if (w->func[ret - WAIT_OBJECT_0])
7388 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00007389
ths5fafdf22007-09-16 21:08:06 +00007390 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00007391 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00007392
thse6b1e552007-04-18 17:56:02 +00007393 /* Check if event is signaled */
7394 ret2 = WaitForSingleObject(w->events[i], 0);
7395 if(ret2 == WAIT_OBJECT_0) {
7396 if (w->func[i])
7397 w->func[i](w->opaque[i]);
7398 } else if (ret2 == WAIT_TIMEOUT) {
7399 } else {
7400 err = GetLastError();
7401 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00007402 }
7403 }
bellarda18e5242006-06-25 17:18:27 +00007404 } else if (ret == WAIT_TIMEOUT) {
7405 } else {
7406 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00007407 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00007408 }
bellardf3311102006-04-12 20:21:17 +00007409 }
bellardfd1dff42006-02-01 21:29:26 +00007410#endif
7411 /* poll any events */
7412 /* XXX: separate device handlers from system ones */
7413 nfds = -1;
7414 FD_ZERO(&rfds);
7415 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00007416 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00007417 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00007418 if (ioh->deleted)
7419 continue;
bellardfd1dff42006-02-01 21:29:26 +00007420 if (ioh->fd_read &&
7421 (!ioh->fd_read_poll ||
7422 ioh->fd_read_poll(ioh->opaque) != 0)) {
7423 FD_SET(ioh->fd, &rfds);
7424 if (ioh->fd > nfds)
7425 nfds = ioh->fd;
7426 }
7427 if (ioh->fd_write) {
7428 FD_SET(ioh->fd, &wfds);
7429 if (ioh->fd > nfds)
7430 nfds = ioh->fd;
7431 }
7432 }
ths3b46e622007-09-17 08:09:54 +00007433
bellardfd1dff42006-02-01 21:29:26 +00007434 tv.tv_sec = 0;
7435#ifdef _WIN32
7436 tv.tv_usec = 0;
bellard38e205a2004-04-06 19:29:17 +00007437#else
bellardfd1dff42006-02-01 21:29:26 +00007438 tv.tv_usec = timeout * 1000;
7439#endif
bellarde0356492006-05-01 13:33:02 +00007440#if defined(CONFIG_SLIRP)
7441 if (slirp_inited) {
7442 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
7443 }
7444#endif
7445 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
bellardfd1dff42006-02-01 21:29:26 +00007446 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00007447 IOHandlerRecord **pioh;
7448
7449 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00007450 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007451 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00007452 }
ths6ab43fd2007-08-25 01:34:19 +00007453 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007454 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00007455 }
7456 }
thscafffd42007-02-28 21:59:44 +00007457
7458 /* remove deleted IO handlers */
7459 pioh = &first_io_handler;
7460 while (*pioh) {
7461 ioh = *pioh;
7462 if (ioh->deleted) {
7463 *pioh = ioh->next;
7464 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00007465 } else
thscafffd42007-02-28 21:59:44 +00007466 pioh = &ioh->next;
7467 }
bellardfd1dff42006-02-01 21:29:26 +00007468 }
bellarde0356492006-05-01 13:33:02 +00007469#if defined(CONFIG_SLIRP)
7470 if (slirp_inited) {
7471 if (ret < 0) {
7472 FD_ZERO(&rfds);
7473 FD_ZERO(&wfds);
7474 FD_ZERO(&xfds);
7475 }
7476 slirp_select_poll(&rfds, &wfds, &xfds);
7477 }
7478#endif
bellardc20709a2004-04-21 23:27:19 +00007479
bellardfd1dff42006-02-01 21:29:26 +00007480 if (vm_running) {
edgar_igl21b20812008-05-15 19:54:00 +00007481 if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
ths5fafdf22007-09-16 21:08:06 +00007482 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
bellardfd1dff42006-02-01 21:29:26 +00007483 qemu_get_clock(vm_clock));
7484 /* run dma transfers, if any */
7485 DMA_run();
7486 }
pbrook423f0742007-05-23 00:06:54 +00007487
bellardfd1dff42006-02-01 21:29:26 +00007488 /* real time timers */
ths5fafdf22007-09-16 21:08:06 +00007489 qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
bellardfd1dff42006-02-01 21:29:26 +00007490 qemu_get_clock(rt_clock));
pbrook423f0742007-05-23 00:06:54 +00007491
balrogd5d08332008-01-05 19:41:47 +00007492 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
7493 alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED);
7494 qemu_rearm_alarm_timer(alarm_timer);
7495 }
balrogb99dc0d2007-12-16 13:17:12 +00007496
pbrook423f0742007-05-23 00:06:54 +00007497 /* Check bottom-halves last in case any of the earlier events triggered
7498 them. */
7499 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00007500
bellard5905b2e2004-08-01 21:53:26 +00007501}
7502
pbrook9596ebb2007-11-18 01:44:38 +00007503static int main_loop(void)
bellard5905b2e2004-08-01 21:53:26 +00007504{
7505 int ret, timeout;
bellard89bfc102006-02-08 22:46:31 +00007506#ifdef CONFIG_PROFILER
7507 int64_t ti;
7508#endif
bellard6a00d602005-11-21 23:25:50 +00007509 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00007510
bellard6a00d602005-11-21 23:25:50 +00007511 cur_cpu = first_cpu;
balrogee5605e2007-12-03 03:01:40 +00007512 next_cpu = cur_cpu->next_cpu ?: first_cpu;
bellard5905b2e2004-08-01 21:53:26 +00007513 for(;;) {
7514 if (vm_running) {
bellard15a76442005-11-23 21:01:03 +00007515
bellard15a76442005-11-23 21:01:03 +00007516 for(;;) {
7517 /* get next cpu */
balrogee5605e2007-12-03 03:01:40 +00007518 env = next_cpu;
bellard89bfc102006-02-08 22:46:31 +00007519#ifdef CONFIG_PROFILER
7520 ti = profile_getclock();
7521#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007522 if (use_icount) {
7523 int64_t count;
7524 int decr;
7525 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
7526 env->icount_decr.u16.low = 0;
7527 env->icount_extra = 0;
7528 count = qemu_next_deadline();
7529 count = (count + (1 << icount_time_shift) - 1)
7530 >> icount_time_shift;
7531 qemu_icount += count;
7532 decr = (count > 0xffff) ? 0xffff : count;
7533 count -= decr;
7534 env->icount_decr.u16.low = decr;
7535 env->icount_extra = count;
7536 }
bellard6a00d602005-11-21 23:25:50 +00007537 ret = cpu_exec(env);
bellard89bfc102006-02-08 22:46:31 +00007538#ifdef CONFIG_PROFILER
7539 qemu_time += profile_getclock() - ti;
7540#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007541 if (use_icount) {
7542 /* Fold pending instructions back into the
7543 instruction counter, and clear the interrupt flag. */
7544 qemu_icount -= (env->icount_decr.u16.low
7545 + env->icount_extra);
7546 env->icount_decr.u32 = 0;
7547 env->icount_extra = 0;
7548 }
balrogee5605e2007-12-03 03:01:40 +00007549 next_cpu = env->next_cpu ?: first_cpu;
aurel3295b01002008-04-04 17:16:35 +00007550 if (event_pending && likely(ret != EXCP_DEBUG)) {
balrogee5605e2007-12-03 03:01:40 +00007551 ret = EXCP_INTERRUPT;
7552 event_pending = 0;
7553 break;
7554 }
pbrookbd967e02007-03-11 18:54:57 +00007555 if (ret == EXCP_HLT) {
7556 /* Give the next CPU a chance to run. */
7557 cur_cpu = env;
7558 continue;
7559 }
bellard15a76442005-11-23 21:01:03 +00007560 if (ret != EXCP_HALTED)
7561 break;
7562 /* all CPUs are halted ? */
pbrookbd967e02007-03-11 18:54:57 +00007563 if (env == cur_cpu)
bellard15a76442005-11-23 21:01:03 +00007564 break;
bellard15a76442005-11-23 21:01:03 +00007565 }
7566 cur_cpu = env;
7567
bellard5905b2e2004-08-01 21:53:26 +00007568 if (shutdown_requested) {
bellard34751872005-07-02 14:31:34 +00007569 ret = EXCP_INTERRUPT;
aurel32b2f76162008-04-11 21:35:52 +00007570 if (no_shutdown) {
7571 vm_stop(0);
7572 no_shutdown = 0;
7573 }
7574 else
7575 break;
bellard5905b2e2004-08-01 21:53:26 +00007576 }
7577 if (reset_requested) {
7578 reset_requested = 0;
7579 qemu_system_reset();
bellard34751872005-07-02 14:31:34 +00007580 ret = EXCP_INTERRUPT;
7581 }
7582 if (powerdown_requested) {
7583 powerdown_requested = 0;
7584 qemu_system_powerdown();
7585 ret = EXCP_INTERRUPT;
bellard5905b2e2004-08-01 21:53:26 +00007586 }
aurel3295b01002008-04-04 17:16:35 +00007587 if (unlikely(ret == EXCP_DEBUG)) {
bellard5905b2e2004-08-01 21:53:26 +00007588 vm_stop(EXCP_DEBUG);
7589 }
pbrookbd967e02007-03-11 18:54:57 +00007590 /* If all cpus are halted then wait until the next IRQ */
bellard5905b2e2004-08-01 21:53:26 +00007591 /* XXX: use timeout computed from timers */
pbrook2e70f6e2008-06-29 01:03:05 +00007592 if (ret == EXCP_HALTED) {
7593 if (use_icount) {
7594 int64_t add;
7595 int64_t delta;
7596 /* Advance virtual time to the next event. */
7597 if (use_icount == 1) {
7598 /* When not using an adaptive execution frequency
7599 we tend to get badly out of sync with real time,
thsbf20dc02008-06-30 17:22:19 +00007600 so just delay for a reasonable amount of time. */
pbrook2e70f6e2008-06-29 01:03:05 +00007601 delta = 0;
7602 } else {
7603 delta = cpu_get_icount() - cpu_get_clock();
7604 }
7605 if (delta > 0) {
7606 /* If virtual time is ahead of real time then just
7607 wait for IO. */
7608 timeout = (delta / 1000000) + 1;
7609 } else {
7610 /* Wait for either IO to occur or the next
7611 timer event. */
7612 add = qemu_next_deadline();
7613 /* We advance the timer before checking for IO.
7614 Limit the amount we advance so that early IO
7615 activity won't get the guest too far ahead. */
7616 if (add > 10000000)
7617 add = 10000000;
7618 delta += add;
7619 add = (add + (1 << icount_time_shift) - 1)
7620 >> icount_time_shift;
7621 qemu_icount += add;
7622 timeout = delta / 1000000;
7623 if (timeout < 0)
7624 timeout = 0;
7625 }
7626 } else {
7627 timeout = 10;
7628 }
7629 } else {
bellard5905b2e2004-08-01 21:53:26 +00007630 timeout = 0;
pbrook2e70f6e2008-06-29 01:03:05 +00007631 }
bellard5905b2e2004-08-01 21:53:26 +00007632 } else {
aliguori5b08fc12008-08-21 20:08:03 +00007633 if (shutdown_requested)
7634 break;
bellard5905b2e2004-08-01 21:53:26 +00007635 timeout = 10;
7636 }
bellard89bfc102006-02-08 22:46:31 +00007637#ifdef CONFIG_PROFILER
7638 ti = profile_getclock();
7639#endif
bellard5905b2e2004-08-01 21:53:26 +00007640 main_loop_wait(timeout);
bellard89bfc102006-02-08 22:46:31 +00007641#ifdef CONFIG_PROFILER
7642 dev_time += profile_getclock() - ti;
7643#endif
bellardb4608c02003-06-27 17:34:32 +00007644 }
bellard34865132003-10-05 14:28:56 +00007645 cpu_disable_ticks();
7646 return ret;
bellardb4608c02003-06-27 17:34:32 +00007647}
7648
ths15f82202007-06-29 23:26:08 +00007649static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00007650{
bellard68d0f702008-01-06 17:21:48 +00007651 printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
bellard0db63472003-10-27 21:37:46 +00007652 "usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00007653 "\n"
bellarda20dd502003-09-30 21:07:02 +00007654 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00007655 "\n"
bellarda20dd502003-09-30 21:07:02 +00007656 "Standard options:\n"
bellardcc1daa42005-06-05 14:49:17 +00007657 "-M machine select emulated machine (-M ? for list)\n"
pbrook5adb4832007-03-08 03:15:18 +00007658 "-cpu cpu select CPU (-cpu ? for list)\n"
bellardc45886d2004-01-05 00:02:06 +00007659 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
bellard36b486b2003-11-11 13:36:08 +00007660 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
7661 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007662 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
aurel32a1620fa2008-04-29 05:58:01 +00007663 "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
7664 " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
7665 " [,cache=on|off][,format=f]\n"
thse4bcb142007-12-02 04:51:10 +00007666 " use 'file' as a drive image\n"
balrog3e3d5812007-04-30 02:09:25 +00007667 "-mtdblock file use 'file' as on-board Flash memory image\n"
pbrooka1bb27b2007-04-06 16:49:48 +00007668 "-sd file use 'file' as SecureDigital card image\n"
j_mayer86f55662007-04-24 06:52:59 +00007669 "-pflash file use 'file' as a parallel flash image\n"
thseec85c22007-01-05 17:41:07 +00007670 "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
ths667acca2006-12-11 02:08:05 +00007671 "-snapshot write to temporary files instead of disk image files\n"
7672#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007673 "-no-frame open SDL window without a frame and window decorations\n"
ths3780e192007-06-21 21:08:02 +00007674 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
ths667acca2006-12-11 02:08:05 +00007675 "-no-quit disable SDL window close capability\n"
7676#endif
bellard52ca8d62006-06-14 16:03:05 +00007677#ifdef TARGET_I386
7678 "-no-fd-bootchk disable boot signature checking for floppy disks\n"
7679#endif
bellarda00bad72004-05-22 21:39:06 +00007680 "-m megs set virtual RAM size to megs MB [default=%d]\n"
bellard91fc2112005-12-18 19:09:37 +00007681 "-smp n set the number of CPUs to 'n' [default=1]\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007682 "-nographic disable graphical output and redirect serial I/Os to console\n"
balroga171fe32007-04-30 01:48:07 +00007683 "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
bellard4ca00742004-12-12 22:20:04 +00007684#ifndef _WIN32
ths667acca2006-12-11 02:08:05 +00007685 "-k language use keyboard layout (for example \"fr\" for French)\n"
bellard4ca00742004-12-12 22:20:04 +00007686#endif
bellard1d14ffa2005-10-30 18:58:22 +00007687#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007688 "-audio-help print list of audio drivers and their options\n"
bellardc0fe3822005-11-05 18:55:28 +00007689 "-soundhw c1,... enable audio support\n"
7690 " and only specified sound cards (comma separated list)\n"
7691 " use -soundhw ? to get the list of supported cards\n"
bellard6a36d842005-12-18 20:34:32 +00007692 " use -soundhw all to enable all of them\n"
bellard1d14ffa2005-10-30 18:58:22 +00007693#endif
bellard89980282004-06-03 14:04:03 +00007694 "-localtime set the real time clock to local time [default=utc]\n"
bellardd63d3072004-10-03 13:29:03 +00007695 "-full-screen start in full screen\n"
bellarda09db212005-04-30 16:10:35 +00007696#ifdef TARGET_I386
7697 "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
7698#endif
bellardb389dbf2005-11-06 16:49:55 +00007699 "-usb enable the USB driver (will be the default soon)\n"
7700 "-usbdevice name add the host or guest USB device 'name'\n"
bellard6f7e9ae2005-03-13 09:43:36 +00007701#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7702 "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
bellardbb0c6722004-06-20 12:37:32 +00007703#endif
thsc35734b2007-03-19 15:17:08 +00007704 "-name string set the name of the guest\n"
blueswir18fcb1b92008-09-18 18:29:08 +00007705 "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
bellarda20dd502003-09-30 21:07:02 +00007706 "\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007707 "Network options:\n"
pbrooka41b2ff2006-02-05 04:14:41 +00007708 "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007709 " create a new Network Interface Card and connect it to VLAN 'n'\n"
bellardc20709a2004-04-21 23:27:19 +00007710#ifdef CONFIG_SLIRP
pbrook115defd2006-04-16 11:06:58 +00007711 "-net user[,vlan=n][,hostname=host]\n"
7712 " connect the user mode network stack to VLAN 'n' and send\n"
7713 " hostname 'host' to DHCP clients\n"
bellard7c9d8e02005-11-15 22:16:05 +00007714#endif
bellard7fb843f2006-02-01 23:06:55 +00007715#ifdef _WIN32
7716 "-net tap[,vlan=n],ifname=name\n"
7717 " connect the host TAP network interface to VLAN 'n'\n"
7718#else
thsb46a8902007-10-21 23:20:45 +00007719 "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7720 " connect the host TAP network interface to VLAN 'n' and use the\n"
7721 " network scripts 'file' (default=%s)\n"
7722 " and 'dfile' (default=%s);\n"
7723 " use '[down]script=no' to disable script execution;\n"
bellard7c9d8e02005-11-15 22:16:05 +00007724 " use 'fd=h' to connect to an already opened TAP interface\n"
bellard7fb843f2006-02-01 23:06:55 +00007725#endif
bellard6a00d602005-11-21 23:25:50 +00007726 "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007727 " connect the vlan 'n' to another VLAN using a socket connection\n"
bellard3d830452005-12-18 16:36:49 +00007728 "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7729 " connect the vlan 'n' to multicast maddr and port\n"
ths8a16d272008-07-19 09:56:24 +00007730#ifdef CONFIG_VDE
7731 "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
7732 " connect the vlan 'n' to port 'n' of a vde switch running\n"
7733 " on host and listening for incoming connections on 'socketpath'.\n"
7734 " Use group 'groupname' and mode 'octalmode' to change default\n"
7735 " ownership and permissions for communication port.\n"
7736#endif
bellard7c9d8e02005-11-15 22:16:05 +00007737 "-net none use it alone to have zero network devices; if no -net option\n"
7738 " is provided, the default is '-net nic -net user'\n"
7739 "\n"
7740#ifdef CONFIG_SLIRP
ths0db11372007-02-20 00:12:07 +00007741 "-tftp dir allow tftp access to files in dir [-net user]\n"
ths47d5d012007-02-20 00:05:08 +00007742 "-bootp file advertise file in BOOTP replies\n"
bellard7c9d8e02005-11-15 22:16:05 +00007743#ifndef _WIN32
7744 "-smb dir allow SMB access to files in 'dir' [-net user]\n"
bellardc94c8d62004-09-13 21:37:34 +00007745#endif
bellard9bf05442004-08-25 22:12:49 +00007746 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
bellard7c9d8e02005-11-15 22:16:05 +00007747 " redirect TCP or UDP connections from host to guest [-net user]\n"
bellardc20709a2004-04-21 23:27:19 +00007748#endif
bellardc4b1fcc2004-03-14 21:44:30 +00007749 "\n"
7750 "Linux boot specific:\n"
bellarda20dd502003-09-30 21:07:02 +00007751 "-kernel bzImage use 'bzImage' as kernel image\n"
7752 "-append cmdline use 'cmdline' as kernel command line\n"
7753 "-initrd file use 'file' as initial ram disk\n"
bellardfc01f7e2003-06-30 10:03:06 +00007754 "\n"
bellard330d0412003-07-26 18:11:40 +00007755 "Debug/Expert options:\n"
bellard82c643f2004-07-14 17:28:13 +00007756 "-monitor dev redirect the monitor to char device 'dev'\n"
7757 "-serial dev redirect the serial port to char device 'dev'\n"
bellard6508fe52005-01-15 12:02:56 +00007758 "-parallel dev redirect the parallel port to char device 'dev'\n"
bellardf7cce892004-12-08 22:21:25 +00007759 "-pidfile file Write PID to 'file'\n"
bellardcd6f1162004-05-13 22:02:20 +00007760 "-S freeze CPU at startup (use 'c' to start execution)\n"
pbrookcfc34752007-02-22 01:48:01 +00007761 "-s wait gdb connection to port\n"
7762 "-p port set gdb connection port [default=%s]\n"
bellardf193c792004-03-21 17:06:25 +00007763 "-d item1,... output log to %s (use -d ? for a list of log items)\n"
bellard46d47672004-11-16 01:45:27 +00007764 "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
7765 " translation (t=none or lba) (usually qemu can guess them)\n"
bellard87b47352006-08-17 17:22:54 +00007766 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
bellardd993e022005-02-10 22:00:06 +00007767#ifdef USE_KQEMU
bellard6515b202006-05-03 22:02:44 +00007768 "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
bellardd993e022005-02-10 22:00:06 +00007769 "-no-kqemu disable KQEMU kernel module usage\n"
7770#endif
bellardbb0c6722004-06-20 12:37:32 +00007771#ifdef TARGET_I386
bellard1bfe8562004-07-08 21:17:50 +00007772 "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
7773 " (default is CL-GD5446 PCI VGA)\n"
bellard6515b202006-05-03 22:02:44 +00007774 "-no-acpi disable ACPI\n"
bellardbb0c6722004-06-20 12:37:32 +00007775#endif
balrog4d3b6f62008-02-10 16:33:14 +00007776#ifdef CONFIG_CURSES
7777 "-curses use a curses/ncurses interface instead of SDL\n"
7778#endif
bellardd1beab82006-10-02 19:44:22 +00007779 "-no-reboot exit instead of rebooting\n"
aurel32b2f76162008-04-11 21:35:52 +00007780 "-no-shutdown stop before shutdown\n"
aurel32a8080002008-05-10 23:28:26 +00007781 "-loadvm [tag|id] start right away with a saved state (loadvm in monitor)\n"
bellard24236862006-04-30 21:28:36 +00007782 "-vnc display start a VNC server on display\n"
ths71e3ceb2006-12-22 02:11:31 +00007783#ifndef _WIN32
7784 "-daemonize daemonize QEMU after initializing\n"
7785#endif
ths9ae02552007-01-05 17:39:04 +00007786 "-option-rom rom load a file, rom, into the option ROM space\n"
blueswir166508602007-05-01 14:16:52 +00007787#ifdef TARGET_SPARC
7788 "-prom-env variable=value set OpenBIOS nvram variables\n"
7789#endif
thsf3dcfad2007-08-24 01:26:02 +00007790 "-clock force the use of the given methods for timer alarm.\n"
aurel323adda042008-03-09 23:43:49 +00007791 " To see what timers are available use -clock ?\n"
bellardbce61842008-02-01 22:18:51 +00007792 "-startdate select initial date of the clock\n"
pbrook2e70f6e2008-06-29 01:03:05 +00007793 "-icount [N|auto]\n"
pbrookdd5d6fe2008-06-29 10:43:16 +00007794 " Enable virtual instruction counter with 2^N clock ticks per instruction\n"
bellard0824d6f2003-06-24 13:42:40 +00007795 "\n"
bellard82c643f2004-07-14 17:28:13 +00007796 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00007797 "ctrl-alt-f toggle full screen\n"
7798 "ctrl-alt-n switch to virtual console 'n'\n"
7799 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00007800 "\n"
7801 "When using -nographic, press 'ctrl-a h' to get some help.\n"
7802 ,
bellard0db63472003-10-27 21:37:46 +00007803 "qemu",
bellarda00bad72004-05-22 21:39:06 +00007804 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00007805#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00007806 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00007807 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00007808#endif
bellard6e44ba72004-01-18 21:56:49 +00007809 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00007810 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00007811 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00007812}
7813
bellardcd6f1162004-05-13 22:02:20 +00007814#define HAS_ARG 0x0001
7815
7816enum {
7817 QEMU_OPTION_h,
7818
bellardcc1daa42005-06-05 14:49:17 +00007819 QEMU_OPTION_M,
j_mayer94fc95c2007-03-05 19:44:02 +00007820 QEMU_OPTION_cpu,
bellardcd6f1162004-05-13 22:02:20 +00007821 QEMU_OPTION_fda,
7822 QEMU_OPTION_fdb,
7823 QEMU_OPTION_hda,
7824 QEMU_OPTION_hdb,
7825 QEMU_OPTION_hdc,
7826 QEMU_OPTION_hdd,
thse4bcb142007-12-02 04:51:10 +00007827 QEMU_OPTION_drive,
bellardcd6f1162004-05-13 22:02:20 +00007828 QEMU_OPTION_cdrom,
balrog3e3d5812007-04-30 02:09:25 +00007829 QEMU_OPTION_mtdblock,
pbrooka1bb27b2007-04-06 16:49:48 +00007830 QEMU_OPTION_sd,
j_mayer86f55662007-04-24 06:52:59 +00007831 QEMU_OPTION_pflash,
bellardcd6f1162004-05-13 22:02:20 +00007832 QEMU_OPTION_boot,
7833 QEMU_OPTION_snapshot,
bellard52ca8d62006-06-14 16:03:05 +00007834#ifdef TARGET_I386
7835 QEMU_OPTION_no_fd_bootchk,
7836#endif
bellardcd6f1162004-05-13 22:02:20 +00007837 QEMU_OPTION_m,
7838 QEMU_OPTION_nographic,
balroga171fe32007-04-30 01:48:07 +00007839 QEMU_OPTION_portrait,
bellard1d14ffa2005-10-30 18:58:22 +00007840#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007841 QEMU_OPTION_audio_help,
7842 QEMU_OPTION_soundhw,
7843#endif
bellardcd6f1162004-05-13 22:02:20 +00007844
bellard7c9d8e02005-11-15 22:16:05 +00007845 QEMU_OPTION_net,
bellardc7f74642004-08-24 21:57:12 +00007846 QEMU_OPTION_tftp,
ths47d5d012007-02-20 00:05:08 +00007847 QEMU_OPTION_bootp,
bellard9d728e82004-09-05 23:09:03 +00007848 QEMU_OPTION_smb,
bellard9bf05442004-08-25 22:12:49 +00007849 QEMU_OPTION_redir,
bellardcd6f1162004-05-13 22:02:20 +00007850
7851 QEMU_OPTION_kernel,
7852 QEMU_OPTION_append,
7853 QEMU_OPTION_initrd,
7854
7855 QEMU_OPTION_S,
7856 QEMU_OPTION_s,
7857 QEMU_OPTION_p,
7858 QEMU_OPTION_d,
7859 QEMU_OPTION_hdachs,
7860 QEMU_OPTION_L,
j_mayer1192dad2007-10-05 13:08:35 +00007861 QEMU_OPTION_bios,
bellard3d11d0e2004-12-12 16:56:30 +00007862 QEMU_OPTION_k,
bellardee22c2f2004-06-03 12:49:50 +00007863 QEMU_OPTION_localtime,
bellard1f042752004-06-05 13:46:47 +00007864 QEMU_OPTION_cirrusvga,
thsd34cab92007-04-02 01:10:46 +00007865 QEMU_OPTION_vmsvga,
bellarde9b137c2004-06-21 16:46:10 +00007866 QEMU_OPTION_g,
bellard1bfe8562004-07-08 21:17:50 +00007867 QEMU_OPTION_std_vga,
ths20d8a3e2007-02-18 17:04:49 +00007868 QEMU_OPTION_echr,
bellard82c643f2004-07-14 17:28:13 +00007869 QEMU_OPTION_monitor,
7870 QEMU_OPTION_serial,
bellard6508fe52005-01-15 12:02:56 +00007871 QEMU_OPTION_parallel,
bellardd63d3072004-10-03 13:29:03 +00007872 QEMU_OPTION_loadvm,
7873 QEMU_OPTION_full_screen,
ths43523e92007-02-18 18:19:32 +00007874 QEMU_OPTION_no_frame,
ths3780e192007-06-21 21:08:02 +00007875 QEMU_OPTION_alt_grab,
ths667acca2006-12-11 02:08:05 +00007876 QEMU_OPTION_no_quit,
bellardf7cce892004-12-08 22:21:25 +00007877 QEMU_OPTION_pidfile,
bellardd993e022005-02-10 22:00:06 +00007878 QEMU_OPTION_no_kqemu,
bellard89bfc102006-02-08 22:46:31 +00007879 QEMU_OPTION_kernel_kqemu,
bellarda09db212005-04-30 16:10:35 +00007880 QEMU_OPTION_win2k_hack,
bellardbb36d472005-11-05 14:22:28 +00007881 QEMU_OPTION_usb,
bellarda594cfb2005-11-06 16:13:29 +00007882 QEMU_OPTION_usbdevice,
bellard6a00d602005-11-21 23:25:50 +00007883 QEMU_OPTION_smp,
bellard24236862006-04-30 21:28:36 +00007884 QEMU_OPTION_vnc,
bellard6515b202006-05-03 22:02:44 +00007885 QEMU_OPTION_no_acpi,
balrog4d3b6f62008-02-10 16:33:14 +00007886 QEMU_OPTION_curses,
bellardd1beab82006-10-02 19:44:22 +00007887 QEMU_OPTION_no_reboot,
aurel32b2f76162008-04-11 21:35:52 +00007888 QEMU_OPTION_no_shutdown,
balrog9467cd42007-05-01 01:34:14 +00007889 QEMU_OPTION_show_cursor,
ths71e3ceb2006-12-22 02:11:31 +00007890 QEMU_OPTION_daemonize,
ths9ae02552007-01-05 17:39:04 +00007891 QEMU_OPTION_option_rom,
thsc35734b2007-03-19 15:17:08 +00007892 QEMU_OPTION_semihosting,
7893 QEMU_OPTION_name,
blueswir166508602007-05-01 14:16:52 +00007894 QEMU_OPTION_prom_env,
balrog2b8f2d42007-07-27 22:08:46 +00007895 QEMU_OPTION_old_param,
thsf3dcfad2007-08-24 01:26:02 +00007896 QEMU_OPTION_clock,
bellard7e0af5d02007-11-07 16:24:33 +00007897 QEMU_OPTION_startdate,
bellard26a5f132008-05-28 12:30:31 +00007898 QEMU_OPTION_tb_size,
pbrook2e70f6e2008-06-29 01:03:05 +00007899 QEMU_OPTION_icount,
blueswir18fcb1b92008-09-18 18:29:08 +00007900 QEMU_OPTION_uuid,
bellardcd6f1162004-05-13 22:02:20 +00007901};
7902
7903typedef struct QEMUOption {
7904 const char *name;
7905 int flags;
7906 int index;
7907} QEMUOption;
7908
7909const QEMUOption qemu_options[] = {
7910 { "h", 0, QEMU_OPTION_h },
pbrook64423fb2007-01-27 17:11:41 +00007911 { "help", 0, QEMU_OPTION_h },
bellardcd6f1162004-05-13 22:02:20 +00007912
bellardcc1daa42005-06-05 14:49:17 +00007913 { "M", HAS_ARG, QEMU_OPTION_M },
j_mayer94fc95c2007-03-05 19:44:02 +00007914 { "cpu", HAS_ARG, QEMU_OPTION_cpu },
bellardcd6f1162004-05-13 22:02:20 +00007915 { "fda", HAS_ARG, QEMU_OPTION_fda },
7916 { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7917 { "hda", HAS_ARG, QEMU_OPTION_hda },
7918 { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7919 { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7920 { "hdd", HAS_ARG, QEMU_OPTION_hdd },
thse4bcb142007-12-02 04:51:10 +00007921 { "drive", HAS_ARG, QEMU_OPTION_drive },
bellardcd6f1162004-05-13 22:02:20 +00007922 { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
balrog3e3d5812007-04-30 02:09:25 +00007923 { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
pbrooka1bb27b2007-04-06 16:49:48 +00007924 { "sd", HAS_ARG, QEMU_OPTION_sd },
j_mayer86f55662007-04-24 06:52:59 +00007925 { "pflash", HAS_ARG, QEMU_OPTION_pflash },
bellardcd6f1162004-05-13 22:02:20 +00007926 { "boot", HAS_ARG, QEMU_OPTION_boot },
7927 { "snapshot", 0, QEMU_OPTION_snapshot },
bellard52ca8d62006-06-14 16:03:05 +00007928#ifdef TARGET_I386
7929 { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7930#endif
bellardcd6f1162004-05-13 22:02:20 +00007931 { "m", HAS_ARG, QEMU_OPTION_m },
7932 { "nographic", 0, QEMU_OPTION_nographic },
balroga171fe32007-04-30 01:48:07 +00007933 { "portrait", 0, QEMU_OPTION_portrait },
bellard3d11d0e2004-12-12 16:56:30 +00007934 { "k", HAS_ARG, QEMU_OPTION_k },
bellard1d14ffa2005-10-30 18:58:22 +00007935#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007936 { "audio-help", 0, QEMU_OPTION_audio_help },
7937 { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7938#endif
bellardcd6f1162004-05-13 22:02:20 +00007939
bellard7c9d8e02005-11-15 22:16:05 +00007940 { "net", HAS_ARG, QEMU_OPTION_net},
bellard158156d2004-05-17 21:13:42 +00007941#ifdef CONFIG_SLIRP
bellardc7f74642004-08-24 21:57:12 +00007942 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
ths47d5d012007-02-20 00:05:08 +00007943 { "bootp", HAS_ARG, QEMU_OPTION_bootp },
bellardc94c8d62004-09-13 21:37:34 +00007944#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00007945 { "smb", HAS_ARG, QEMU_OPTION_smb },
bellardc94c8d62004-09-13 21:37:34 +00007946#endif
bellard9bf05442004-08-25 22:12:49 +00007947 { "redir", HAS_ARG, QEMU_OPTION_redir },
bellard158156d2004-05-17 21:13:42 +00007948#endif
bellardcd6f1162004-05-13 22:02:20 +00007949
7950 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7951 { "append", HAS_ARG, QEMU_OPTION_append },
7952 { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7953
7954 { "S", 0, QEMU_OPTION_S },
7955 { "s", 0, QEMU_OPTION_s },
7956 { "p", HAS_ARG, QEMU_OPTION_p },
7957 { "d", HAS_ARG, QEMU_OPTION_d },
7958 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7959 { "L", HAS_ARG, QEMU_OPTION_L },
j_mayer1192dad2007-10-05 13:08:35 +00007960 { "bios", HAS_ARG, QEMU_OPTION_bios },
bellardd993e022005-02-10 22:00:06 +00007961#ifdef USE_KQEMU
7962 { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
bellard89bfc102006-02-08 22:46:31 +00007963 { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
bellardd993e022005-02-10 22:00:06 +00007964#endif
bellard6f7e9ae2005-03-13 09:43:36 +00007965#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00007966 { "g", 1, QEMU_OPTION_g },
bellard77d4bc32004-05-26 22:13:53 +00007967#endif
bellardee22c2f2004-06-03 12:49:50 +00007968 { "localtime", 0, QEMU_OPTION_localtime },
bellard1bfe8562004-07-08 21:17:50 +00007969 { "std-vga", 0, QEMU_OPTION_std_vga },
balrog8b6e0722007-06-22 08:23:44 +00007970 { "echr", HAS_ARG, QEMU_OPTION_echr },
7971 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7972 { "serial", HAS_ARG, QEMU_OPTION_serial },
7973 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
bellardd63d3072004-10-03 13:29:03 +00007974 { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7975 { "full-screen", 0, QEMU_OPTION_full_screen },
ths667acca2006-12-11 02:08:05 +00007976#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007977 { "no-frame", 0, QEMU_OPTION_no_frame },
ths3780e192007-06-21 21:08:02 +00007978 { "alt-grab", 0, QEMU_OPTION_alt_grab },
ths667acca2006-12-11 02:08:05 +00007979 { "no-quit", 0, QEMU_OPTION_no_quit },
7980#endif
bellardf7cce892004-12-08 22:21:25 +00007981 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
bellarda09db212005-04-30 16:10:35 +00007982 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
bellarda594cfb2005-11-06 16:13:29 +00007983 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
bellard6a00d602005-11-21 23:25:50 +00007984 { "smp", HAS_ARG, QEMU_OPTION_smp },
bellard24236862006-04-30 21:28:36 +00007985 { "vnc", HAS_ARG, QEMU_OPTION_vnc },
balrog4d3b6f62008-02-10 16:33:14 +00007986#ifdef CONFIG_CURSES
7987 { "curses", 0, QEMU_OPTION_curses },
7988#endif
blueswir18fcb1b92008-09-18 18:29:08 +00007989 { "uuid", HAS_ARG, QEMU_OPTION_uuid },
ths96d30e42007-01-07 20:42:14 +00007990
bellard1f042752004-06-05 13:46:47 +00007991 /* temporary options */
bellarda594cfb2005-11-06 16:13:29 +00007992 { "usb", 0, QEMU_OPTION_usb },
bellard1f042752004-06-05 13:46:47 +00007993 { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
thsd34cab92007-04-02 01:10:46 +00007994 { "vmwarevga", 0, QEMU_OPTION_vmsvga },
bellard6515b202006-05-03 22:02:44 +00007995 { "no-acpi", 0, QEMU_OPTION_no_acpi },
bellardd1beab82006-10-02 19:44:22 +00007996 { "no-reboot", 0, QEMU_OPTION_no_reboot },
aurel32b2f76162008-04-11 21:35:52 +00007997 { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
balrog9467cd42007-05-01 01:34:14 +00007998 { "show-cursor", 0, QEMU_OPTION_show_cursor },
ths71e3ceb2006-12-22 02:11:31 +00007999 { "daemonize", 0, QEMU_OPTION_daemonize },
ths9ae02552007-01-05 17:39:04 +00008000 { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
pbrooka87295e2007-05-26 15:09:38 +00008001#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00008002 { "semihosting", 0, QEMU_OPTION_semihosting },
8003#endif
thsc35734b2007-03-19 15:17:08 +00008004 { "name", HAS_ARG, QEMU_OPTION_name },
blueswir166508602007-05-01 14:16:52 +00008005#if defined(TARGET_SPARC)
8006 { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
8007#endif
balrog2b8f2d42007-07-27 22:08:46 +00008008#if defined(TARGET_ARM)
8009 { "old-param", 0, QEMU_OPTION_old_param },
8010#endif
thsf3dcfad2007-08-24 01:26:02 +00008011 { "clock", HAS_ARG, QEMU_OPTION_clock },
bellard7e0af5d02007-11-07 16:24:33 +00008012 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
bellard26a5f132008-05-28 12:30:31 +00008013 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
pbrook2e70f6e2008-06-29 01:03:05 +00008014 { "icount", HAS_ARG, QEMU_OPTION_icount },
bellardcd6f1162004-05-13 22:02:20 +00008015 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00008016};
8017
bellard5905b2e2004-08-01 21:53:26 +00008018/* password input */
8019
balrog2bac6012007-04-30 01:34:31 +00008020int qemu_key_check(BlockDriverState *bs, const char *name)
8021{
8022 char password[256];
8023 int i;
8024
8025 if (!bdrv_is_encrypted(bs))
8026 return 0;
8027
8028 term_printf("%s is encrypted.\n", name);
8029 for(i = 0; i < 3; i++) {
8030 monitor_readline("Password: ", 1, password, sizeof(password));
8031 if (bdrv_set_key(bs, password) == 0)
8032 return 0;
8033 term_printf("invalid password\n");
8034 }
8035 return -EPERM;
8036}
8037
aliguori83ab7952008-08-19 14:44:22 +00008038static BlockDriverState *get_bdrv(int index)
8039{
8040 if (index > nb_drives)
8041 return NULL;
8042 return drives_table[index].bdrv;
8043}
8044
bellard5905b2e2004-08-01 21:53:26 +00008045static void read_passwords(void)
8046{
8047 BlockDriverState *bs;
balrog2bac6012007-04-30 01:34:31 +00008048 int i;
bellard5905b2e2004-08-01 21:53:26 +00008049
aliguori83ab7952008-08-19 14:44:22 +00008050 for(i = 0; i < 6; i++) {
8051 bs = get_bdrv(i);
8052 if (bs)
8053 qemu_key_check(bs, bdrv_get_device_name(bs));
bellard5905b2e2004-08-01 21:53:26 +00008054 }
8055}
8056
bellard1d14ffa2005-10-30 18:58:22 +00008057#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00008058struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00008059#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00008060#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00008061 {
8062 "pcspk",
8063 "PC speaker",
8064 0,
8065 1,
8066 { .init_isa = pcspk_audio_init }
8067 },
8068#endif
bellard6a36d842005-12-18 20:34:32 +00008069 {
8070 "sb16",
8071 "Creative Sound Blaster 16",
8072 0,
8073 1,
8074 { .init_isa = SB16_init }
8075 },
8076
malccc53d262008-06-13 10:48:22 +00008077#ifdef CONFIG_CS4231A
8078 {
8079 "cs4231a",
8080 "CS4231A",
8081 0,
8082 1,
8083 { .init_isa = cs4231a_init }
8084 },
8085#endif
8086
bellard6a36d842005-12-18 20:34:32 +00008087#ifdef CONFIG_ADLIB
8088 {
8089 "adlib",
8090#ifdef HAS_YMF262
8091 "Yamaha YMF262 (OPL3)",
8092#else
8093 "Yamaha YM3812 (OPL2)",
8094#endif
8095 0,
8096 1,
8097 { .init_isa = Adlib_init }
8098 },
8099#endif
8100
8101#ifdef CONFIG_GUS
8102 {
8103 "gus",
8104 "Gravis Ultrasound GF1",
8105 0,
8106 1,
8107 { .init_isa = GUS_init }
8108 },
8109#endif
8110
balroge5c9a132008-01-14 04:27:55 +00008111#ifdef CONFIG_AC97
8112 {
8113 "ac97",
8114 "Intel 82801AA AC97 Audio",
8115 0,
8116 0,
8117 { .init_pci = ac97_init }
8118 },
8119#endif
8120
bellard6a36d842005-12-18 20:34:32 +00008121 {
8122 "es1370",
8123 "ENSONIQ AudioPCI ES1370",
8124 0,
8125 0,
8126 { .init_pci = es1370_init }
8127 },
balrogb00052e2007-04-30 02:22:06 +00008128#endif
bellard6a36d842005-12-18 20:34:32 +00008129
8130 { NULL, NULL, 0, 0, { NULL } }
8131};
8132
bellard1d14ffa2005-10-30 18:58:22 +00008133static void select_soundhw (const char *optarg)
8134{
bellard6a36d842005-12-18 20:34:32 +00008135 struct soundhw *c;
8136
bellard1d14ffa2005-10-30 18:58:22 +00008137 if (*optarg == '?') {
8138 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00008139
bellard1d14ffa2005-10-30 18:58:22 +00008140 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00008141 for (c = soundhw; c->name; ++c) {
8142 printf ("%-11s %s\n", c->name, c->descr);
8143 }
8144 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00008145 exit (*optarg != '?');
8146 }
8147 else {
bellard6a36d842005-12-18 20:34:32 +00008148 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00008149 const char *p;
8150 char *e;
8151 int bad_card = 0;
8152
bellard6a36d842005-12-18 20:34:32 +00008153 if (!strcmp (optarg, "all")) {
8154 for (c = soundhw; c->name; ++c) {
8155 c->enabled = 1;
8156 }
8157 return;
8158 }
bellard1d14ffa2005-10-30 18:58:22 +00008159
bellard6a36d842005-12-18 20:34:32 +00008160 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00008161 while (*p) {
8162 e = strchr (p, ',');
8163 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00008164
8165 for (c = soundhw; c->name; ++c) {
8166 if (!strncmp (c->name, p, l)) {
8167 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00008168 break;
8169 }
8170 }
bellard6a36d842005-12-18 20:34:32 +00008171
8172 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00008173 if (l > 80) {
8174 fprintf (stderr,
8175 "Unknown sound card name (too big to show)\n");
8176 }
8177 else {
8178 fprintf (stderr, "Unknown sound card name `%.*s'\n",
8179 (int) l, p);
8180 }
8181 bad_card = 1;
8182 }
8183 p += l + (e != NULL);
8184 }
8185
8186 if (bad_card)
8187 goto show_valid_cards;
8188 }
8189}
8190#endif
8191
bellard3587d7e2006-06-26 20:03:44 +00008192#ifdef _WIN32
8193static BOOL WINAPI qemu_ctrl_handler(DWORD type)
8194{
8195 exit(STATUS_CONTROL_C_EXIT);
8196 return TRUE;
8197}
8198#endif
8199
blueswir18fcb1b92008-09-18 18:29:08 +00008200static int qemu_uuid_parse(const char *str, uint8_t *uuid)
8201{
8202 int ret;
8203
8204 if(strlen(str) != 36)
8205 return -1;
8206
8207 ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
8208 &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
8209 &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
8210
8211 if(ret != 16)
8212 return -1;
8213
8214 return 0;
8215}
8216
bellard7c9d8e02005-11-15 22:16:05 +00008217#define MAX_NET_CLIENTS 32
bellardc20709a2004-04-21 23:27:19 +00008218
aliguori5b08fc12008-08-21 20:08:03 +00008219#ifndef _WIN32
8220
8221static void termsig_handler(int signal)
8222{
8223 qemu_system_shutdown_request();
8224}
8225
blueswir16f9e3802008-09-09 18:56:59 +00008226static void termsig_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00008227{
8228 struct sigaction act;
8229
8230 memset(&act, 0, sizeof(act));
8231 act.sa_handler = termsig_handler;
8232 sigaction(SIGINT, &act, NULL);
8233 sigaction(SIGHUP, &act, NULL);
8234 sigaction(SIGTERM, &act, NULL);
8235}
8236
8237#endif
8238
bellard0824d6f2003-06-24 13:42:40 +00008239int main(int argc, char **argv)
8240{
bellard67b915a2004-03-31 23:37:16 +00008241#ifdef CONFIG_GDBSTUB
pbrookcfc34752007-02-22 01:48:01 +00008242 int use_gdbstub;
8243 const char *gdbstub_port;
bellard67b915a2004-03-31 23:37:16 +00008244#endif
j_mayer28c5af52007-11-11 01:50:45 +00008245 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00008246 int i;
j_mayer28c5af52007-11-11 01:50:45 +00008247 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00008248 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00008249 const char *kernel_filename, *kernel_cmdline;
j_mayer28c5af52007-11-11 01:50:45 +00008250 const char *boot_devices = "";
bellard313aa562003-08-10 21:52:11 +00008251 DisplayState *ds = &display_state;
bellard46d47672004-11-16 01:45:27 +00008252 int cyls, heads, secs, translation;
pbrookfd5f3932008-03-26 20:55:43 +00008253 const char *net_clients[MAX_NET_CLIENTS];
bellard7c9d8e02005-11-15 22:16:05 +00008254 int nb_net_clients;
thse4bcb142007-12-02 04:51:10 +00008255 int hda_index;
bellardcd6f1162004-05-13 22:02:20 +00008256 int optind;
8257 const char *r, *optarg;
bellard82c643f2004-07-14 17:28:13 +00008258 CharDriverState *monitor_hd;
pbrookfd5f3932008-03-26 20:55:43 +00008259 const char *monitor_device;
8260 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00008261 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00008262 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00008263 int parallel_device_index;
bellardd63d3072004-10-03 13:29:03 +00008264 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00008265 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00008266 const char *cpu_model;
pbrookfd5f3932008-03-26 20:55:43 +00008267 const char *usb_devices[MAX_USB_CMDLINE];
bellarda594cfb2005-11-06 16:13:29 +00008268 int usb_devices_index;
ths71e3ceb2006-12-22 02:11:31 +00008269 int fds[2];
bellard26a5f132008-05-28 12:30:31 +00008270 int tb_size;
ths93815bc2007-03-19 15:58:31 +00008271 const char *pid_file = NULL;
blueswir1833c7172007-05-27 19:36:43 +00008272 VLANState *vlan;
bellard0bd48852005-11-11 00:00:47 +00008273
8274 LIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00008275#ifndef _WIN32
8276 {
8277 struct sigaction act;
8278 sigfillset(&act.sa_mask);
8279 act.sa_flags = 0;
8280 act.sa_handler = SIG_IGN;
8281 sigaction(SIGPIPE, &act, NULL);
8282 }
bellard3587d7e2006-06-26 20:03:44 +00008283#else
8284 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00008285 /* Note: cpu_interrupt() is currently not SMP safe, so we force
8286 QEMU to run on a single CPU */
8287 {
8288 HANDLE h;
8289 DWORD mask, smask;
8290 int i;
8291 h = GetCurrentProcess();
8292 if (GetProcessAffinityMask(h, &mask, &smask)) {
8293 for(i = 0; i < 32; i++) {
8294 if (mask & (1 << i))
8295 break;
8296 }
8297 if (i != 32) {
8298 mask = 1 << i;
8299 SetProcessAffinityMask(h, mask);
8300 }
8301 }
8302 }
bellard67b915a2004-03-31 23:37:16 +00008303#endif
bellardbe995c22006-06-25 16:25:21 +00008304
bellardcc1daa42005-06-05 14:49:17 +00008305 register_machines();
8306 machine = first_machine;
j_mayer94fc95c2007-03-05 19:44:02 +00008307 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00008308 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00008309 ram_size = 0;
bellard313aa562003-08-10 21:52:11 +00008310 vga_ram_size = VGA_RAM_SIZE;
bellard67b915a2004-03-31 23:37:16 +00008311#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00008312 use_gdbstub = 0;
bellardc636bb62007-02-05 20:46:05 +00008313 gdbstub_port = DEFAULT_GDBSTUB_PORT;
bellard67b915a2004-03-31 23:37:16 +00008314#endif
bellard33e39632003-07-06 17:15:21 +00008315 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00008316 nographic = 0;
balrog4d3b6f62008-02-10 16:33:14 +00008317 curses = 0;
bellarda20dd502003-09-30 21:07:02 +00008318 kernel_filename = NULL;
8319 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00008320 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00008321 translation = BIOS_ATA_TRANSLATION_AUTO;
pbrookc60e08d2008-07-01 16:24:38 +00008322 monitor_device = "vc";
bellardc4b1fcc2004-03-14 21:44:30 +00008323
aurel32c75a8232008-05-04 00:50:34 +00008324 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00008325 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00008326 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00008327 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00008328
aurel32c75a8232008-05-04 00:50:34 +00008329 parallel_devices[0] = "vc:640x480";
bellard6508fe52005-01-15 12:02:56 +00008330 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00008331 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00008332 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00008333
bellarda594cfb2005-11-06 16:13:29 +00008334 usb_devices_index = 0;
ths3b46e622007-09-17 08:09:54 +00008335
bellard7c9d8e02005-11-15 22:16:05 +00008336 nb_net_clients = 0;
thse4bcb142007-12-02 04:51:10 +00008337 nb_drives = 0;
8338 nb_drives_opt = 0;
8339 hda_index = -1;
bellard7c9d8e02005-11-15 22:16:05 +00008340
8341 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00008342
bellard26a5f132008-05-28 12:30:31 +00008343 tb_size = 0;
8344
bellardcd6f1162004-05-13 22:02:20 +00008345 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00008346 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00008347 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00008348 break;
bellardcd6f1162004-05-13 22:02:20 +00008349 r = argv[optind];
8350 if (r[0] != '-') {
balrog609497a2008-01-14 02:56:53 +00008351 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00008352 } else {
8353 const QEMUOption *popt;
8354
8355 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00008356 /* Treat --foo the same as -foo. */
8357 if (r[1] == '-')
8358 r++;
bellardcd6f1162004-05-13 22:02:20 +00008359 popt = qemu_options;
8360 for(;;) {
8361 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00008362 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00008363 argv[0], r);
8364 exit(1);
8365 }
8366 if (!strcmp(popt->name, r + 1))
8367 break;
8368 popt++;
8369 }
8370 if (popt->flags & HAS_ARG) {
8371 if (optind >= argc) {
8372 fprintf(stderr, "%s: option '%s' requires an argument\n",
8373 argv[0], r);
8374 exit(1);
8375 }
8376 optarg = argv[optind++];
8377 } else {
8378 optarg = NULL;
8379 }
8380
8381 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00008382 case QEMU_OPTION_M:
8383 machine = find_machine(optarg);
8384 if (!machine) {
8385 QEMUMachine *m;
8386 printf("Supported machines are:\n");
8387 for(m = first_machine; m != NULL; m = m->next) {
8388 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00008389 m->name, m->desc,
bellardcc1daa42005-06-05 14:49:17 +00008390 m == first_machine ? " (default)" : "");
8391 }
ths15f82202007-06-29 23:26:08 +00008392 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00008393 }
8394 break;
j_mayer94fc95c2007-03-05 19:44:02 +00008395 case QEMU_OPTION_cpu:
8396 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00008397 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00008398/* XXX: implement xxx_cpu_list for targets that still miss it */
8399#if defined(cpu_list)
8400 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00008401#endif
ths15f82202007-06-29 23:26:08 +00008402 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00008403 } else {
8404 cpu_model = optarg;
8405 }
8406 break;
bellardcd6f1162004-05-13 22:02:20 +00008407 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00008408 initrd_filename = optarg;
8409 break;
bellardcd6f1162004-05-13 22:02:20 +00008410 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00008411 if (cyls == 0)
balrog609497a2008-01-14 02:56:53 +00008412 hda_index = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00008413 else
balrog609497a2008-01-14 02:56:53 +00008414 hda_index = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00008415 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00008416 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008417 translation == BIOS_ATA_TRANSLATION_LBA ?
8418 ",trans=lba" :
8419 translation == BIOS_ATA_TRANSLATION_NONE ?
8420 ",trans=none" : "");
8421 break;
bellardcd6f1162004-05-13 22:02:20 +00008422 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00008423 case QEMU_OPTION_hdc:
8424 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00008425 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00008426 break;
thse4bcb142007-12-02 04:51:10 +00008427 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00008428 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00008429 break;
balrog3e3d5812007-04-30 02:09:25 +00008430 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00008431 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00008432 break;
pbrooka1bb27b2007-04-06 16:49:48 +00008433 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00008434 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00008435 break;
j_mayer86f55662007-04-24 06:52:59 +00008436 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00008437 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00008438 break;
bellardcd6f1162004-05-13 22:02:20 +00008439 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00008440 snapshot = 1;
8441 break;
bellardcd6f1162004-05-13 22:02:20 +00008442 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00008443 {
bellard330d0412003-07-26 18:11:40 +00008444 const char *p;
8445 p = optarg;
8446 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008447 if (cyls < 1 || cyls > 16383)
8448 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008449 if (*p != ',')
8450 goto chs_fail;
8451 p++;
8452 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008453 if (heads < 1 || heads > 16)
8454 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008455 if (*p != ',')
8456 goto chs_fail;
8457 p++;
8458 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008459 if (secs < 1 || secs > 63)
8460 goto chs_fail;
8461 if (*p == ',') {
8462 p++;
8463 if (!strcmp(p, "none"))
8464 translation = BIOS_ATA_TRANSLATION_NONE;
8465 else if (!strcmp(p, "lba"))
8466 translation = BIOS_ATA_TRANSLATION_LBA;
8467 else if (!strcmp(p, "auto"))
8468 translation = BIOS_ATA_TRANSLATION_AUTO;
8469 else
8470 goto chs_fail;
8471 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00008472 chs_fail:
bellard46d47672004-11-16 01:45:27 +00008473 fprintf(stderr, "qemu: invalid physical CHS format\n");
8474 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00008475 }
thse4bcb142007-12-02 04:51:10 +00008476 if (hda_index != -1)
balrog609497a2008-01-14 02:56:53 +00008477 snprintf(drives_opt[hda_index].opt,
8478 sizeof(drives_opt[hda_index].opt),
8479 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
8480 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008481 translation == BIOS_ATA_TRANSLATION_LBA ?
8482 ",trans=lba" :
8483 translation == BIOS_ATA_TRANSLATION_NONE ?
8484 ",trans=none" : "");
bellard330d0412003-07-26 18:11:40 +00008485 }
8486 break;
bellardcd6f1162004-05-13 22:02:20 +00008487 case QEMU_OPTION_nographic:
bellarda20dd502003-09-30 21:07:02 +00008488 nographic = 1;
8489 break;
balrog4d3b6f62008-02-10 16:33:14 +00008490#ifdef CONFIG_CURSES
8491 case QEMU_OPTION_curses:
8492 curses = 1;
8493 break;
8494#endif
balroga171fe32007-04-30 01:48:07 +00008495 case QEMU_OPTION_portrait:
8496 graphic_rotate = 1;
8497 break;
bellardcd6f1162004-05-13 22:02:20 +00008498 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00008499 kernel_filename = optarg;
8500 break;
bellardcd6f1162004-05-13 22:02:20 +00008501 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00008502 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00008503 break;
bellardcd6f1162004-05-13 22:02:20 +00008504 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00008505 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00008506 break;
bellardcd6f1162004-05-13 22:02:20 +00008507 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00008508 boot_devices = optarg;
8509 /* We just do some generic consistency checks */
8510 {
8511 /* Could easily be extended to 64 devices if needed */
ths60fe76f2007-12-16 03:02:09 +00008512 const char *p;
j_mayer28c5af52007-11-11 01:50:45 +00008513
8514 boot_devices_bitmap = 0;
8515 for (p = boot_devices; *p != '\0'; p++) {
8516 /* Allowed boot devices are:
8517 * a b : floppy disk drives
8518 * c ... f : IDE disk drives
8519 * g ... m : machine implementation dependant drives
8520 * n ... p : network devices
8521 * It's up to each machine implementation to check
8522 * if the given boot devices match the actual hardware
8523 * implementation and firmware features.
8524 */
8525 if (*p < 'a' || *p > 'q') {
8526 fprintf(stderr, "Invalid boot device '%c'\n", *p);
8527 exit(1);
8528 }
8529 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
8530 fprintf(stderr,
8531 "Boot device '%c' was given twice\n",*p);
8532 exit(1);
8533 }
8534 boot_devices_bitmap |= 1 << (*p - 'a');
8535 }
bellard36b486b2003-11-11 13:36:08 +00008536 }
8537 break;
bellardcd6f1162004-05-13 22:02:20 +00008538 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00008539 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00008540 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00008541 break;
bellard52ca8d62006-06-14 16:03:05 +00008542#ifdef TARGET_I386
8543 case QEMU_OPTION_no_fd_bootchk:
8544 fd_bootchk = 0;
8545 break;
8546#endif
bellard7c9d8e02005-11-15 22:16:05 +00008547 case QEMU_OPTION_net:
8548 if (nb_net_clients >= MAX_NET_CLIENTS) {
8549 fprintf(stderr, "qemu: too many network clients\n");
bellardc4b1fcc2004-03-14 21:44:30 +00008550 exit(1);
8551 }
pbrookfd5f3932008-03-26 20:55:43 +00008552 net_clients[nb_net_clients] = optarg;
bellard7c9d8e02005-11-15 22:16:05 +00008553 nb_net_clients++;
bellard702c6512004-04-02 21:21:32 +00008554 break;
bellardc7f74642004-08-24 21:57:12 +00008555#ifdef CONFIG_SLIRP
8556 case QEMU_OPTION_tftp:
bellardc7f74642004-08-24 21:57:12 +00008557 tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00008558 break;
ths47d5d012007-02-20 00:05:08 +00008559 case QEMU_OPTION_bootp:
8560 bootp_filename = optarg;
8561 break;
bellardc94c8d62004-09-13 21:37:34 +00008562#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00008563 case QEMU_OPTION_smb:
8564 net_slirp_smb(optarg);
8565 break;
bellardc94c8d62004-09-13 21:37:34 +00008566#endif
bellard9bf05442004-08-25 22:12:49 +00008567 case QEMU_OPTION_redir:
ths3b46e622007-09-17 08:09:54 +00008568 net_slirp_redir(optarg);
bellard9bf05442004-08-25 22:12:49 +00008569 break;
bellardc7f74642004-08-24 21:57:12 +00008570#endif
bellard1d14ffa2005-10-30 18:58:22 +00008571#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00008572 case QEMU_OPTION_audio_help:
8573 AUD_help ();
8574 exit (0);
8575 break;
8576 case QEMU_OPTION_soundhw:
8577 select_soundhw (optarg);
8578 break;
8579#endif
bellardcd6f1162004-05-13 22:02:20 +00008580 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00008581 help(0);
bellardcd6f1162004-05-13 22:02:20 +00008582 break;
aurel3200f82b82008-04-27 21:12:55 +00008583 case QEMU_OPTION_m: {
8584 uint64_t value;
8585 char *ptr;
8586
8587 value = strtoul(optarg, &ptr, 10);
8588 switch (*ptr) {
8589 case 0: case 'M': case 'm':
8590 value <<= 20;
8591 break;
8592 case 'G': case 'g':
8593 value <<= 30;
8594 break;
8595 default:
8596 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00008597 exit(1);
8598 }
aurel3200f82b82008-04-27 21:12:55 +00008599
8600 /* On 32-bit hosts, QEMU is limited by virtual address space */
8601 if (value > (2047 << 20)
8602#ifndef USE_KQEMU
8603 && HOST_LONG_BITS == 32
8604#endif
8605 ) {
8606 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
8607 exit(1);
8608 }
8609 if (value != (uint64_t)(ram_addr_t)value) {
8610 fprintf(stderr, "qemu: ram size too large\n");
8611 exit(1);
8612 }
8613 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00008614 break;
aurel3200f82b82008-04-27 21:12:55 +00008615 }
bellardcd6f1162004-05-13 22:02:20 +00008616 case QEMU_OPTION_d:
8617 {
8618 int mask;
8619 CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00008620
bellardcd6f1162004-05-13 22:02:20 +00008621 mask = cpu_str_to_log_mask(optarg);
8622 if (!mask) {
8623 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00008624 for(item = cpu_log_items; item->mask != 0; item++) {
8625 printf("%-10s %s\n", item->name, item->help);
8626 }
8627 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00008628 }
8629 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00008630 }
bellardcd6f1162004-05-13 22:02:20 +00008631 break;
bellard67b915a2004-03-31 23:37:16 +00008632#ifdef CONFIG_GDBSTUB
bellardcd6f1162004-05-13 22:02:20 +00008633 case QEMU_OPTION_s:
8634 use_gdbstub = 1;
8635 break;
8636 case QEMU_OPTION_p:
pbrookcfc34752007-02-22 01:48:01 +00008637 gdbstub_port = optarg;
bellardcd6f1162004-05-13 22:02:20 +00008638 break;
bellard67b915a2004-03-31 23:37:16 +00008639#endif
bellardcd6f1162004-05-13 22:02:20 +00008640 case QEMU_OPTION_L:
8641 bios_dir = optarg;
8642 break;
j_mayer1192dad2007-10-05 13:08:35 +00008643 case QEMU_OPTION_bios:
8644 bios_name = optarg;
8645 break;
bellardcd6f1162004-05-13 22:02:20 +00008646 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00008647 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00008648 break;
bellard3d11d0e2004-12-12 16:56:30 +00008649 case QEMU_OPTION_k:
8650 keyboard_layout = optarg;
8651 break;
bellardee22c2f2004-06-03 12:49:50 +00008652 case QEMU_OPTION_localtime:
8653 rtc_utc = 0;
8654 break;
bellard1f042752004-06-05 13:46:47 +00008655 case QEMU_OPTION_cirrusvga:
8656 cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +00008657 vmsvga_enabled = 0;
8658 break;
8659 case QEMU_OPTION_vmsvga:
8660 cirrus_vga_enabled = 0;
8661 vmsvga_enabled = 1;
bellard1f042752004-06-05 13:46:47 +00008662 break;
bellard1bfe8562004-07-08 21:17:50 +00008663 case QEMU_OPTION_std_vga:
8664 cirrus_vga_enabled = 0;
thsd34cab92007-04-02 01:10:46 +00008665 vmsvga_enabled = 0;
bellard1bfe8562004-07-08 21:17:50 +00008666 break;
bellarde9b137c2004-06-21 16:46:10 +00008667 case QEMU_OPTION_g:
8668 {
8669 const char *p;
8670 int w, h, depth;
8671 p = optarg;
8672 w = strtol(p, (char **)&p, 10);
8673 if (w <= 0) {
8674 graphic_error:
8675 fprintf(stderr, "qemu: invalid resolution or depth\n");
8676 exit(1);
8677 }
8678 if (*p != 'x')
8679 goto graphic_error;
8680 p++;
8681 h = strtol(p, (char **)&p, 10);
8682 if (h <= 0)
8683 goto graphic_error;
8684 if (*p == 'x') {
8685 p++;
8686 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00008687 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00008688 depth != 24 && depth != 32)
8689 goto graphic_error;
8690 } else if (*p == '\0') {
8691 depth = graphic_depth;
8692 } else {
8693 goto graphic_error;
8694 }
ths3b46e622007-09-17 08:09:54 +00008695
bellarde9b137c2004-06-21 16:46:10 +00008696 graphic_width = w;
8697 graphic_height = h;
8698 graphic_depth = depth;
8699 }
8700 break;
ths20d8a3e2007-02-18 17:04:49 +00008701 case QEMU_OPTION_echr:
8702 {
8703 char *r;
8704 term_escape_char = strtol(optarg, &r, 0);
8705 if (r == optarg)
8706 printf("Bad argument to echr\n");
8707 break;
8708 }
bellard82c643f2004-07-14 17:28:13 +00008709 case QEMU_OPTION_monitor:
pbrookfd5f3932008-03-26 20:55:43 +00008710 monitor_device = optarg;
bellard82c643f2004-07-14 17:28:13 +00008711 break;
8712 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00008713 if (serial_device_index >= MAX_SERIAL_PORTS) {
8714 fprintf(stderr, "qemu: too many serial ports\n");
8715 exit(1);
8716 }
pbrookfd5f3932008-03-26 20:55:43 +00008717 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00008718 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00008719 break;
bellard6508fe52005-01-15 12:02:56 +00008720 case QEMU_OPTION_parallel:
8721 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
8722 fprintf(stderr, "qemu: too many parallel ports\n");
8723 exit(1);
8724 }
pbrookfd5f3932008-03-26 20:55:43 +00008725 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00008726 parallel_device_index++;
8727 break;
bellardd63d3072004-10-03 13:29:03 +00008728 case QEMU_OPTION_loadvm:
8729 loadvm = optarg;
8730 break;
8731 case QEMU_OPTION_full_screen:
8732 full_screen = 1;
8733 break;
ths667acca2006-12-11 02:08:05 +00008734#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00008735 case QEMU_OPTION_no_frame:
8736 no_frame = 1;
8737 break;
ths3780e192007-06-21 21:08:02 +00008738 case QEMU_OPTION_alt_grab:
8739 alt_grab = 1;
8740 break;
ths667acca2006-12-11 02:08:05 +00008741 case QEMU_OPTION_no_quit:
8742 no_quit = 1;
8743 break;
8744#endif
bellardf7cce892004-12-08 22:21:25 +00008745 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00008746 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00008747 break;
bellarda09db212005-04-30 16:10:35 +00008748#ifdef TARGET_I386
8749 case QEMU_OPTION_win2k_hack:
8750 win2k_install_hack = 1;
8751 break;
8752#endif
bellardd993e022005-02-10 22:00:06 +00008753#ifdef USE_KQEMU
8754 case QEMU_OPTION_no_kqemu:
8755 kqemu_allowed = 0;
8756 break;
bellard89bfc102006-02-08 22:46:31 +00008757 case QEMU_OPTION_kernel_kqemu:
8758 kqemu_allowed = 2;
8759 break;
bellardd993e022005-02-10 22:00:06 +00008760#endif
bellardbb36d472005-11-05 14:22:28 +00008761 case QEMU_OPTION_usb:
8762 usb_enabled = 1;
8763 break;
bellarda594cfb2005-11-06 16:13:29 +00008764 case QEMU_OPTION_usbdevice:
8765 usb_enabled = 1;
pbrook0d92ed32006-05-21 16:30:15 +00008766 if (usb_devices_index >= MAX_USB_CMDLINE) {
bellarda594cfb2005-11-06 16:13:29 +00008767 fprintf(stderr, "Too many USB devices\n");
8768 exit(1);
8769 }
pbrookfd5f3932008-03-26 20:55:43 +00008770 usb_devices[usb_devices_index] = optarg;
bellarda594cfb2005-11-06 16:13:29 +00008771 usb_devices_index++;
8772 break;
bellard6a00d602005-11-21 23:25:50 +00008773 case QEMU_OPTION_smp:
8774 smp_cpus = atoi(optarg);
bellardba3c64f2005-12-05 20:31:52 +00008775 if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
bellard6a00d602005-11-21 23:25:50 +00008776 fprintf(stderr, "Invalid number of CPUs\n");
8777 exit(1);
8778 }
8779 break;
bellard24236862006-04-30 21:28:36 +00008780 case QEMU_OPTION_vnc:
ths73fc9742006-12-22 02:09:07 +00008781 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00008782 break;
bellard6515b202006-05-03 22:02:44 +00008783 case QEMU_OPTION_no_acpi:
8784 acpi_enabled = 0;
8785 break;
bellardd1beab82006-10-02 19:44:22 +00008786 case QEMU_OPTION_no_reboot:
8787 no_reboot = 1;
8788 break;
aurel32b2f76162008-04-11 21:35:52 +00008789 case QEMU_OPTION_no_shutdown:
8790 no_shutdown = 1;
8791 break;
balrog9467cd42007-05-01 01:34:14 +00008792 case QEMU_OPTION_show_cursor:
8793 cursor_hide = 0;
8794 break;
blueswir18fcb1b92008-09-18 18:29:08 +00008795 case QEMU_OPTION_uuid:
8796 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
8797 fprintf(stderr, "Fail to parse UUID string."
8798 " Wrong format.\n");
8799 exit(1);
8800 }
8801 break;
ths71e3ceb2006-12-22 02:11:31 +00008802 case QEMU_OPTION_daemonize:
8803 daemonize = 1;
8804 break;
ths9ae02552007-01-05 17:39:04 +00008805 case QEMU_OPTION_option_rom:
8806 if (nb_option_roms >= MAX_OPTION_ROMS) {
8807 fprintf(stderr, "Too many option ROMs\n");
8808 exit(1);
8809 }
8810 option_rom[nb_option_roms] = optarg;
8811 nb_option_roms++;
8812 break;
pbrook8e716212007-01-20 17:12:09 +00008813 case QEMU_OPTION_semihosting:
8814 semihosting_enabled = 1;
8815 break;
thsc35734b2007-03-19 15:17:08 +00008816 case QEMU_OPTION_name:
8817 qemu_name = optarg;
8818 break;
blueswir166508602007-05-01 14:16:52 +00008819#ifdef TARGET_SPARC
8820 case QEMU_OPTION_prom_env:
8821 if (nb_prom_envs >= MAX_PROM_ENVS) {
8822 fprintf(stderr, "Too many prom variables\n");
8823 exit(1);
8824 }
8825 prom_envs[nb_prom_envs] = optarg;
8826 nb_prom_envs++;
8827 break;
8828#endif
balrog2b8f2d42007-07-27 22:08:46 +00008829#ifdef TARGET_ARM
8830 case QEMU_OPTION_old_param:
8831 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00008832 break;
balrog2b8f2d42007-07-27 22:08:46 +00008833#endif
thsf3dcfad2007-08-24 01:26:02 +00008834 case QEMU_OPTION_clock:
8835 configure_alarms(optarg);
8836 break;
bellard7e0af5d02007-11-07 16:24:33 +00008837 case QEMU_OPTION_startdate:
8838 {
8839 struct tm tm;
balrogf6503052008-02-17 11:42:19 +00008840 time_t rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008841 if (!strcmp(optarg, "now")) {
balrogf6503052008-02-17 11:42:19 +00008842 rtc_date_offset = -1;
bellard7e0af5d02007-11-07 16:24:33 +00008843 } else {
8844 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8845 &tm.tm_year,
8846 &tm.tm_mon,
8847 &tm.tm_mday,
8848 &tm.tm_hour,
8849 &tm.tm_min,
8850 &tm.tm_sec) == 6) {
8851 /* OK */
8852 } else if (sscanf(optarg, "%d-%d-%d",
8853 &tm.tm_year,
8854 &tm.tm_mon,
8855 &tm.tm_mday) == 3) {
8856 tm.tm_hour = 0;
8857 tm.tm_min = 0;
8858 tm.tm_sec = 0;
8859 } else {
8860 goto date_fail;
8861 }
8862 tm.tm_year -= 1900;
8863 tm.tm_mon--;
bellard3c6b2082007-11-10 19:36:39 +00008864 rtc_start_date = mktimegm(&tm);
bellard7e0af5d02007-11-07 16:24:33 +00008865 if (rtc_start_date == -1) {
8866 date_fail:
8867 fprintf(stderr, "Invalid date format. Valid format are:\n"
8868 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8869 exit(1);
8870 }
balrogf6503052008-02-17 11:42:19 +00008871 rtc_date_offset = time(NULL) - rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008872 }
8873 }
8874 break;
bellard26a5f132008-05-28 12:30:31 +00008875 case QEMU_OPTION_tb_size:
8876 tb_size = strtol(optarg, NULL, 0);
8877 if (tb_size < 0)
8878 tb_size = 0;
8879 break;
pbrook2e70f6e2008-06-29 01:03:05 +00008880 case QEMU_OPTION_icount:
8881 use_icount = 1;
8882 if (strcmp(optarg, "auto") == 0) {
8883 icount_time_shift = -1;
8884 } else {
8885 icount_time_shift = strtol(optarg, NULL, 0);
8886 }
8887 break;
bellardcd6f1162004-05-13 22:02:20 +00008888 }
bellard0824d6f2003-06-24 13:42:40 +00008889 }
8890 }
bellard330d0412003-07-26 18:11:40 +00008891
aliguoribc0129d2008-08-01 15:12:34 +00008892 if (nographic) {
8893 if (serial_device_index == 0)
8894 serial_devices[0] = "stdio";
8895 if (parallel_device_index == 0)
8896 parallel_devices[0] = "null";
8897 if (strncmp(monitor_device, "vc", 2) == 0)
8898 monitor_device = "stdio";
8899 }
8900
ths71e3ceb2006-12-22 02:11:31 +00008901#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00008902 if (daemonize) {
8903 pid_t pid;
8904
8905 if (pipe(fds) == -1)
8906 exit(1);
8907
8908 pid = fork();
8909 if (pid > 0) {
8910 uint8_t status;
8911 ssize_t len;
8912
8913 close(fds[1]);
8914
8915 again:
ths93815bc2007-03-19 15:58:31 +00008916 len = read(fds[0], &status, 1);
8917 if (len == -1 && (errno == EINTR))
8918 goto again;
8919
8920 if (len != 1)
8921 exit(1);
8922 else if (status == 1) {
8923 fprintf(stderr, "Could not acquire pidfile\n");
8924 exit(1);
8925 } else
8926 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00008927 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00008928 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00008929
8930 setsid();
8931
8932 pid = fork();
8933 if (pid > 0)
8934 exit(0);
8935 else if (pid < 0)
8936 exit(1);
8937
8938 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00008939
8940 signal(SIGTSTP, SIG_IGN);
8941 signal(SIGTTOU, SIG_IGN);
8942 signal(SIGTTIN, SIG_IGN);
8943 }
8944#endif
8945
thsaa26bb22007-03-25 21:33:06 +00008946 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00008947 if (daemonize) {
8948 uint8_t status = 1;
8949 write(fds[1], &status, 1);
8950 } else
8951 fprintf(stderr, "Could not acquire pid file\n");
8952 exit(1);
8953 }
8954
bellardff3fbb32006-01-08 10:53:14 +00008955#ifdef USE_KQEMU
8956 if (smp_cpus > 1)
8957 kqemu_allowed = 0;
8958#endif
bellarda20dd502003-09-30 21:07:02 +00008959 linux_boot = (kernel_filename != NULL);
balrog7317b8c2007-11-18 02:09:36 +00008960 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
balrog6c41b272007-11-17 12:12:29 +00008961
j_mayer28c5af52007-11-11 01:50:45 +00008962 if (!linux_boot && net_boot == 0 &&
blueswir1f88e4b92008-08-12 15:58:35 +00008963 !machine->nodisk_ok && nb_drives_opt == 0)
ths15f82202007-06-29 23:26:08 +00008964 help(1);
bellard0824d6f2003-06-24 13:42:40 +00008965
thsf8d39c02008-07-03 10:01:15 +00008966 if (!linux_boot && *kernel_cmdline != '\0') {
8967 fprintf(stderr, "-append only allowed with -kernel option\n");
8968 exit(1);
8969 }
8970
8971 if (!linux_boot && initrd_filename != NULL) {
8972 fprintf(stderr, "-initrd only allowed with -kernel option\n");
8973 exit(1);
8974 }
8975
ths96d30e42007-01-07 20:42:14 +00008976 /* boot to floppy or the default cd if no hard disk defined yet */
j_mayer28c5af52007-11-11 01:50:45 +00008977 if (!boot_devices[0]) {
thse4bcb142007-12-02 04:51:10 +00008978 boot_devices = "cad";
ths96d30e42007-01-07 20:42:14 +00008979 }
bellardb118d612003-06-30 23:36:21 +00008980 setvbuf(stdout, NULL, _IOLBF, 0);
ths3b46e622007-09-17 08:09:54 +00008981
pbrook634fce92006-07-15 17:40:09 +00008982 init_timers();
8983 init_timer_alarm();
bellard83f64092006-08-01 16:21:11 +00008984 qemu_aio_init();
pbrook2e70f6e2008-06-29 01:03:05 +00008985 if (use_icount && icount_time_shift < 0) {
8986 use_icount = 2;
8987 /* 125MIPS seems a reasonable initial guess at the guest speed.
8988 It will be corrected fairly quickly anyway. */
8989 icount_time_shift = 3;
8990 init_icount_adjust();
8991 }
pbrook634fce92006-07-15 17:40:09 +00008992
bellardfd1dff42006-02-01 21:29:26 +00008993#ifdef _WIN32
8994 socket_init();
8995#endif
8996
bellard7c9d8e02005-11-15 22:16:05 +00008997 /* init network clients */
8998 if (nb_net_clients == 0) {
8999 /* if no clients, we use a default config */
aliguorif441b282008-08-28 20:05:14 +00009000 net_clients[nb_net_clients++] = "nic";
9001#ifdef CONFIG_SLIRP
9002 net_clients[nb_net_clients++] = "user";
9003#endif
bellardc20709a2004-04-21 23:27:19 +00009004 }
9005
bellard7c9d8e02005-11-15 22:16:05 +00009006 for(i = 0;i < nb_net_clients; i++) {
balrog9ad97e62008-07-29 13:16:31 +00009007 if (net_client_parse(net_clients[i]) < 0)
bellard7c9d8e02005-11-15 22:16:05 +00009008 exit(1);
bellard702c6512004-04-02 21:21:32 +00009009 }
blueswir1833c7172007-05-27 19:36:43 +00009010 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
9011 if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
9012 continue;
balrog9ad97e62008-07-29 13:16:31 +00009013 if (vlan->nb_guest_devs == 0)
9014 fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
blueswir1833c7172007-05-27 19:36:43 +00009015 if (vlan->nb_host_devs == 0)
9016 fprintf(stderr,
9017 "Warning: vlan %d is not connected to host network\n",
9018 vlan->id);
9019 }
bellardf1510b22003-06-25 00:07:40 +00009020
thseec85c22007-01-05 17:41:07 +00009021#ifdef TARGET_I386
balroged494d82007-12-11 23:23:52 +00009022 /* XXX: this should be moved in the PC machine instantiation code */
j_mayer28c5af52007-11-11 01:50:45 +00009023 if (net_boot != 0) {
9024 int netroms = 0;
9025 for (i = 0; i < nb_nics && i < 4; i++) {
thseec85c22007-01-05 17:41:07 +00009026 const char *model = nd_table[i].model;
9027 char buf[1024];
j_mayer28c5af52007-11-11 01:50:45 +00009028 if (net_boot & (1 << i)) {
9029 if (model == NULL)
9030 model = "ne2k_pci";
9031 snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
9032 if (get_image_size(buf) > 0) {
9033 if (nb_option_roms >= MAX_OPTION_ROMS) {
9034 fprintf(stderr, "Too many option ROMs\n");
9035 exit(1);
9036 }
9037 option_rom[nb_option_roms] = strdup(buf);
9038 nb_option_roms++;
9039 netroms++;
9040 }
9041 }
thseec85c22007-01-05 17:41:07 +00009042 }
j_mayer28c5af52007-11-11 01:50:45 +00009043 if (netroms == 0) {
thseec85c22007-01-05 17:41:07 +00009044 fprintf(stderr, "No valid PXE rom found for network device\n");
9045 exit(1);
9046 }
thseec85c22007-01-05 17:41:07 +00009047 }
9048#endif
9049
bellard0824d6f2003-06-24 13:42:40 +00009050 /* init the memory */
balrog7fb4fdc2008-04-24 17:59:27 +00009051 phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
9052
9053 if (machine->ram_require & RAMSIZE_FIXED) {
9054 if (ram_size > 0) {
9055 if (ram_size < phys_ram_size) {
aurel32cd940062008-04-28 20:26:54 +00009056 fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
9057 machine->name, (unsigned long long) phys_ram_size);
balrog7fb4fdc2008-04-24 17:59:27 +00009058 exit(-1);
9059 }
9060
9061 phys_ram_size = ram_size;
9062 } else
9063 ram_size = phys_ram_size;
9064 } else {
aurel324fc5d072008-04-27 21:39:40 +00009065 if (ram_size == 0)
balrog7fb4fdc2008-04-24 17:59:27 +00009066 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
9067
9068 phys_ram_size += ram_size;
9069 }
ths9ae02552007-01-05 17:39:04 +00009070
bellardd993e022005-02-10 22:00:06 +00009071 phys_ram_base = qemu_vmalloc(phys_ram_size);
bellard7f7f9872003-10-30 01:11:23 +00009072 if (!phys_ram_base) {
9073 fprintf(stderr, "Could not allocate physical memory\n");
bellard0824d6f2003-06-24 13:42:40 +00009074 exit(1);
9075 }
9076
bellard26a5f132008-05-28 12:30:31 +00009077 /* init the dynamic translator */
9078 cpu_exec_init_all(tb_size * 1024 * 1024);
9079
bellard5905b2e2004-08-01 21:53:26 +00009080 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00009081
9082 /* we always create the cdrom drive, even if no disk is there */
9083
9084 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009085 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00009086
balrog9d413d12007-12-04 00:10:34 +00009087 /* we always create at least one floppy */
thse4bcb142007-12-02 04:51:10 +00009088
9089 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009090 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00009091
balrog9d413d12007-12-04 00:10:34 +00009092 /* we always create one sd slot, even if no card is in it */
9093
9094 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009095 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00009096
ths96d30e42007-01-07 20:42:14 +00009097 /* open the virtual block devices */
bellardc4b1fcc2004-03-14 21:44:30 +00009098
thse4bcb142007-12-02 04:51:10 +00009099 for(i = 0; i < nb_drives_opt; i++)
balrog609497a2008-01-14 02:56:53 +00009100 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
thse4bcb142007-12-02 04:51:10 +00009101 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00009102
bellardc88676f2006-08-06 13:36:11 +00009103 register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
9104 register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00009105
bellard313aa562003-08-10 21:52:11 +00009106 /* terminal init */
ths740733b2007-06-08 01:57:56 +00009107 memset(&display_state, 0, sizeof(display_state));
bellarda20dd502003-09-30 21:07:02 +00009108 if (nographic) {
balrog4d3b6f62008-02-10 16:33:14 +00009109 if (curses) {
9110 fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
9111 exit(1);
9112 }
ths2ff89792007-06-21 23:34:19 +00009113 /* nearly nothing to do */
9114 dumb_display_init(ds);
ths73fc9742006-12-22 02:09:07 +00009115 } else if (vnc_display != NULL) {
ths71cab5c2007-08-25 01:35:38 +00009116 vnc_display_init(ds);
9117 if (vnc_display_open(ds, vnc_display) < 0)
9118 exit(1);
balrog4d3b6f62008-02-10 16:33:14 +00009119 } else
9120#if defined(CONFIG_CURSES)
9121 if (curses) {
9122 curses_display_init(ds, full_screen);
9123 } else
9124#endif
9125 {
bellard5b0753e2005-03-01 21:37:28 +00009126#if defined(CONFIG_SDL)
ths43523e92007-02-18 18:19:32 +00009127 sdl_display_init(ds, full_screen, no_frame);
bellard5b0753e2005-03-01 21:37:28 +00009128#elif defined(CONFIG_COCOA)
9129 cocoa_display_init(ds, full_screen);
pbrook67276f52007-11-15 19:04:08 +00009130#else
9131 dumb_display_init(ds);
bellard313aa562003-08-10 21:52:11 +00009132#endif
9133 }
bellard0824d6f2003-06-24 13:42:40 +00009134
aliguori5b08fc12008-08-21 20:08:03 +00009135#ifndef _WIN32
9136 /* must be after terminal init, SDL library changes signal handlers */
9137 termsig_setup();
9138#endif
9139
ths20d8a3e2007-02-18 17:04:49 +00009140 /* Maintain compatibility with multiple stdio monitors */
9141 if (!strcmp(monitor_device,"stdio")) {
9142 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
pbrookfd5f3932008-03-26 20:55:43 +00009143 const char *devname = serial_devices[i];
9144 if (devname && !strcmp(devname,"mon:stdio")) {
9145 monitor_device = NULL;
ths20d8a3e2007-02-18 17:04:49 +00009146 break;
pbrookfd5f3932008-03-26 20:55:43 +00009147 } else if (devname && !strcmp(devname,"stdio")) {
9148 monitor_device = NULL;
9149 serial_devices[i] = "mon:stdio";
ths20d8a3e2007-02-18 17:04:49 +00009150 break;
9151 }
9152 }
bellard82c643f2004-07-14 17:28:13 +00009153 }
pbrookfd5f3932008-03-26 20:55:43 +00009154 if (monitor_device) {
ths20d8a3e2007-02-18 17:04:49 +00009155 monitor_hd = qemu_chr_open(monitor_device);
9156 if (!monitor_hd) {
9157 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
9158 exit(1);
9159 }
9160 monitor_init(monitor_hd, !nographic);
9161 }
bellard82c643f2004-07-14 17:28:13 +00009162
bellard8d11df92004-08-24 21:13:40 +00009163 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00009164 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00009165 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00009166 serial_hds[i] = qemu_chr_open(devname);
bellard8d11df92004-08-24 21:13:40 +00009167 if (!serial_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00009168 fprintf(stderr, "qemu: could not open serial device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00009169 devname);
bellard8d11df92004-08-24 21:13:40 +00009170 exit(1);
9171 }
thsaf3a9032007-07-11 23:14:59 +00009172 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00009173 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00009174 }
bellard82c643f2004-07-14 17:28:13 +00009175 }
bellard82c643f2004-07-14 17:28:13 +00009176
bellard6508fe52005-01-15 12:02:56 +00009177 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00009178 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00009179 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00009180 parallel_hds[i] = qemu_chr_open(devname);
bellard6508fe52005-01-15 12:02:56 +00009181 if (!parallel_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00009182 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00009183 devname);
bellard6508fe52005-01-15 12:02:56 +00009184 exit(1);
9185 }
thsaf3a9032007-07-11 23:14:59 +00009186 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00009187 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00009188 }
9189 }
9190
blueswir1b881c2c2007-11-18 08:46:58 +00009191 machine->init(ram_size, vga_ram_size, boot_devices, ds,
j_mayer94fc95c2007-03-05 19:44:02 +00009192 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
bellard73332e52004-04-04 20:22:28 +00009193
pbrook0d92ed32006-05-21 16:30:15 +00009194 /* init USB devices */
9195 if (usb_enabled) {
9196 for(i = 0; i < usb_devices_index; i++) {
9197 if (usb_device_add(usb_devices[i]) < 0) {
9198 fprintf(stderr, "Warning: could not add USB device %s\n",
9199 usb_devices[i]);
9200 }
9201 }
9202 }
9203
ths740733b2007-06-08 01:57:56 +00009204 if (display_state.dpy_refresh) {
9205 display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
9206 qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
9207 }
bellard7f7f9872003-10-30 01:11:23 +00009208
bellard67b915a2004-03-31 23:37:16 +00009209#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00009210 if (use_gdbstub) {
bellardc636bb62007-02-05 20:46:05 +00009211 /* XXX: use standard host:port notation and modify options
9212 accordingly. */
pbrookcfc34752007-02-22 01:48:01 +00009213 if (gdbserver_start(gdbstub_port) < 0) {
9214 fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
bellardc636bb62007-02-05 20:46:05 +00009215 gdbstub_port);
bellard8a7ddc32004-03-31 19:00:16 +00009216 exit(1);
bellard8a7ddc32004-03-31 19:00:16 +00009217 }
balrog45669e02007-07-02 13:20:17 +00009218 }
bellard67b915a2004-03-31 23:37:16 +00009219#endif
balrog45669e02007-07-02 13:20:17 +00009220
bellardd63d3072004-10-03 13:29:03 +00009221 if (loadvm)
bellardfaea38e2006-08-05 21:31:00 +00009222 do_loadvm(loadvm);
bellardd63d3072004-10-03 13:29:03 +00009223
bellard67b915a2004-03-31 23:37:16 +00009224 {
bellard5905b2e2004-08-01 21:53:26 +00009225 /* XXX: simplify init */
aliguori83ab7952008-08-19 14:44:22 +00009226 read_passwords();
pbrook3c07f8e2007-01-21 16:47:01 +00009227 if (autostart) {
bellard5905b2e2004-08-01 21:53:26 +00009228 vm_start();
9229 }
bellard0824d6f2003-06-24 13:42:40 +00009230 }
thsffd843b2006-12-21 19:46:43 +00009231
ths71e3ceb2006-12-22 02:11:31 +00009232 if (daemonize) {
9233 uint8_t status = 0;
9234 ssize_t len;
9235 int fd;
9236
9237 again1:
9238 len = write(fds[1], &status, 1);
9239 if (len == -1 && (errno == EINTR))
9240 goto again1;
9241
9242 if (len != 1)
9243 exit(1);
9244
aliguoribd54b862008-07-23 00:58:33 +00009245 chdir("/");
balrogaeb30be2007-07-02 15:03:13 +00009246 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00009247 if (fd == -1)
9248 exit(1);
9249
9250 dup2(fd, 0);
9251 dup2(fd, 1);
9252 dup2(fd, 2);
9253
9254 close(fd);
9255 }
9256
bellard8a7ddc32004-03-31 19:00:16 +00009257 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00009258 quit_timers();
thsb46a8902007-10-21 23:20:45 +00009259
ths7d294b62007-10-26 17:21:58 +00009260#if !defined(_WIN32)
thsb46a8902007-10-21 23:20:45 +00009261 /* close network clients */
9262 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
9263 VLANClientState *vc;
9264
ths7d294b62007-10-26 17:21:58 +00009265 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
thsb46a8902007-10-21 23:20:45 +00009266 if (vc->fd_read == tap_receive) {
9267 char ifname[64];
9268 TAPState *s = vc->opaque;
9269
9270 if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
9271 s->down_script[0])
9272 launch_script(s->down_script, ifname, s->fd);
9273 }
ths8a16d272008-07-19 09:56:24 +00009274#if defined(CONFIG_VDE)
9275 if (vc->fd_read == vde_from_qemu) {
9276 VDEState *s = vc->opaque;
9277 vde_close(s->vde);
9278 }
9279#endif
ths4fddf622007-12-17 04:42:29 +00009280 }
ths7d294b62007-10-26 17:21:58 +00009281 }
9282#endif
bellard0824d6f2003-06-24 13:42:40 +00009283 return 0;
9284}