blob: 0619f1c6120e929c5ff34cde5763235ca0a817e8 [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
thscb4b9762007-09-13 12:39:35 +0000103#else
104#include <winsock2.h>
105int inet_aton(const char *cp, struct in_addr *ia);
bellardec530c82006-04-25 22:36:06 +0000106#endif
bellard67b915a2004-03-31 23:37:16 +0000107
bellardc20709a2004-04-21 23:27:19 +0000108#if defined(CONFIG_SLIRP)
109#include "libslirp.h"
110#endif
111
blueswir19892fbf2008-08-24 10:34:20 +0000112#if defined(__OpenBSD__)
113#include <util.h>
114#endif
115
ths8a16d272008-07-19 09:56:24 +0000116#if defined(CONFIG_VDE)
117#include <libvdeplug.h>
118#endif
119
bellard67b915a2004-03-31 23:37:16 +0000120#ifdef _WIN32
bellard7d3505c2004-05-12 19:32:15 +0000121#include <malloc.h>
bellard67b915a2004-03-31 23:37:16 +0000122#include <sys/timeb.h>
ths4fddf622007-12-17 04:42:29 +0000123#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000124#define getopt_long_only getopt_long
125#define memalign(align, size) malloc(size)
126#endif
127
bellard6ca957f2006-04-30 22:53:25 +0000128#include "qemu_socket.h"
129
bellard73332e52004-04-04 20:22:28 +0000130#ifdef CONFIG_SDL
bellard96bcd4f2004-07-10 16:26:15 +0000131#ifdef __APPLE__
bellard83fb7ad2004-07-05 21:25:26 +0000132#include <SDL/SDL.h>
bellard96bcd4f2004-07-10 16:26:15 +0000133#endif
bellard73332e52004-04-04 20:22:28 +0000134#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000135
bellard5b0753e2005-03-01 21:37:28 +0000136#ifdef CONFIG_COCOA
137#undef main
138#define main qemu_main
139#endif /* CONFIG_COCOA */
140
bellard0824d6f2003-06-24 13:42:40 +0000141#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000142
bellard8a7ddc32004-03-31 19:00:16 +0000143#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000144
bellard5a671352003-10-01 00:13:48 +0000145#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
thsb46a8902007-10-21 23:20:45 +0000146#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
pbrooka14d6c82006-12-23 15:37:33 +0000147#ifdef __sun__
148#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
149#else
150#define SMBD_COMMAND "/usr/sbin/smbd"
151#endif
bellardf1510b22003-06-25 00:07:40 +0000152
bellard0824d6f2003-06-24 13:42:40 +0000153//#define DEBUG_UNUSED_IOPORT
bellardfd872592004-05-12 19:11:15 +0000154//#define DEBUG_IOPORT
bellard330d0412003-07-26 18:11:40 +0000155
bellard77d4bc32004-05-26 22:13:53 +0000156#ifdef TARGET_PPC
157#define DEFAULT_RAM_SIZE 144
158#else
bellard1bfe8562004-07-08 21:17:50 +0000159#define DEFAULT_RAM_SIZE 128
bellard77d4bc32004-05-26 22:13:53 +0000160#endif
bellard313aa562003-08-10 21:52:11 +0000161
pbrook0d92ed32006-05-21 16:30:15 +0000162/* Max number of USB devices that can be specified on the commandline. */
163#define MAX_USB_CMDLINE 8
164
bellard7dea1da2003-11-16 15:59:30 +0000165/* XXX: use a two level table to limit memory usage */
166#define MAX_IOPORTS 65536
bellard0824d6f2003-06-24 13:42:40 +0000167
bellard80cabfa2004-03-14 12:20:30 +0000168const char *bios_dir = CONFIG_QEMU_SHAREDIR;
j_mayer1192dad2007-10-05 13:08:35 +0000169const char *bios_name = NULL;
bellardc4b1fcc2004-03-14 21:44:30 +0000170void *ioport_opaque[MAX_IOPORTS];
bellardfc01f7e2003-06-30 10:03:06 +0000171IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
172IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
thse4bcb142007-12-02 04:51:10 +0000173/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000174 to store the VM snapshots */
thse4bcb142007-12-02 04:51:10 +0000175DriveInfo drives_table[MAX_DRIVES+1];
176int nb_drives;
bellardfaea38e2006-08-05 21:31:00 +0000177/* point to the block driver where the snapshots are managed */
178BlockDriverState *bs_snapshots;
bellard313aa562003-08-10 21:52:11 +0000179int vga_ram_size;
180static DisplayState display_state;
bellarda20dd502003-09-30 21:07:02 +0000181int nographic;
balrog4d3b6f62008-02-10 16:33:14 +0000182int curses;
bellard3d11d0e2004-12-12 16:56:30 +0000183const char* keyboard_layout = NULL;
bellard313aa562003-08-10 21:52:11 +0000184int64_t ticks_per_sec;
aurel3200f82b82008-04-27 21:12:55 +0000185ram_addr_t ram_size;
bellard80cabfa2004-03-14 12:20:30 +0000186int pit_min_timer_count = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000187int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000188NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000189int vm_running;
balrogf6503052008-02-17 11:42:19 +0000190static int rtc_utc = 1;
191static int rtc_date_offset = -1; /* -1 means no change */
bellard1bfe8562004-07-08 21:17:50 +0000192int cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +0000193int vmsvga_enabled = 0;
bellardd8272202005-04-06 20:32:23 +0000194#ifdef TARGET_SPARC
195int graphic_width = 1024;
196int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000197int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000198#else
bellard1bfe8562004-07-08 21:17:50 +0000199int graphic_width = 800;
200int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000201int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000202#endif
bellardd63d3072004-10-03 13:29:03 +0000203int full_screen = 0;
ths43523e92007-02-18 18:19:32 +0000204int no_frame = 0;
ths667acca2006-12-11 02:08:05 +0000205int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000206CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000207CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
bellarda09db212005-04-30 16:10:35 +0000208#ifdef TARGET_I386
209int win2k_install_hack = 0;
210#endif
bellardbb36d472005-11-05 14:22:28 +0000211int usb_enabled = 0;
bellard7c9d8e02005-11-15 22:16:05 +0000212static VLANState *first_vlan;
bellard6a00d602005-11-21 23:25:50 +0000213int smp_cpus = 1;
ths73fc9742006-12-22 02:09:07 +0000214const char *vnc_display;
bellardd3e9db92005-12-17 01:27:28 +0000215#if defined(TARGET_SPARC)
bellardba3c64f2005-12-05 20:31:52 +0000216#define MAX_CPUS 16
bellardd3e9db92005-12-17 01:27:28 +0000217#elif defined(TARGET_I386)
218#define MAX_CPUS 255
bellardba3c64f2005-12-05 20:31:52 +0000219#else
bellardd3e9db92005-12-17 01:27:28 +0000220#define MAX_CPUS 1
bellardba3c64f2005-12-05 20:31:52 +0000221#endif
bellard6515b202006-05-03 22:02:44 +0000222int acpi_enabled = 1;
bellard52ca8d62006-06-14 16:03:05 +0000223int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000224int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000225int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000226int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000227int graphic_rotate = 0;
ths71e3ceb2006-12-22 02:11:31 +0000228int daemonize = 0;
ths9ae02552007-01-05 17:39:04 +0000229const char *option_rom[MAX_OPTION_ROMS];
230int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000231int semihosting_enabled = 0;
pbrook3c07f8e2007-01-21 16:47:01 +0000232int autostart = 1;
balrog2b8f2d42007-07-27 22:08:46 +0000233#ifdef TARGET_ARM
234int old_param = 0;
235#endif
thsc35734b2007-03-19 15:17:08 +0000236const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000237int alt_grab = 0;
blueswir166508602007-05-01 14:16:52 +0000238#ifdef TARGET_SPARC
239unsigned int nb_prom_envs = 0;
240const char *prom_envs[MAX_PROM_ENVS];
241#endif
thse4bcb142007-12-02 04:51:10 +0000242int nb_drives_opt;
balrog609497a2008-01-14 02:56:53 +0000243struct drive_opt {
244 const char *file;
245 char opt[1024];
246} drives_opt[MAX_DRIVES];
bellard0824d6f2003-06-24 13:42:40 +0000247
balrogee5605e2007-12-03 03:01:40 +0000248static CPUState *cur_cpu;
249static CPUState *next_cpu;
balrog76ea08f2007-12-16 11:48:54 +0000250static int event_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000251/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000252static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000253/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000254#define MAX_ICOUNT_SHIFT 10
255/* Compensate for varying guest execution speed. */
256static int64_t qemu_icount_bias;
257QEMUTimer *icount_rt_timer;
258QEMUTimer *icount_vm_timer;
balrogee5605e2007-12-03 03:01:40 +0000259
balrogaeb30be2007-07-02 15:03:13 +0000260#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
261
bellard0824d6f2003-06-24 13:42:40 +0000262/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000263/* x86 ISA bus support */
264
265target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000266PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000267
aliguori477e3ed2008-07-23 15:19:59 +0000268static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;
269static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;
270
271static uint32_t ioport_read(int index, uint32_t address)
272{
273 static IOPortReadFunc *default_func[3] = {
274 default_ioport_readb,
275 default_ioport_readw,
276 default_ioport_readl
277 };
278 IOPortReadFunc *func = ioport_read_table[index][address];
279 if (!func)
280 func = default_func[index];
281 return func(ioport_opaque[address], address);
282}
283
284static void ioport_write(int index, uint32_t address, uint32_t data)
285{
286 static IOPortWriteFunc *default_func[3] = {
287 default_ioport_writeb,
288 default_ioport_writew,
289 default_ioport_writel
290 };
291 IOPortWriteFunc *func = ioport_write_table[index][address];
292 if (!func)
293 func = default_func[index];
294 func(ioport_opaque[address], address, data);
295}
296
pbrook9596ebb2007-11-18 01:44:38 +0000297static uint32_t default_ioport_readb(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000298{
299#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000300 fprintf(stderr, "unused inb: port=0x%04x\n", address);
bellard0824d6f2003-06-24 13:42:40 +0000301#endif
bellardfc01f7e2003-06-30 10:03:06 +0000302 return 0xff;
bellard0824d6f2003-06-24 13:42:40 +0000303}
304
pbrook9596ebb2007-11-18 01:44:38 +0000305static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000306{
307#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000308 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
bellard0824d6f2003-06-24 13:42:40 +0000309#endif
310}
311
312/* default is to make two byte accesses */
pbrook9596ebb2007-11-18 01:44:38 +0000313static uint32_t default_ioport_readw(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000314{
315 uint32_t data;
aliguori477e3ed2008-07-23 15:19:59 +0000316 data = ioport_read(0, address);
bellarddb45c292004-05-12 19:50:26 +0000317 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000318 data |= ioport_read(0, address) << 8;
bellard0824d6f2003-06-24 13:42:40 +0000319 return data;
320}
321
pbrook9596ebb2007-11-18 01:44:38 +0000322static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000323{
aliguori477e3ed2008-07-23 15:19:59 +0000324 ioport_write(0, address, data & 0xff);
bellarddb45c292004-05-12 19:50:26 +0000325 address = (address + 1) & (MAX_IOPORTS - 1);
aliguori477e3ed2008-07-23 15:19:59 +0000326 ioport_write(0, address, (data >> 8) & 0xff);
bellardfc01f7e2003-06-30 10:03:06 +0000327}
328
pbrook9596ebb2007-11-18 01:44:38 +0000329static uint32_t default_ioport_readl(void *opaque, uint32_t address)
bellardfc01f7e2003-06-30 10:03:06 +0000330{
331#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000332 fprintf(stderr, "unused inl: port=0x%04x\n", address);
bellardfc01f7e2003-06-30 10:03:06 +0000333#endif
334 return 0xffffffff;
335}
336
pbrook9596ebb2007-11-18 01:44:38 +0000337static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
bellardfc01f7e2003-06-30 10:03:06 +0000338{
339#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000340 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
bellardfc01f7e2003-06-30 10:03:06 +0000341#endif
bellard0824d6f2003-06-24 13:42:40 +0000342}
343
bellardfc01f7e2003-06-30 10:03:06 +0000344/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000345int register_ioport_read(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000346 IOPortReadFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000347{
bellardfc01f7e2003-06-30 10:03:06 +0000348 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000349
bellardc4b1fcc2004-03-14 21:44:30 +0000350 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000351 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000352 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000353 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000354 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000355 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000356 } else {
balrog88fdf562008-04-26 21:11:22 +0000357 hw_error("register_ioport_read: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000358 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000359 }
360 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000361 ioport_read_table[bsize][i] = func;
bellardc4b1fcc2004-03-14 21:44:30 +0000362 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
balrog88fdf562008-04-26 21:11:22 +0000363 hw_error("register_ioport_read: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000364 ioport_opaque[i] = opaque;
365 }
bellard0824d6f2003-06-24 13:42:40 +0000366 return 0;
367}
368
bellardfc01f7e2003-06-30 10:03:06 +0000369/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000370int register_ioport_write(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000371 IOPortWriteFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000372{
bellardfc01f7e2003-06-30 10:03:06 +0000373 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000374
bellardc4b1fcc2004-03-14 21:44:30 +0000375 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000376 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000377 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000378 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000379 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000380 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000381 } else {
balrog88fdf562008-04-26 21:11:22 +0000382 hw_error("register_ioport_write: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000383 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000384 }
385 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000386 ioport_write_table[bsize][i] = func;
balrog88fdf562008-04-26 21:11:22 +0000387 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
388 hw_error("register_ioport_write: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000389 ioport_opaque[i] = opaque;
390 }
bellardf1510b22003-06-25 00:07:40 +0000391 return 0;
392}
393
bellard69b91032004-05-18 23:05:28 +0000394void isa_unassign_ioport(int start, int length)
395{
396 int i;
397
398 for(i = start; i < start + length; i++) {
399 ioport_read_table[0][i] = default_ioport_readb;
400 ioport_read_table[1][i] = default_ioport_readw;
401 ioport_read_table[2][i] = default_ioport_readl;
402
403 ioport_write_table[0][i] = default_ioport_writeb;
404 ioport_write_table[1][i] = default_ioport_writew;
405 ioport_write_table[2][i] = default_ioport_writel;
406 }
407}
408
bellard20f32282005-01-03 23:36:21 +0000409/***********************************************************/
410
bellardc45886d2004-01-05 00:02:06 +0000411void cpu_outb(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000412{
bellardfd872592004-05-12 19:11:15 +0000413#ifdef DEBUG_IOPORT
414 if (loglevel & CPU_LOG_IOPORT)
415 fprintf(logfile, "outb: %04x %02x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000416#endif
aliguori477e3ed2008-07-23 15:19:59 +0000417 ioport_write(0, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000418#ifdef USE_KQEMU
419 if (env)
420 env->last_io_time = cpu_get_time_fast();
421#endif
bellard0824d6f2003-06-24 13:42:40 +0000422}
423
bellardc45886d2004-01-05 00:02:06 +0000424void cpu_outw(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000425{
bellardfd872592004-05-12 19:11:15 +0000426#ifdef DEBUG_IOPORT
427 if (loglevel & CPU_LOG_IOPORT)
428 fprintf(logfile, "outw: %04x %04x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000429#endif
aliguori477e3ed2008-07-23 15:19:59 +0000430 ioport_write(1, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000431#ifdef USE_KQEMU
432 if (env)
433 env->last_io_time = cpu_get_time_fast();
434#endif
bellard0824d6f2003-06-24 13:42:40 +0000435}
436
bellardc45886d2004-01-05 00:02:06 +0000437void cpu_outl(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000438{
bellardfd872592004-05-12 19:11:15 +0000439#ifdef DEBUG_IOPORT
440 if (loglevel & CPU_LOG_IOPORT)
441 fprintf(logfile, "outl: %04x %08x\n", addr, val);
442#endif
aliguori477e3ed2008-07-23 15:19:59 +0000443 ioport_write(2, addr, val);
bellard89bfc102006-02-08 22:46:31 +0000444#ifdef USE_KQEMU
445 if (env)
446 env->last_io_time = cpu_get_time_fast();
447#endif
bellard0824d6f2003-06-24 13:42:40 +0000448}
449
bellardc45886d2004-01-05 00:02:06 +0000450int cpu_inb(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000451{
bellardfd872592004-05-12 19:11:15 +0000452 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000453 val = ioport_read(0, addr);
bellardfd872592004-05-12 19:11:15 +0000454#ifdef DEBUG_IOPORT
455 if (loglevel & CPU_LOG_IOPORT)
456 fprintf(logfile, "inb : %04x %02x\n", addr, val);
457#endif
bellard89bfc102006-02-08 22:46:31 +0000458#ifdef USE_KQEMU
459 if (env)
460 env->last_io_time = cpu_get_time_fast();
461#endif
bellardfd872592004-05-12 19:11:15 +0000462 return val;
bellard0824d6f2003-06-24 13:42:40 +0000463}
464
bellardc45886d2004-01-05 00:02:06 +0000465int cpu_inw(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000466{
bellardfd872592004-05-12 19:11:15 +0000467 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000468 val = ioport_read(1, addr);
bellardfd872592004-05-12 19:11:15 +0000469#ifdef DEBUG_IOPORT
470 if (loglevel & CPU_LOG_IOPORT)
471 fprintf(logfile, "inw : %04x %04x\n", addr, val);
472#endif
bellard89bfc102006-02-08 22:46:31 +0000473#ifdef USE_KQEMU
474 if (env)
475 env->last_io_time = cpu_get_time_fast();
476#endif
bellardfd872592004-05-12 19:11:15 +0000477 return val;
bellard0824d6f2003-06-24 13:42:40 +0000478}
479
bellardc45886d2004-01-05 00:02:06 +0000480int cpu_inl(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000481{
bellardfd872592004-05-12 19:11:15 +0000482 int val;
aliguori477e3ed2008-07-23 15:19:59 +0000483 val = ioport_read(2, addr);
bellardfd872592004-05-12 19:11:15 +0000484#ifdef DEBUG_IOPORT
485 if (loglevel & CPU_LOG_IOPORT)
486 fprintf(logfile, "inl : %04x %08x\n", addr, val);
487#endif
bellard89bfc102006-02-08 22:46:31 +0000488#ifdef USE_KQEMU
489 if (env)
490 env->last_io_time = cpu_get_time_fast();
491#endif
bellardfd872592004-05-12 19:11:15 +0000492 return val;
bellard0824d6f2003-06-24 13:42:40 +0000493}
494
495/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000496void hw_error(const char *fmt, ...)
497{
498 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000499 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000500
501 va_start(ap, fmt);
502 fprintf(stderr, "qemu: hardware error: ");
503 vfprintf(stderr, fmt, ap);
504 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000505 for(env = first_cpu; env != NULL; env = env->next_cpu) {
506 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000507#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000508 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000509#else
bellard6a00d602005-11-21 23:25:50 +0000510 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000511#endif
bellard6a00d602005-11-21 23:25:50 +0000512 }
bellard0824d6f2003-06-24 13:42:40 +0000513 va_end(ap);
514 abort();
515}
516
bellard8a7ddc32004-03-31 19:00:16 +0000517/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000518/* keyboard/mouse */
519
520static QEMUPutKBDEvent *qemu_put_kbd_event;
521static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000522static QEMUPutMouseEntry *qemu_put_mouse_event_head;
523static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000524
525void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
526{
527 qemu_put_kbd_event_opaque = opaque;
528 qemu_put_kbd_event = func;
529}
530
ths455204e2007-01-05 16:42:13 +0000531QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
532 void *opaque, int absolute,
533 const char *name)
bellard63066f42004-06-03 18:45:02 +0000534{
ths455204e2007-01-05 16:42:13 +0000535 QEMUPutMouseEntry *s, *cursor;
536
537 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
538 if (!s)
539 return NULL;
540
541 s->qemu_put_mouse_event = func;
542 s->qemu_put_mouse_event_opaque = opaque;
543 s->qemu_put_mouse_event_absolute = absolute;
544 s->qemu_put_mouse_event_name = qemu_strdup(name);
545 s->next = NULL;
546
547 if (!qemu_put_mouse_event_head) {
548 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
549 return s;
550 }
551
552 cursor = qemu_put_mouse_event_head;
553 while (cursor->next != NULL)
554 cursor = cursor->next;
555
556 cursor->next = s;
557 qemu_put_mouse_event_current = s;
558
559 return s;
560}
561
562void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
563{
564 QEMUPutMouseEntry *prev = NULL, *cursor;
565
566 if (!qemu_put_mouse_event_head || entry == NULL)
567 return;
568
569 cursor = qemu_put_mouse_event_head;
570 while (cursor != NULL && cursor != entry) {
571 prev = cursor;
572 cursor = cursor->next;
573 }
574
575 if (cursor == NULL) // does not exist or list empty
576 return;
577 else if (prev == NULL) { // entry is head
578 qemu_put_mouse_event_head = cursor->next;
579 if (qemu_put_mouse_event_current == entry)
580 qemu_put_mouse_event_current = cursor->next;
581 qemu_free(entry->qemu_put_mouse_event_name);
582 qemu_free(entry);
583 return;
584 }
585
586 prev->next = entry->next;
587
588 if (qemu_put_mouse_event_current == entry)
589 qemu_put_mouse_event_current = prev;
590
591 qemu_free(entry->qemu_put_mouse_event_name);
592 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000593}
594
595void kbd_put_keycode(int keycode)
596{
597 if (qemu_put_kbd_event) {
598 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
599 }
600}
601
602void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
603{
ths455204e2007-01-05 16:42:13 +0000604 QEMUPutMouseEvent *mouse_event;
605 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000606 int width;
ths455204e2007-01-05 16:42:13 +0000607
608 if (!qemu_put_mouse_event_current) {
609 return;
610 }
611
612 mouse_event =
613 qemu_put_mouse_event_current->qemu_put_mouse_event;
614 mouse_event_opaque =
615 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
616
617 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000618 if (graphic_rotate) {
619 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
620 width = 0x7fff;
621 else
aurel32b94ed572008-03-10 19:34:27 +0000622 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000623 mouse_event(mouse_event_opaque,
624 width - dy, dx, dz, buttons_state);
625 } else
626 mouse_event(mouse_event_opaque,
627 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000628 }
629}
630
bellard09b26c52006-04-12 21:09:08 +0000631int kbd_mouse_is_absolute(void)
632{
ths455204e2007-01-05 16:42:13 +0000633 if (!qemu_put_mouse_event_current)
634 return 0;
635
636 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
637}
638
639void do_info_mice(void)
640{
641 QEMUPutMouseEntry *cursor;
642 int index = 0;
643
644 if (!qemu_put_mouse_event_head) {
645 term_printf("No mouse devices connected\n");
646 return;
647 }
648
649 term_printf("Mouse devices available:\n");
650 cursor = qemu_put_mouse_event_head;
651 while (cursor != NULL) {
652 term_printf("%c Mouse #%d: %s\n",
653 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
654 index, cursor->qemu_put_mouse_event_name);
655 index++;
656 cursor = cursor->next;
657 }
658}
659
660void do_mouse_set(int index)
661{
662 QEMUPutMouseEntry *cursor;
663 int i = 0;
664
665 if (!qemu_put_mouse_event_head) {
666 term_printf("No mouse devices connected\n");
667 return;
668 }
669
670 cursor = qemu_put_mouse_event_head;
671 while (cursor != NULL && index != i) {
672 i++;
673 cursor = cursor->next;
674 }
675
676 if (cursor != NULL)
677 qemu_put_mouse_event_current = cursor;
678 else
679 term_printf("Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000680}
681
bellard87858c82003-06-27 12:01:39 +0000682/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000683uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000684{
685 union {
686 uint64_t ll;
687 struct {
688#ifdef WORDS_BIGENDIAN
689 uint32_t high, low;
690#else
691 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000692#endif
bellard87858c82003-06-27 12:01:39 +0000693 } l;
694 } u, res;
695 uint64_t rl, rh;
696
697 u.ll = a;
698 rl = (uint64_t)u.l.low * (uint64_t)b;
699 rh = (uint64_t)u.l.high * (uint64_t)b;
700 rh += (rl >> 32);
701 res.l.high = rh / c;
702 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
703 return res.ll;
704}
705
bellard1dce7c32006-07-13 23:20:22 +0000706/***********************************************************/
707/* real time host monotonic timer */
708
709#define QEMU_TIMER_BASE 1000000000LL
710
711#ifdef WIN32
712
713static int64_t clock_freq;
714
715static void init_get_clock(void)
716{
bellarda8e5ac32006-07-14 09:36:13 +0000717 LARGE_INTEGER freq;
718 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000719 ret = QueryPerformanceFrequency(&freq);
720 if (ret == 0) {
721 fprintf(stderr, "Could not calibrate ticks\n");
722 exit(1);
723 }
724 clock_freq = freq.QuadPart;
725}
726
727static int64_t get_clock(void)
728{
729 LARGE_INTEGER ti;
730 QueryPerformanceCounter(&ti);
731 return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
732}
733
734#else
735
736static int use_rt_clock;
737
738static void init_get_clock(void)
739{
740 use_rt_clock = 0;
741#if defined(__linux__)
742 {
743 struct timespec ts;
744 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
745 use_rt_clock = 1;
746 }
747 }
748#endif
749}
750
751static int64_t get_clock(void)
752{
753#if defined(__linux__)
754 if (use_rt_clock) {
755 struct timespec ts;
756 clock_gettime(CLOCK_MONOTONIC, &ts);
757 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000758 } else
bellard1dce7c32006-07-13 23:20:22 +0000759#endif
760 {
761 /* XXX: using gettimeofday leads to problems if the date
762 changes, so it should be avoided. */
763 struct timeval tv;
764 gettimeofday(&tv, NULL);
765 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
766 }
767}
bellard1dce7c32006-07-13 23:20:22 +0000768#endif
769
pbrook2e70f6e2008-06-29 01:03:05 +0000770/* Return the virtual CPU time, based on the instruction counter. */
771static int64_t cpu_get_icount(void)
772{
773 int64_t icount;
774 CPUState *env = cpu_single_env;;
775 icount = qemu_icount;
776 if (env) {
777 if (!can_do_io(env))
778 fprintf(stderr, "Bad clock read\n");
779 icount -= (env->icount_decr.u16.low + env->icount_extra);
780 }
781 return qemu_icount_bias + (icount << icount_time_shift);
782}
783
bellard1dce7c32006-07-13 23:20:22 +0000784/***********************************************************/
785/* guest cycle counter */
786
787static int64_t cpu_ticks_prev;
788static int64_t cpu_ticks_offset;
789static int64_t cpu_clock_offset;
790static int cpu_ticks_enabled;
791
792/* return the host CPU cycle counter and handle stop/restart */
793int64_t cpu_get_ticks(void)
794{
pbrook2e70f6e2008-06-29 01:03:05 +0000795 if (use_icount) {
796 return cpu_get_icount();
797 }
bellard1dce7c32006-07-13 23:20:22 +0000798 if (!cpu_ticks_enabled) {
799 return cpu_ticks_offset;
800 } else {
801 int64_t ticks;
802 ticks = cpu_get_real_ticks();
803 if (cpu_ticks_prev > ticks) {
804 /* Note: non increasing ticks may happen if the host uses
805 software suspend */
806 cpu_ticks_offset += cpu_ticks_prev - ticks;
807 }
808 cpu_ticks_prev = ticks;
809 return ticks + cpu_ticks_offset;
810 }
811}
812
813/* return the host CPU monotonic timer and handle stop/restart */
814static int64_t cpu_get_clock(void)
815{
816 int64_t ti;
817 if (!cpu_ticks_enabled) {
818 return cpu_clock_offset;
819 } else {
820 ti = get_clock();
821 return ti + cpu_clock_offset;
822 }
823}
824
825/* enable cpu_get_ticks() */
826void cpu_enable_ticks(void)
827{
828 if (!cpu_ticks_enabled) {
829 cpu_ticks_offset -= cpu_get_real_ticks();
830 cpu_clock_offset -= get_clock();
831 cpu_ticks_enabled = 1;
832 }
833}
834
835/* disable cpu_get_ticks() : the clock is stopped. You must not call
836 cpu_get_ticks() after that. */
837void cpu_disable_ticks(void)
838{
839 if (cpu_ticks_enabled) {
840 cpu_ticks_offset = cpu_get_ticks();
841 cpu_clock_offset = cpu_get_clock();
842 cpu_ticks_enabled = 0;
843 }
844}
845
846/***********************************************************/
847/* timers */
ths5fafdf22007-09-16 21:08:06 +0000848
bellard8a7ddc32004-03-31 19:00:16 +0000849#define QEMU_TIMER_REALTIME 0
850#define QEMU_TIMER_VIRTUAL 1
851
852struct QEMUClock {
853 int type;
854 /* XXX: add frequency */
855};
856
857struct QEMUTimer {
858 QEMUClock *clock;
859 int64_t expire_time;
860 QEMUTimerCB *cb;
861 void *opaque;
862 struct QEMUTimer *next;
863};
864
thsc8994012007-08-19 21:56:03 +0000865struct qemu_alarm_timer {
866 char const *name;
thsefe75412007-08-24 01:36:32 +0000867 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000868
869 int (*start)(struct qemu_alarm_timer *t);
870 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000871 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000872 void *priv;
873};
874
thsefe75412007-08-24 01:36:32 +0000875#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000876#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000877
878static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
879{
880 return t->flags & ALARM_FLAG_DYNTICKS;
881}
882
883static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
884{
885 if (!alarm_has_dynticks(t))
886 return;
887
888 t->rearm(t);
889}
890
891/* TODO: MIN_TIMER_REARM_US should be optimized */
892#define MIN_TIMER_REARM_US 250
893
thsc8994012007-08-19 21:56:03 +0000894static struct qemu_alarm_timer *alarm_timer;
895
896#ifdef _WIN32
897
898struct qemu_alarm_win32 {
899 MMRESULT timerId;
900 HANDLE host_alarm;
901 unsigned int period;
902} alarm_win32_data = {0, NULL, -1};
903
904static int win32_start_timer(struct qemu_alarm_timer *t);
905static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000906static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000907
908#else
909
910static int unix_start_timer(struct qemu_alarm_timer *t);
911static void unix_stop_timer(struct qemu_alarm_timer *t);
912
ths231c6582007-08-26 17:29:15 +0000913#ifdef __linux__
914
thsefe75412007-08-24 01:36:32 +0000915static int dynticks_start_timer(struct qemu_alarm_timer *t);
916static void dynticks_stop_timer(struct qemu_alarm_timer *t);
917static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
918
thsc40ec5a2007-08-19 22:09:40 +0000919static int hpet_start_timer(struct qemu_alarm_timer *t);
920static void hpet_stop_timer(struct qemu_alarm_timer *t);
921
thsc8994012007-08-19 21:56:03 +0000922static int rtc_start_timer(struct qemu_alarm_timer *t);
923static void rtc_stop_timer(struct qemu_alarm_timer *t);
924
thsefe75412007-08-24 01:36:32 +0000925#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000926
927#endif /* _WIN32 */
928
pbrook2e70f6e2008-06-29 01:03:05 +0000929/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000930 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000931 When the guest is idle real and virtual time will be aligned in
932 the IO wait loop. */
933#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
934
935static void icount_adjust(void)
936{
937 int64_t cur_time;
938 int64_t cur_icount;
939 int64_t delta;
940 static int64_t last_delta;
941 /* If the VM is not running, then do nothing. */
942 if (!vm_running)
943 return;
944
945 cur_time = cpu_get_clock();
946 cur_icount = qemu_get_clock(vm_clock);
947 delta = cur_icount - cur_time;
948 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
949 if (delta > 0
950 && last_delta + ICOUNT_WOBBLE < delta * 2
951 && icount_time_shift > 0) {
952 /* The guest is getting too far ahead. Slow time down. */
953 icount_time_shift--;
954 }
955 if (delta < 0
956 && last_delta - ICOUNT_WOBBLE > delta * 2
957 && icount_time_shift < MAX_ICOUNT_SHIFT) {
958 /* The guest is getting too far behind. Speed time up. */
959 icount_time_shift++;
960 }
961 last_delta = delta;
962 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
963}
964
965static void icount_adjust_rt(void * opaque)
966{
967 qemu_mod_timer(icount_rt_timer,
968 qemu_get_clock(rt_clock) + 1000);
969 icount_adjust();
970}
971
972static void icount_adjust_vm(void * opaque)
973{
974 qemu_mod_timer(icount_vm_timer,
975 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
976 icount_adjust();
977}
978
979static void init_icount_adjust(void)
980{
981 /* Have both realtime and virtual time triggers for speed adjustment.
982 The realtime trigger catches emulated time passing too slowly,
983 the virtual time trigger catches emulated time passing too fast.
984 Realtime triggers occur even when idle, so use them less frequently
985 than VM triggers. */
986 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
987 qemu_mod_timer(icount_rt_timer,
988 qemu_get_clock(rt_clock) + 1000);
989 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
990 qemu_mod_timer(icount_vm_timer,
991 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
992}
993
thsc8994012007-08-19 21:56:03 +0000994static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000995#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000996#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000997 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
998 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000999 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +00001000 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +00001001 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +00001002 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001003#endif
thsefe75412007-08-24 01:36:32 +00001004 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +00001005#else
thsefe75412007-08-24 01:36:32 +00001006 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
1007 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
1008 {"win32", 0, win32_start_timer,
1009 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +00001010#endif
1011 {NULL, }
1012};
1013
blueswir13f47aa82008-03-09 06:59:01 +00001014static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +00001015{
1016 int i;
1017
1018 printf("Available alarm timers, in order of precedence:\n");
1019 for (i = 0; alarm_timers[i].name; i++)
1020 printf("%s\n", alarm_timers[i].name);
1021}
1022
1023static void configure_alarms(char const *opt)
1024{
1025 int i;
1026 int cur = 0;
1027 int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
1028 char *arg;
1029 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +00001030 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +00001031
aurel323adda042008-03-09 23:43:49 +00001032 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +00001033 show_available_alarms();
1034 exit(0);
1035 }
1036
1037 arg = strdup(opt);
1038
1039 /* Reorder the array */
1040 name = strtok(arg, ",");
1041 while (name) {
balroge2b577e2007-09-17 21:25:20 +00001042 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +00001043 if (!strcmp(alarm_timers[i].name, name))
1044 break;
1045 }
1046
1047 if (i == count) {
1048 fprintf(stderr, "Unknown clock %s\n", name);
1049 goto next;
1050 }
1051
1052 if (i < cur)
1053 /* Ignore */
1054 goto next;
1055
1056 /* Swap */
1057 tmp = alarm_timers[i];
1058 alarm_timers[i] = alarm_timers[cur];
1059 alarm_timers[cur] = tmp;
1060
1061 cur++;
1062next:
1063 name = strtok(NULL, ",");
1064 }
1065
1066 free(arg);
1067
1068 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +00001069 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +00001070 for (i = cur; i < count; i++)
1071 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +00001072 } else {
1073 show_available_alarms();
1074 exit(1);
thsf3dcfad2007-08-24 01:26:02 +00001075 }
thsf3dcfad2007-08-24 01:26:02 +00001076}
1077
bellard8a7ddc32004-03-31 19:00:16 +00001078QEMUClock *rt_clock;
1079QEMUClock *vm_clock;
1080
1081static QEMUTimer *active_timers[2];
bellard8a7ddc32004-03-31 19:00:16 +00001082
pbrook9596ebb2007-11-18 01:44:38 +00001083static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +00001084{
1085 QEMUClock *clock;
1086 clock = qemu_mallocz(sizeof(QEMUClock));
1087 if (!clock)
1088 return NULL;
1089 clock->type = type;
1090 return clock;
1091}
1092
1093QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
1094{
1095 QEMUTimer *ts;
1096
1097 ts = qemu_mallocz(sizeof(QEMUTimer));
1098 ts->clock = clock;
1099 ts->cb = cb;
1100 ts->opaque = opaque;
1101 return ts;
1102}
1103
1104void qemu_free_timer(QEMUTimer *ts)
1105{
1106 qemu_free(ts);
1107}
1108
1109/* stop a timer, but do not dealloc it */
1110void qemu_del_timer(QEMUTimer *ts)
1111{
1112 QEMUTimer **pt, *t;
1113
1114 /* NOTE: this code must be signal safe because
1115 qemu_timer_expired() can be called from a signal. */
1116 pt = &active_timers[ts->clock->type];
1117 for(;;) {
1118 t = *pt;
1119 if (!t)
1120 break;
1121 if (t == ts) {
1122 *pt = t->next;
1123 break;
1124 }
1125 pt = &t->next;
1126 }
1127}
1128
1129/* modify the current timer so that it will be fired when current_time
1130 >= expire_time. The corresponding callback will be called. */
1131void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1132{
1133 QEMUTimer **pt, *t;
1134
1135 qemu_del_timer(ts);
1136
1137 /* add the timer in the sorted list */
1138 /* NOTE: this code must be signal safe because
1139 qemu_timer_expired() can be called from a signal. */
1140 pt = &active_timers[ts->clock->type];
1141 for(;;) {
1142 t = *pt;
1143 if (!t)
1144 break;
ths5fafdf22007-09-16 21:08:06 +00001145 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +00001146 break;
1147 pt = &t->next;
1148 }
1149 ts->expire_time = expire_time;
1150 ts->next = *pt;
1151 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +00001152
1153 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +00001154 if (pt == &active_timers[ts->clock->type]) {
1155 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
1156 qemu_rearm_alarm_timer(alarm_timer);
1157 }
1158 /* Interrupt execution to force deadline recalculation. */
1159 if (use_icount && cpu_single_env) {
1160 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1161 }
1162 }
bellard8a7ddc32004-03-31 19:00:16 +00001163}
1164
1165int qemu_timer_pending(QEMUTimer *ts)
1166{
1167 QEMUTimer *t;
1168 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1169 if (t == ts)
1170 return 1;
1171 }
1172 return 0;
1173}
1174
1175static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1176{
1177 if (!timer_head)
1178 return 0;
1179 return (timer_head->expire_time <= current_time);
1180}
1181
1182static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1183{
1184 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001185
bellard8a7ddc32004-03-31 19:00:16 +00001186 for(;;) {
1187 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001188 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001189 break;
1190 /* remove timer from the list before calling the callback */
1191 *ptimer_head = ts->next;
1192 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001193
bellard8a7ddc32004-03-31 19:00:16 +00001194 /* run the callback (the timer list can be modified) */
1195 ts->cb(ts->opaque);
1196 }
1197}
1198
1199int64_t qemu_get_clock(QEMUClock *clock)
1200{
1201 switch(clock->type) {
1202 case QEMU_TIMER_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001203 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001204 default:
1205 case QEMU_TIMER_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001206 if (use_icount) {
1207 return cpu_get_icount();
1208 } else {
1209 return cpu_get_clock();
1210 }
bellard8a7ddc32004-03-31 19:00:16 +00001211 }
1212}
1213
bellard1dce7c32006-07-13 23:20:22 +00001214static void init_timers(void)
1215{
1216 init_get_clock();
1217 ticks_per_sec = QEMU_TIMER_BASE;
1218 rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1219 vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1220}
1221
bellard8a7ddc32004-03-31 19:00:16 +00001222/* save a timer */
1223void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1224{
1225 uint64_t expire_time;
1226
1227 if (qemu_timer_pending(ts)) {
1228 expire_time = ts->expire_time;
1229 } else {
1230 expire_time = -1;
1231 }
1232 qemu_put_be64(f, expire_time);
1233}
1234
1235void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1236{
1237 uint64_t expire_time;
1238
1239 expire_time = qemu_get_be64(f);
1240 if (expire_time != -1) {
1241 qemu_mod_timer(ts, expire_time);
1242 } else {
1243 qemu_del_timer(ts);
1244 }
1245}
1246
1247static void timer_save(QEMUFile *f, void *opaque)
1248{
1249 if (cpu_ticks_enabled) {
1250 hw_error("cannot save state if virtual timers are running");
1251 }
thsbee8d682007-12-16 23:41:11 +00001252 qemu_put_be64(f, cpu_ticks_offset);
1253 qemu_put_be64(f, ticks_per_sec);
1254 qemu_put_be64(f, cpu_clock_offset);
bellard8a7ddc32004-03-31 19:00:16 +00001255}
1256
1257static int timer_load(QEMUFile *f, void *opaque, int version_id)
1258{
bellardc88676f2006-08-06 13:36:11 +00001259 if (version_id != 1 && version_id != 2)
bellard8a7ddc32004-03-31 19:00:16 +00001260 return -EINVAL;
1261 if (cpu_ticks_enabled) {
1262 return -EINVAL;
1263 }
thsbee8d682007-12-16 23:41:11 +00001264 cpu_ticks_offset=qemu_get_be64(f);
1265 ticks_per_sec=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001266 if (version_id == 2) {
thsbee8d682007-12-16 23:41:11 +00001267 cpu_clock_offset=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001268 }
bellard8a7ddc32004-03-31 19:00:16 +00001269 return 0;
1270}
1271
bellard67b915a2004-03-31 23:37:16 +00001272#ifdef _WIN32
ths5fafdf22007-09-16 21:08:06 +00001273void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
bellard67b915a2004-03-31 23:37:16 +00001274 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1275#else
bellard8a7ddc32004-03-31 19:00:16 +00001276static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001277#endif
bellard8a7ddc32004-03-31 19:00:16 +00001278{
bellard02ba45c2004-06-25 14:46:23 +00001279#if 0
1280#define DISP_FREQ 1000
1281 {
1282 static int64_t delta_min = INT64_MAX;
1283 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1284 static int count;
1285 ti = qemu_get_clock(vm_clock);
1286 if (last_clock != 0) {
1287 delta = ti - last_clock;
1288 if (delta < delta_min)
1289 delta_min = delta;
1290 if (delta > delta_max)
1291 delta_max = delta;
1292 delta_cum += delta;
1293 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001294 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
bellard02ba45c2004-06-25 14:46:23 +00001295 muldiv64(delta_min, 1000000, ticks_per_sec),
1296 muldiv64(delta_max, 1000000, ticks_per_sec),
1297 muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1298 (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1299 count = 0;
1300 delta_min = INT64_MAX;
1301 delta_max = 0;
1302 delta_cum = 0;
1303 }
1304 }
1305 last_clock = ti;
1306 }
1307#endif
thsefe75412007-08-24 01:36:32 +00001308 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001309 (!use_icount &&
1310 qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1311 qemu_get_clock(vm_clock))) ||
bellard8a7ddc32004-03-31 19:00:16 +00001312 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1313 qemu_get_clock(rt_clock))) {
bellard06d9f2f2006-05-01 13:23:04 +00001314#ifdef _WIN32
thsc8994012007-08-19 21:56:03 +00001315 struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1316 SetEvent(data->host_alarm);
bellard06d9f2f2006-05-01 13:23:04 +00001317#endif
balrogee5605e2007-12-03 03:01:40 +00001318 CPUState *env = next_cpu;
1319
balrogd5d08332008-01-05 19:41:47 +00001320 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1321
balrog4f8eb8d2007-12-16 12:39:38 +00001322 if (env) {
1323 /* stop the currently executing cpu because a timer occured */
1324 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
bellarda332e112005-09-03 17:55:47 +00001325#ifdef USE_KQEMU
balrog4f8eb8d2007-12-16 12:39:38 +00001326 if (env->kqemu_enabled) {
1327 kqemu_cpu_interrupt(env);
1328 }
balrogee5605e2007-12-03 03:01:40 +00001329#endif
balrog4f8eb8d2007-12-16 12:39:38 +00001330 }
balrogee5605e2007-12-03 03:01:40 +00001331 event_pending = 1;
bellard8a7ddc32004-03-31 19:00:16 +00001332 }
1333}
1334
pbrook2e70f6e2008-06-29 01:03:05 +00001335static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001336{
pbrook2e70f6e2008-06-29 01:03:05 +00001337 int64_t delta;
thsefe75412007-08-24 01:36:32 +00001338
1339 if (active_timers[QEMU_TIMER_VIRTUAL]) {
pbrook2e70f6e2008-06-29 01:03:05 +00001340 delta = active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1341 qemu_get_clock(vm_clock);
1342 } else {
1343 /* To avoid problems with overflow limit this to 2^32. */
1344 delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001345 }
1346
pbrook2e70f6e2008-06-29 01:03:05 +00001347 if (delta < 0)
1348 delta = 0;
thsefe75412007-08-24 01:36:32 +00001349
pbrook2e70f6e2008-06-29 01:03:05 +00001350 return delta;
1351}
1352
1353static 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}
1375
bellardfd872592004-05-12 19:11:15 +00001376#ifndef _WIN32
1377
bellard829309c2004-05-20 13:20:12 +00001378#if defined(__linux__)
1379
bellardfd872592004-05-12 19:11:15 +00001380#define RTC_FREQ 1024
1381
thsc8994012007-08-19 21:56:03 +00001382static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001383{
thsc8994012007-08-19 21:56:03 +00001384 struct sigaction act;
1385
1386 /* timer signal */
1387 sigfillset(&act.sa_mask);
1388 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001389 act.sa_handler = host_alarm_handler;
1390
1391 sigaction(SIGIO, &act, NULL);
1392 fcntl(fd, F_SETFL, O_ASYNC);
1393 fcntl(fd, F_SETOWN, getpid());
1394}
1395
thsc40ec5a2007-08-19 22:09:40 +00001396static int hpet_start_timer(struct qemu_alarm_timer *t)
1397{
1398 struct hpet_info info;
1399 int r, fd;
1400
1401 fd = open("/dev/hpet", O_RDONLY);
1402 if (fd < 0)
1403 return -1;
1404
1405 /* Set frequency */
1406 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1407 if (r < 0) {
1408 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1409 "error, but for better emulation accuracy type:\n"
1410 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1411 goto fail;
1412 }
1413
1414 /* Check capabilities */
1415 r = ioctl(fd, HPET_INFO, &info);
1416 if (r < 0)
1417 goto fail;
1418
1419 /* Enable periodic mode */
1420 r = ioctl(fd, HPET_EPI, 0);
1421 if (info.hi_flags && (r < 0))
1422 goto fail;
1423
1424 /* Enable interrupt */
1425 r = ioctl(fd, HPET_IE_ON, 0);
1426 if (r < 0)
1427 goto fail;
1428
1429 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001430 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001431
1432 return 0;
1433fail:
1434 close(fd);
1435 return -1;
1436}
1437
1438static void hpet_stop_timer(struct qemu_alarm_timer *t)
1439{
pbrookfcdc2122007-08-23 20:22:22 +00001440 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001441
1442 close(fd);
1443}
1444
thsc8994012007-08-19 21:56:03 +00001445static int rtc_start_timer(struct qemu_alarm_timer *t)
1446{
1447 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001448 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001449
balrogaeb30be2007-07-02 15:03:13 +00001450 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001451 if (rtc_fd < 0)
1452 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001453 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1454 if (current_rtc_freq != RTC_FREQ &&
1455 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001456 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1457 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1458 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1459 goto fail;
1460 }
1461 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1462 fail:
1463 close(rtc_fd);
1464 return -1;
1465 }
thsc8994012007-08-19 21:56:03 +00001466
1467 enable_sigio_timer(rtc_fd);
1468
pbrookfcdc2122007-08-23 20:22:22 +00001469 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001470
bellardfd872592004-05-12 19:11:15 +00001471 return 0;
1472}
1473
thsc8994012007-08-19 21:56:03 +00001474static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001475{
pbrookfcdc2122007-08-23 20:22:22 +00001476 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001477
1478 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001479}
1480
thsefe75412007-08-24 01:36:32 +00001481static int dynticks_start_timer(struct qemu_alarm_timer *t)
1482{
1483 struct sigevent ev;
1484 timer_t host_timer;
1485 struct sigaction act;
1486
1487 sigfillset(&act.sa_mask);
1488 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001489 act.sa_handler = host_alarm_handler;
1490
1491 sigaction(SIGALRM, &act, NULL);
1492
1493 ev.sigev_value.sival_int = 0;
1494 ev.sigev_notify = SIGEV_SIGNAL;
1495 ev.sigev_signo = SIGALRM;
1496
1497 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1498 perror("timer_create");
1499
1500 /* disable dynticks */
1501 fprintf(stderr, "Dynamic Ticks disabled\n");
1502
1503 return -1;
1504 }
1505
1506 t->priv = (void *)host_timer;
1507
1508 return 0;
1509}
1510
1511static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1512{
1513 timer_t host_timer = (timer_t)t->priv;
1514
1515 timer_delete(host_timer);
1516}
1517
1518static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1519{
1520 timer_t host_timer = (timer_t)t->priv;
1521 struct itimerspec timeout;
1522 int64_t nearest_delta_us = INT64_MAX;
1523 int64_t current_us;
1524
1525 if (!active_timers[QEMU_TIMER_REALTIME] &&
1526 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001527 return;
thsefe75412007-08-24 01:36:32 +00001528
pbrook2e70f6e2008-06-29 01:03:05 +00001529 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001530
1531 /* check whether a timer is already running */
1532 if (timer_gettime(host_timer, &timeout)) {
1533 perror("gettime");
1534 fprintf(stderr, "Internal timer error: aborting\n");
1535 exit(1);
1536 }
1537 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1538 if (current_us && current_us <= nearest_delta_us)
1539 return;
1540
1541 timeout.it_interval.tv_sec = 0;
1542 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1543 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1544 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1545 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1546 perror("settime");
1547 fprintf(stderr, "Internal timer error: aborting\n");
1548 exit(1);
1549 }
1550}
1551
ths70744b32007-08-26 17:31:30 +00001552#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001553
thsc8994012007-08-19 21:56:03 +00001554static int unix_start_timer(struct qemu_alarm_timer *t)
1555{
1556 struct sigaction act;
1557 struct itimerval itv;
1558 int err;
1559
1560 /* timer signal */
1561 sigfillset(&act.sa_mask);
1562 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001563 act.sa_handler = host_alarm_handler;
1564
1565 sigaction(SIGALRM, &act, NULL);
1566
1567 itv.it_interval.tv_sec = 0;
1568 /* for i386 kernel 2.6 to get 1 ms */
1569 itv.it_interval.tv_usec = 999;
1570 itv.it_value.tv_sec = 0;
1571 itv.it_value.tv_usec = 10 * 1000;
1572
1573 err = setitimer(ITIMER_REAL, &itv, NULL);
1574 if (err)
1575 return -1;
1576
1577 return 0;
1578}
1579
1580static void unix_stop_timer(struct qemu_alarm_timer *t)
1581{
1582 struct itimerval itv;
1583
1584 memset(&itv, 0, sizeof(itv));
1585 setitimer(ITIMER_REAL, &itv, NULL);
1586}
1587
bellard829309c2004-05-20 13:20:12 +00001588#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001589
thsc8994012007-08-19 21:56:03 +00001590#ifdef _WIN32
1591
1592static int win32_start_timer(struct qemu_alarm_timer *t)
1593{
1594 TIMECAPS tc;
1595 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001596 UINT flags;
thsc8994012007-08-19 21:56:03 +00001597
1598 data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1599 if (!data->host_alarm) {
1600 perror("Failed CreateEvent");
thsc396a7f2007-08-20 15:42:22 +00001601 return -1;
thsc8994012007-08-19 21:56:03 +00001602 }
1603
1604 memset(&tc, 0, sizeof(tc));
1605 timeGetDevCaps(&tc, sizeof(tc));
1606
1607 if (data->period < tc.wPeriodMin)
1608 data->period = tc.wPeriodMin;
1609
1610 timeBeginPeriod(data->period);
1611
thsefe75412007-08-24 01:36:32 +00001612 flags = TIME_CALLBACK_FUNCTION;
1613 if (alarm_has_dynticks(t))
1614 flags |= TIME_ONESHOT;
1615 else
1616 flags |= TIME_PERIODIC;
1617
thsc8994012007-08-19 21:56:03 +00001618 data->timerId = timeSetEvent(1, // interval (ms)
1619 data->period, // resolution
1620 host_alarm_handler, // function
1621 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001622 flags);
thsc8994012007-08-19 21:56:03 +00001623
1624 if (!data->timerId) {
1625 perror("Failed to initialize win32 alarm timer");
1626
1627 timeEndPeriod(data->period);
1628 CloseHandle(data->host_alarm);
1629 return -1;
1630 }
1631
1632 qemu_add_wait_object(data->host_alarm, NULL, NULL);
1633
1634 return 0;
1635}
1636
1637static void win32_stop_timer(struct qemu_alarm_timer *t)
1638{
1639 struct qemu_alarm_win32 *data = t->priv;
1640
1641 timeKillEvent(data->timerId);
1642 timeEndPeriod(data->period);
1643
1644 CloseHandle(data->host_alarm);
1645}
1646
thsefe75412007-08-24 01:36:32 +00001647static void win32_rearm_timer(struct qemu_alarm_timer *t)
1648{
1649 struct qemu_alarm_win32 *data = t->priv;
1650 uint64_t nearest_delta_us;
1651
1652 if (!active_timers[QEMU_TIMER_REALTIME] &&
1653 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001654 return;
thsefe75412007-08-24 01:36:32 +00001655
pbrook2e70f6e2008-06-29 01:03:05 +00001656 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001657 nearest_delta_us /= 1000;
1658
1659 timeKillEvent(data->timerId);
1660
1661 data->timerId = timeSetEvent(1,
1662 data->period,
1663 host_alarm_handler,
1664 (DWORD)t,
1665 TIME_ONESHOT | TIME_PERIODIC);
1666
1667 if (!data->timerId) {
1668 perror("Failed to re-arm win32 alarm timer");
1669
1670 timeEndPeriod(data->period);
1671 CloseHandle(data->host_alarm);
1672 exit(1);
1673 }
1674}
1675
thsc8994012007-08-19 21:56:03 +00001676#endif /* _WIN32 */
1677
bellard1dce7c32006-07-13 23:20:22 +00001678static void init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001679{
thsc8994012007-08-19 21:56:03 +00001680 struct qemu_alarm_timer *t;
1681 int i, err = -1;
bellard06d9f2f2006-05-01 13:23:04 +00001682
thsc8994012007-08-19 21:56:03 +00001683 for (i = 0; alarm_timers[i].name; i++) {
1684 t = &alarm_timers[i];
1685
thsc8994012007-08-19 21:56:03 +00001686 err = t->start(t);
1687 if (!err)
1688 break;
bellard67b915a2004-03-31 23:37:16 +00001689 }
bellardfd872592004-05-12 19:11:15 +00001690
thsc8994012007-08-19 21:56:03 +00001691 if (err) {
1692 fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1693 fprintf(stderr, "Terminating\n");
1694 exit(1);
bellard67b915a2004-03-31 23:37:16 +00001695 }
thsc8994012007-08-19 21:56:03 +00001696
1697 alarm_timer = t;
bellard8a7ddc32004-03-31 19:00:16 +00001698}
1699
pbrook9596ebb2007-11-18 01:44:38 +00001700static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001701{
thsc8994012007-08-19 21:56:03 +00001702 alarm_timer->stop(alarm_timer);
1703 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001704}
1705
bellardc4b1fcc2004-03-14 21:44:30 +00001706/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001707/* host time/date access */
1708void qemu_get_timedate(struct tm *tm, int offset)
1709{
1710 time_t ti;
1711 struct tm *ret;
1712
1713 time(&ti);
1714 ti += offset;
1715 if (rtc_date_offset == -1) {
1716 if (rtc_utc)
1717 ret = gmtime(&ti);
1718 else
1719 ret = localtime(&ti);
1720 } else {
1721 ti -= rtc_date_offset;
1722 ret = gmtime(&ti);
1723 }
1724
1725 memcpy(tm, ret, sizeof(struct tm));
1726}
1727
1728int qemu_timedate_diff(struct tm *tm)
1729{
1730 time_t seconds;
1731
1732 if (rtc_date_offset == -1)
1733 if (rtc_utc)
1734 seconds = mktimegm(tm);
1735 else
1736 seconds = mktime(tm);
1737 else
1738 seconds = mktimegm(tm) + rtc_date_offset;
1739
1740 return seconds - time(NULL);
1741}
1742
1743/***********************************************************/
bellard82c643f2004-07-14 17:28:13 +00001744/* character device */
bellardc45886d2004-01-05 00:02:06 +00001745
pbrooke5b0bc42007-01-27 23:46:43 +00001746static void qemu_chr_event(CharDriverState *s, int event)
1747{
1748 if (!s->chr_event)
1749 return;
1750 s->chr_event(s->handler_opaque, event);
1751}
1752
ths86e94de2007-01-05 22:01:59 +00001753static void qemu_chr_reset_bh(void *opaque)
1754{
1755 CharDriverState *s = opaque;
pbrooke5b0bc42007-01-27 23:46:43 +00001756 qemu_chr_event(s, CHR_EVENT_RESET);
ths86e94de2007-01-05 22:01:59 +00001757 qemu_bh_delete(s->bh);
1758 s->bh = NULL;
1759}
1760
1761void qemu_chr_reset(CharDriverState *s)
1762{
1763 if (s->bh == NULL) {
1764 s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1765 qemu_bh_schedule(s->bh);
1766 }
1767}
1768
bellard82c643f2004-07-14 17:28:13 +00001769int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
bellard67b915a2004-03-31 23:37:16 +00001770{
bellard82c643f2004-07-14 17:28:13 +00001771 return s->chr_write(s, buf, len);
bellard67b915a2004-03-31 23:37:16 +00001772}
1773
bellarde57a8c02005-11-10 23:58:52 +00001774int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00001775{
bellarde57a8c02005-11-10 23:58:52 +00001776 if (!s->chr_ioctl)
1777 return -ENOTSUP;
1778 return s->chr_ioctl(s, cmd, arg);
bellardf8d179e2005-11-08 22:30:36 +00001779}
1780
pbrooke5b0bc42007-01-27 23:46:43 +00001781int qemu_chr_can_read(CharDriverState *s)
1782{
1783 if (!s->chr_can_read)
1784 return 0;
1785 return s->chr_can_read(s->handler_opaque);
1786}
1787
1788void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1789{
1790 s->chr_read(s->handler_opaque, buf, len);
1791}
1792
balrogbd9bdce2007-11-25 00:55:06 +00001793void qemu_chr_accept_input(CharDriverState *s)
1794{
1795 if (s->chr_accept_input)
1796 s->chr_accept_input(s);
1797}
pbrooke5b0bc42007-01-27 23:46:43 +00001798
bellard82c643f2004-07-14 17:28:13 +00001799void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
bellard0824d6f2003-06-24 13:42:40 +00001800{
bellard82c643f2004-07-14 17:28:13 +00001801 char buf[4096];
1802 va_list ap;
1803 va_start(ap, fmt);
1804 vsnprintf(buf, sizeof(buf), fmt, ap);
thsffe8ab82007-12-16 03:16:05 +00001805 qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
bellard82c643f2004-07-14 17:28:13 +00001806 va_end(ap);
1807}
1808
bellard5905b2e2004-08-01 21:53:26 +00001809void qemu_chr_send_event(CharDriverState *s, int event)
1810{
1811 if (s->chr_send_event)
1812 s->chr_send_event(s, event);
1813}
1814
ths5fafdf22007-09-16 21:08:06 +00001815void qemu_chr_add_handlers(CharDriverState *s,
1816 IOCanRWHandler *fd_can_read,
pbrooke5b0bc42007-01-27 23:46:43 +00001817 IOReadHandler *fd_read,
1818 IOEventHandler *fd_event,
1819 void *opaque)
bellard82c643f2004-07-14 17:28:13 +00001820{
pbrooke5b0bc42007-01-27 23:46:43 +00001821 s->chr_can_read = fd_can_read;
1822 s->chr_read = fd_read;
1823 s->chr_event = fd_event;
1824 s->handler_opaque = opaque;
1825 if (s->chr_update_read_handler)
1826 s->chr_update_read_handler(s);
bellard82c643f2004-07-14 17:28:13 +00001827}
ths3b46e622007-09-17 08:09:54 +00001828
bellard82c643f2004-07-14 17:28:13 +00001829static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1830{
1831 return len;
1832}
1833
ths52f61fd2006-12-22 21:20:52 +00001834static CharDriverState *qemu_chr_open_null(void)
bellard82c643f2004-07-14 17:28:13 +00001835{
1836 CharDriverState *chr;
1837
1838 chr = qemu_mallocz(sizeof(CharDriverState));
1839 if (!chr)
1840 return NULL;
1841 chr->chr_write = null_chr_write;
bellard82c643f2004-07-14 17:28:13 +00001842 return chr;
1843}
1844
ths20d8a3e2007-02-18 17:04:49 +00001845/* MUX driver for serial I/O splitting */
1846static int term_timestamps;
1847static int64_t term_timestamps_start;
ths9c1de612007-02-21 17:25:30 +00001848#define MAX_MUX 4
balrogbd9bdce2007-11-25 00:55:06 +00001849#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
1850#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
ths20d8a3e2007-02-18 17:04:49 +00001851typedef struct {
1852 IOCanRWHandler *chr_can_read[MAX_MUX];
1853 IOReadHandler *chr_read[MAX_MUX];
1854 IOEventHandler *chr_event[MAX_MUX];
1855 void *ext_opaque[MAX_MUX];
1856 CharDriverState *drv;
balrogbd9bdce2007-11-25 00:55:06 +00001857 unsigned char buffer[MUX_BUFFER_SIZE];
1858 int prod;
1859 int cons;
ths20d8a3e2007-02-18 17:04:49 +00001860 int mux_cnt;
1861 int term_got_escape;
1862 int max_size;
1863} MuxDriver;
1864
1865
1866static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1867{
1868 MuxDriver *d = chr->opaque;
1869 int ret;
1870 if (!term_timestamps) {
1871 ret = d->drv->chr_write(d->drv, buf, len);
1872 } else {
1873 int i;
1874
1875 ret = 0;
1876 for(i = 0; i < len; i++) {
1877 ret += d->drv->chr_write(d->drv, buf+i, 1);
1878 if (buf[i] == '\n') {
1879 char buf1[64];
1880 int64_t ti;
1881 int secs;
1882
1883 ti = get_clock();
1884 if (term_timestamps_start == -1)
1885 term_timestamps_start = ti;
1886 ti -= term_timestamps_start;
1887 secs = ti / 1000000000;
1888 snprintf(buf1, sizeof(buf1),
1889 "[%02d:%02d:%02d.%03d] ",
1890 secs / 3600,
1891 (secs / 60) % 60,
1892 secs % 60,
1893 (int)((ti / 1000000) % 1000));
thsffe8ab82007-12-16 03:16:05 +00001894 d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
ths20d8a3e2007-02-18 17:04:49 +00001895 }
1896 }
1897 }
1898 return ret;
1899}
1900
1901static char *mux_help[] = {
1902 "% h print this help\n\r",
1903 "% x exit emulator\n\r",
1904 "% s save disk data back to file (if -snapshot)\n\r",
1905 "% t toggle console timestamps\n\r"
1906 "% b send break (magic sysrq)\n\r",
1907 "% c switch between console and monitor\n\r",
1908 "% % sends %\n\r",
1909 NULL
1910};
1911
1912static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1913static void mux_print_help(CharDriverState *chr)
1914{
1915 int i, j;
1916 char ebuf[15] = "Escape-Char";
1917 char cbuf[50] = "\n\r";
1918
1919 if (term_escape_char > 0 && term_escape_char < 26) {
blueswir1363a37d2008-08-21 17:58:08 +00001920 snprintf(cbuf, sizeof(cbuf), "\n\r");
1921 snprintf(ebuf, sizeof(ebuf), "C-%c", term_escape_char - 1 + 'a');
ths20d8a3e2007-02-18 17:04:49 +00001922 } else {
blueswir1363a37d2008-08-21 17:58:08 +00001923 snprintf(cbuf, sizeof(cbuf),
1924 "\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
1925 term_escape_char);
ths20d8a3e2007-02-18 17:04:49 +00001926 }
thsffe8ab82007-12-16 03:16:05 +00001927 chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
ths20d8a3e2007-02-18 17:04:49 +00001928 for (i = 0; mux_help[i] != NULL; i++) {
1929 for (j=0; mux_help[i][j] != '\0'; j++) {
1930 if (mux_help[i][j] == '%')
thsffe8ab82007-12-16 03:16:05 +00001931 chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
ths20d8a3e2007-02-18 17:04:49 +00001932 else
thsffe8ab82007-12-16 03:16:05 +00001933 chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
ths20d8a3e2007-02-18 17:04:49 +00001934 }
1935 }
1936}
1937
1938static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1939{
1940 if (d->term_got_escape) {
1941 d->term_got_escape = 0;
1942 if (ch == term_escape_char)
1943 goto send_char;
1944 switch(ch) {
1945 case '?':
1946 case 'h':
1947 mux_print_help(chr);
1948 break;
1949 case 'x':
1950 {
1951 char *term = "QEMU: Terminated\n\r";
thsffe8ab82007-12-16 03:16:05 +00001952 chr->chr_write(chr,(uint8_t *)term,strlen(term));
ths20d8a3e2007-02-18 17:04:49 +00001953 exit(0);
1954 break;
1955 }
1956 case 's':
1957 {
1958 int i;
thse4bcb142007-12-02 04:51:10 +00001959 for (i = 0; i < nb_drives; i++) {
1960 bdrv_commit(drives_table[i].bdrv);
ths20d8a3e2007-02-18 17:04:49 +00001961 }
1962 }
1963 break;
1964 case 'b':
balrog36ddb832007-05-18 17:46:59 +00001965 qemu_chr_event(chr, CHR_EVENT_BREAK);
ths20d8a3e2007-02-18 17:04:49 +00001966 break;
1967 case 'c':
1968 /* Switch to the next registered device */
1969 chr->focus++;
1970 if (chr->focus >= d->mux_cnt)
1971 chr->focus = 0;
1972 break;
1973 case 't':
1974 term_timestamps = !term_timestamps;
1975 term_timestamps_start = -1;
1976 break;
1977 }
1978 } else if (ch == term_escape_char) {
1979 d->term_got_escape = 1;
1980 } else {
1981 send_char:
1982 return 1;
1983 }
1984 return 0;
1985}
1986
balrogbd9bdce2007-11-25 00:55:06 +00001987static void mux_chr_accept_input(CharDriverState *chr)
1988{
1989 int m = chr->focus;
1990 MuxDriver *d = chr->opaque;
1991
1992 while (d->prod != d->cons &&
1993 d->chr_can_read[m] &&
1994 d->chr_can_read[m](d->ext_opaque[m])) {
1995 d->chr_read[m](d->ext_opaque[m],
1996 &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
1997 }
1998}
1999
ths20d8a3e2007-02-18 17:04:49 +00002000static int mux_chr_can_read(void *opaque)
2001{
2002 CharDriverState *chr = opaque;
2003 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00002004
2005 if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
2006 return 1;
ths20d8a3e2007-02-18 17:04:49 +00002007 if (d->chr_can_read[chr->focus])
balrogbd9bdce2007-11-25 00:55:06 +00002008 return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
ths20d8a3e2007-02-18 17:04:49 +00002009 return 0;
2010}
2011
2012static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
2013{
2014 CharDriverState *chr = opaque;
2015 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00002016 int m = chr->focus;
ths20d8a3e2007-02-18 17:04:49 +00002017 int i;
balrogbd9bdce2007-11-25 00:55:06 +00002018
2019 mux_chr_accept_input (opaque);
2020
ths20d8a3e2007-02-18 17:04:49 +00002021 for(i = 0; i < size; i++)
balrogbd9bdce2007-11-25 00:55:06 +00002022 if (mux_proc_byte(chr, d, buf[i])) {
2023 if (d->prod == d->cons &&
2024 d->chr_can_read[m] &&
2025 d->chr_can_read[m](d->ext_opaque[m]))
2026 d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
2027 else
2028 d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
2029 }
ths20d8a3e2007-02-18 17:04:49 +00002030}
2031
2032static void mux_chr_event(void *opaque, int event)
2033{
2034 CharDriverState *chr = opaque;
2035 MuxDriver *d = chr->opaque;
2036 int i;
2037
2038 /* Send the event to all registered listeners */
2039 for (i = 0; i < d->mux_cnt; i++)
2040 if (d->chr_event[i])
2041 d->chr_event[i](d->ext_opaque[i], event);
2042}
2043
2044static void mux_chr_update_read_handler(CharDriverState *chr)
2045{
2046 MuxDriver *d = chr->opaque;
2047
2048 if (d->mux_cnt >= MAX_MUX) {
2049 fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
2050 return;
2051 }
2052 d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
2053 d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
2054 d->chr_read[d->mux_cnt] = chr->chr_read;
2055 d->chr_event[d->mux_cnt] = chr->chr_event;
2056 /* Fix up the real driver with mux routines */
2057 if (d->mux_cnt == 0) {
2058 qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
2059 mux_chr_event, chr);
2060 }
2061 chr->focus = d->mux_cnt;
2062 d->mux_cnt++;
2063}
2064
pbrook9596ebb2007-11-18 01:44:38 +00002065static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
ths20d8a3e2007-02-18 17:04:49 +00002066{
2067 CharDriverState *chr;
2068 MuxDriver *d;
2069
2070 chr = qemu_mallocz(sizeof(CharDriverState));
2071 if (!chr)
2072 return NULL;
2073 d = qemu_mallocz(sizeof(MuxDriver));
2074 if (!d) {
2075 free(chr);
2076 return NULL;
2077 }
2078
2079 chr->opaque = d;
2080 d->drv = drv;
2081 chr->focus = -1;
2082 chr->chr_write = mux_chr_write;
2083 chr->chr_update_read_handler = mux_chr_update_read_handler;
balrogbd9bdce2007-11-25 00:55:06 +00002084 chr->chr_accept_input = mux_chr_accept_input;
ths20d8a3e2007-02-18 17:04:49 +00002085 return chr;
2086}
2087
2088
bellardfd1dff42006-02-01 21:29:26 +00002089#ifdef _WIN32
bellard82c643f2004-07-14 17:28:13 +00002090
bellardfd1dff42006-02-01 21:29:26 +00002091static void socket_cleanup(void)
2092{
2093 WSACleanup();
2094}
bellard82c643f2004-07-14 17:28:13 +00002095
bellardfd1dff42006-02-01 21:29:26 +00002096static int socket_init(void)
2097{
2098 WSADATA Data;
2099 int ret, err;
2100
2101 ret = WSAStartup(MAKEWORD(2,2), &Data);
2102 if (ret != 0) {
2103 err = WSAGetLastError();
2104 fprintf(stderr, "WSAStartup: %d\n", err);
2105 return -1;
2106 }
2107 atexit(socket_cleanup);
2108 return 0;
2109}
2110
2111static int send_all(int fd, const uint8_t *buf, int len1)
2112{
2113 int ret, len;
ths3b46e622007-09-17 08:09:54 +00002114
bellardfd1dff42006-02-01 21:29:26 +00002115 len = len1;
2116 while (len > 0) {
2117 ret = send(fd, buf, len, 0);
2118 if (ret < 0) {
2119 int errno;
2120 errno = WSAGetLastError();
2121 if (errno != WSAEWOULDBLOCK) {
2122 return -1;
2123 }
2124 } else if (ret == 0) {
2125 break;
2126 } else {
2127 buf += ret;
2128 len -= ret;
2129 }
2130 }
2131 return len1 - len;
2132}
2133
2134void socket_set_nonblock(int fd)
2135{
2136 unsigned long opt = 1;
2137 ioctlsocket(fd, FIONBIO, &opt);
2138}
2139
2140#else
2141
bellard1d969052004-09-18 19:34:39 +00002142static int unix_write(int fd, const uint8_t *buf, int len1)
2143{
2144 int ret, len;
2145
2146 len = len1;
2147 while (len > 0) {
2148 ret = write(fd, buf, len);
2149 if (ret < 0) {
2150 if (errno != EINTR && errno != EAGAIN)
2151 return -1;
2152 } else if (ret == 0) {
2153 break;
2154 } else {
2155 buf += ret;
2156 len -= ret;
2157 }
2158 }
2159 return len1 - len;
2160}
2161
bellardfd1dff42006-02-01 21:29:26 +00002162static inline int send_all(int fd, const uint8_t *buf, int len1)
2163{
2164 return unix_write(fd, buf, len1);
2165}
2166
2167void socket_set_nonblock(int fd)
2168{
thsfd58ff92008-07-18 16:34:43 +00002169 int f;
2170 f = fcntl(fd, F_GETFL);
2171 fcntl(fd, F_SETFL, f | O_NONBLOCK);
bellardfd1dff42006-02-01 21:29:26 +00002172}
2173#endif /* !_WIN32 */
2174
2175#ifndef _WIN32
2176
2177typedef struct {
2178 int fd_in, fd_out;
bellardfd1dff42006-02-01 21:29:26 +00002179 int max_size;
2180} FDCharDriver;
2181
ths20d8a3e2007-02-18 17:04:49 +00002182#define STDIO_MAX_CLIENTS 1
2183static int stdio_nb_clients = 0;
bellardfd1dff42006-02-01 21:29:26 +00002184
bellard82c643f2004-07-14 17:28:13 +00002185static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2186{
2187 FDCharDriver *s = chr->opaque;
bellard1d969052004-09-18 19:34:39 +00002188 return unix_write(s->fd_out, buf, len);
bellard82c643f2004-07-14 17:28:13 +00002189}
2190
bellard7c9d8e02005-11-15 22:16:05 +00002191static int fd_chr_read_poll(void *opaque)
2192{
2193 CharDriverState *chr = opaque;
2194 FDCharDriver *s = chr->opaque;
2195
pbrooke5b0bc42007-01-27 23:46:43 +00002196 s->max_size = qemu_chr_can_read(chr);
bellard7c9d8e02005-11-15 22:16:05 +00002197 return s->max_size;
2198}
2199
2200static void fd_chr_read(void *opaque)
2201{
2202 CharDriverState *chr = opaque;
2203 FDCharDriver *s = chr->opaque;
2204 int size, len;
2205 uint8_t buf[1024];
ths3b46e622007-09-17 08:09:54 +00002206
bellard7c9d8e02005-11-15 22:16:05 +00002207 len = sizeof(buf);
2208 if (len > s->max_size)
2209 len = s->max_size;
2210 if (len == 0)
2211 return;
2212 size = read(s->fd_in, buf, len);
pbrook188157f2006-11-01 01:44:16 +00002213 if (size == 0) {
2214 /* FD has been closed. Remove it from the active list. */
2215 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2216 return;
2217 }
bellard7c9d8e02005-11-15 22:16:05 +00002218 if (size > 0) {
pbrooke5b0bc42007-01-27 23:46:43 +00002219 qemu_chr_read(chr, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00002220 }
2221}
2222
pbrooke5b0bc42007-01-27 23:46:43 +00002223static void fd_chr_update_read_handler(CharDriverState *chr)
bellard82c643f2004-07-14 17:28:13 +00002224{
2225 FDCharDriver *s = chr->opaque;
2226
bellardf8d179e2005-11-08 22:30:36 +00002227 if (s->fd_in >= 0) {
2228 if (nographic && s->fd_in == 0) {
bellardf8d179e2005-11-08 22:30:36 +00002229 } else {
ths5fafdf22007-09-16 21:08:06 +00002230 qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
bellard7c9d8e02005-11-15 22:16:05 +00002231 fd_chr_read, NULL, chr);
bellardf8d179e2005-11-08 22:30:36 +00002232 }
bellard0824d6f2003-06-24 13:42:40 +00002233 }
2234}
2235
balroga11d0702008-01-19 13:00:43 +00002236static void fd_chr_close(struct CharDriverState *chr)
2237{
2238 FDCharDriver *s = chr->opaque;
2239
2240 if (s->fd_in >= 0) {
2241 if (nographic && s->fd_in == 0) {
2242 } else {
2243 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2244 }
2245 }
2246
2247 qemu_free(s);
2248}
2249
bellard82c643f2004-07-14 17:28:13 +00002250/* open a character device to a unix fd */
ths52f61fd2006-12-22 21:20:52 +00002251static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
bellard82c643f2004-07-14 17:28:13 +00002252{
2253 CharDriverState *chr;
2254 FDCharDriver *s;
2255
2256 chr = qemu_mallocz(sizeof(CharDriverState));
2257 if (!chr)
2258 return NULL;
2259 s = qemu_mallocz(sizeof(FDCharDriver));
2260 if (!s) {
2261 free(chr);
2262 return NULL;
2263 }
2264 s->fd_in = fd_in;
2265 s->fd_out = fd_out;
2266 chr->opaque = s;
2267 chr->chr_write = fd_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00002268 chr->chr_update_read_handler = fd_chr_update_read_handler;
balroga11d0702008-01-19 13:00:43 +00002269 chr->chr_close = fd_chr_close;
ths86e94de2007-01-05 22:01:59 +00002270
2271 qemu_chr_reset(chr);
2272
bellard82c643f2004-07-14 17:28:13 +00002273 return chr;
2274}
2275
ths52f61fd2006-12-22 21:20:52 +00002276static CharDriverState *qemu_chr_open_file_out(const char *file_out)
bellardf8d179e2005-11-08 22:30:36 +00002277{
2278 int fd_out;
2279
balrogaeb30be2007-07-02 15:03:13 +00002280 TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
bellardf8d179e2005-11-08 22:30:36 +00002281 if (fd_out < 0)
2282 return NULL;
2283 return qemu_chr_open_fd(-1, fd_out);
2284}
2285
ths52f61fd2006-12-22 21:20:52 +00002286static CharDriverState *qemu_chr_open_pipe(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002287{
thsc26c1c42006-12-22 19:25:31 +00002288 int fd_in, fd_out;
2289 char filename_in[256], filename_out[256];
bellardf8d179e2005-11-08 22:30:36 +00002290
thsc26c1c42006-12-22 19:25:31 +00002291 snprintf(filename_in, 256, "%s.in", filename);
2292 snprintf(filename_out, 256, "%s.out", filename);
balrogaeb30be2007-07-02 15:03:13 +00002293 TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2294 TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002295 if (fd_in < 0 || fd_out < 0) {
2296 if (fd_in >= 0)
2297 close(fd_in);
2298 if (fd_out >= 0)
2299 close(fd_out);
balrogaeb30be2007-07-02 15:03:13 +00002300 TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002301 if (fd_in < 0)
2302 return NULL;
2303 }
2304 return qemu_chr_open_fd(fd_in, fd_out);
bellardf8d179e2005-11-08 22:30:36 +00002305}
2306
2307
bellard82c643f2004-07-14 17:28:13 +00002308/* for STDIO, we handle the case where several clients use it
2309 (nographic mode) */
2310
bellardaa0bc6b2005-09-03 15:28:58 +00002311#define TERM_FIFO_MAX_SIZE 1
2312
bellardaa0bc6b2005-09-03 15:28:58 +00002313static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
bellard1dce7c32006-07-13 23:20:22 +00002314static int term_fifo_size;
bellard82c643f2004-07-14 17:28:13 +00002315
bellard7c9d8e02005-11-15 22:16:05 +00002316static int stdio_read_poll(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002317{
ths20d8a3e2007-02-18 17:04:49 +00002318 CharDriverState *chr = opaque;
bellardaa0bc6b2005-09-03 15:28:58 +00002319
ths20d8a3e2007-02-18 17:04:49 +00002320 /* try to flush the queue if needed */
2321 if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2322 qemu_chr_read(chr, term_fifo, 1);
2323 term_fifo_size = 0;
bellardaa0bc6b2005-09-03 15:28:58 +00002324 }
ths20d8a3e2007-02-18 17:04:49 +00002325 /* see if we can absorb more chars */
2326 if (term_fifo_size == 0)
2327 return 1;
2328 else
2329 return 0;
bellard82c643f2004-07-14 17:28:13 +00002330}
2331
bellard7c9d8e02005-11-15 22:16:05 +00002332static void stdio_read(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002333{
bellard7c9d8e02005-11-15 22:16:05 +00002334 int size;
2335 uint8_t buf[1];
ths20d8a3e2007-02-18 17:04:49 +00002336 CharDriverState *chr = opaque;
2337
bellard7c9d8e02005-11-15 22:16:05 +00002338 size = read(0, buf, 1);
pbrook519945d2006-09-10 14:39:54 +00002339 if (size == 0) {
2340 /* stdin has been closed. Remove it from the active list. */
2341 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2342 return;
2343 }
ths20d8a3e2007-02-18 17:04:49 +00002344 if (size > 0) {
2345 if (qemu_chr_can_read(chr) > 0) {
2346 qemu_chr_read(chr, buf, 1);
2347 } else if (term_fifo_size == 0) {
2348 term_fifo[term_fifo_size++] = buf[0];
bellard1dce7c32006-07-13 23:20:22 +00002349 }
bellard1dce7c32006-07-13 23:20:22 +00002350 }
2351}
2352
bellard8d11df92004-08-24 21:13:40 +00002353/* init terminal so that we can grab keys */
2354static struct termios oldtty;
2355static int old_fd0_flags;
balroga11d0702008-01-19 13:00:43 +00002356static int term_atexit_done;
bellard8d11df92004-08-24 21:13:40 +00002357
2358static void term_exit(void)
2359{
2360 tcsetattr (0, TCSANOW, &oldtty);
2361 fcntl(0, F_SETFL, old_fd0_flags);
2362}
2363
2364static void term_init(void)
2365{
2366 struct termios tty;
2367
2368 tcgetattr (0, &tty);
2369 oldtty = tty;
2370 old_fd0_flags = fcntl(0, F_GETFL);
2371
2372 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2373 |INLCR|IGNCR|ICRNL|IXON);
2374 tty.c_oflag |= OPOST;
2375 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2376 /* if graphical mode, we allow Ctrl-C handling */
2377 if (nographic)
2378 tty.c_lflag &= ~ISIG;
2379 tty.c_cflag &= ~(CSIZE|PARENB);
2380 tty.c_cflag |= CS8;
2381 tty.c_cc[VMIN] = 1;
2382 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +00002383
bellard8d11df92004-08-24 21:13:40 +00002384 tcsetattr (0, TCSANOW, &tty);
2385
balroga11d0702008-01-19 13:00:43 +00002386 if (!term_atexit_done++)
2387 atexit(term_exit);
bellard8d11df92004-08-24 21:13:40 +00002388
2389 fcntl(0, F_SETFL, O_NONBLOCK);
2390}
2391
balroga11d0702008-01-19 13:00:43 +00002392static void qemu_chr_close_stdio(struct CharDriverState *chr)
2393{
2394 term_exit();
2395 stdio_nb_clients--;
2396 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2397 fd_chr_close(chr);
2398}
2399
ths52f61fd2006-12-22 21:20:52 +00002400static CharDriverState *qemu_chr_open_stdio(void)
bellard82c643f2004-07-14 17:28:13 +00002401{
2402 CharDriverState *chr;
2403
ths20d8a3e2007-02-18 17:04:49 +00002404 if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2405 return NULL;
2406 chr = qemu_chr_open_fd(0, 1);
balroga11d0702008-01-19 13:00:43 +00002407 chr->chr_close = qemu_chr_close_stdio;
ths20d8a3e2007-02-18 17:04:49 +00002408 qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2409 stdio_nb_clients++;
2410 term_init();
2411
bellard82c643f2004-07-14 17:28:13 +00002412 return chr;
2413}
2414
aurel3264b7b732008-05-05 10:05:31 +00002415#ifdef __sun__
2416/* Once Solaris has openpty(), this is going to be removed. */
2417int openpty(int *amaster, int *aslave, char *name,
2418 struct termios *termp, struct winsize *winp)
2419{
2420 const char *slave;
2421 int mfd = -1, sfd = -1;
2422
2423 *amaster = *aslave = -1;
2424
2425 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
2426 if (mfd < 0)
2427 goto err;
2428
2429 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
2430 goto err;
2431
2432 if ((slave = ptsname(mfd)) == NULL)
2433 goto err;
2434
2435 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
2436 goto err;
2437
2438 if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
2439 (termp != NULL && tcgetattr(sfd, termp) < 0))
2440 goto err;
2441
2442 if (amaster)
2443 *amaster = mfd;
2444 if (aslave)
2445 *aslave = sfd;
2446 if (winp)
2447 ioctl(sfd, TIOCSWINSZ, winp);
2448
2449 return 0;
2450
2451err:
2452 if (sfd != -1)
2453 close(sfd);
2454 close(mfd);
2455 return -1;
2456}
2457
2458void cfmakeraw (struct termios *termios_p)
2459{
2460 termios_p->c_iflag &=
2461 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2462 termios_p->c_oflag &= ~OPOST;
2463 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2464 termios_p->c_cflag &= ~(CSIZE|PARENB);
2465 termios_p->c_cflag |= CS8;
2466
2467 termios_p->c_cc[VMIN] = 0;
2468 termios_p->c_cc[VTIME] = 0;
2469}
2470#endif
2471
blueswir19892fbf2008-08-24 10:34:20 +00002472#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
2473 || defined(__NetBSD__) || defined(__OpenBSD__)
aliguori279e6942008-07-28 18:55:32 +00002474
2475typedef struct {
2476 int fd;
2477 int connected;
2478 int polling;
2479 int read_bytes;
2480 QEMUTimer *timer;
2481} PtyCharDriver;
2482
2483static void pty_chr_update_read_handler(CharDriverState *chr);
2484static void pty_chr_state(CharDriverState *chr, int connected);
2485
2486static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2487{
2488 PtyCharDriver *s = chr->opaque;
2489
2490 if (!s->connected) {
2491 /* guest sends data, check for (re-)connect */
2492 pty_chr_update_read_handler(chr);
2493 return 0;
2494 }
2495 return unix_write(s->fd, buf, len);
2496}
2497
2498static int pty_chr_read_poll(void *opaque)
2499{
2500 CharDriverState *chr = opaque;
2501 PtyCharDriver *s = chr->opaque;
2502
2503 s->read_bytes = qemu_chr_can_read(chr);
2504 return s->read_bytes;
2505}
2506
2507static void pty_chr_read(void *opaque)
2508{
2509 CharDriverState *chr = opaque;
2510 PtyCharDriver *s = chr->opaque;
2511 int size, len;
2512 uint8_t buf[1024];
2513
2514 len = sizeof(buf);
2515 if (len > s->read_bytes)
2516 len = s->read_bytes;
2517 if (len == 0)
2518 return;
2519 size = read(s->fd, buf, len);
2520 if ((size == -1 && errno == EIO) ||
2521 (size == 0)) {
2522 pty_chr_state(chr, 0);
2523 return;
2524 }
2525 if (size > 0) {
2526 pty_chr_state(chr, 1);
2527 qemu_chr_read(chr, buf, size);
2528 }
2529}
2530
2531static void pty_chr_update_read_handler(CharDriverState *chr)
2532{
2533 PtyCharDriver *s = chr->opaque;
2534
2535 qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
2536 pty_chr_read, NULL, chr);
2537 s->polling = 1;
2538 /*
2539 * Short timeout here: just need wait long enougth that qemu makes
2540 * it through the poll loop once. When reconnected we want a
2541 * short timeout so we notice it almost instantly. Otherwise
2542 * read() gives us -EIO instantly, making pty_chr_state() reset the
2543 * timeout to the normal (much longer) poll interval before the
2544 * timer triggers.
2545 */
2546 qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
2547}
2548
2549static void pty_chr_state(CharDriverState *chr, int connected)
2550{
2551 PtyCharDriver *s = chr->opaque;
2552
2553 if (!connected) {
2554 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
2555 s->connected = 0;
2556 s->polling = 0;
2557 /* (re-)connect poll interval for idle guests: once per second.
2558 * We check more frequently in case the guests sends data to
2559 * the virtual device linked to our pty. */
2560 qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
2561 } else {
2562 if (!s->connected)
2563 qemu_chr_reset(chr);
2564 s->connected = 1;
2565 }
2566}
2567
blueswir18fcd3692008-08-17 20:26:25 +00002568static void pty_chr_timer(void *opaque)
aliguori279e6942008-07-28 18:55:32 +00002569{
2570 struct CharDriverState *chr = opaque;
2571 PtyCharDriver *s = chr->opaque;
2572
2573 if (s->connected)
2574 return;
2575 if (s->polling) {
2576 /* If we arrive here without polling being cleared due
2577 * read returning -EIO, then we are (re-)connected */
2578 pty_chr_state(chr, 1);
2579 return;
2580 }
2581
2582 /* Next poll ... */
2583 pty_chr_update_read_handler(chr);
2584}
2585
2586static void pty_chr_close(struct CharDriverState *chr)
2587{
2588 PtyCharDriver *s = chr->opaque;
2589
2590 qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
2591 close(s->fd);
2592 qemu_free(s);
2593}
2594
ths52f61fd2006-12-22 21:20:52 +00002595static CharDriverState *qemu_chr_open_pty(void)
bellard82c643f2004-07-14 17:28:13 +00002596{
aliguori279e6942008-07-28 18:55:32 +00002597 CharDriverState *chr;
2598 PtyCharDriver *s;
bellard91fc2112005-12-18 19:09:37 +00002599 struct termios tty;
aliguori279e6942008-07-28 18:55:32 +00002600 int slave_fd;
blueswir19892fbf2008-08-24 10:34:20 +00002601#if defined(__OpenBSD__)
2602 char pty_name[PATH_MAX];
2603#define q_ptsname(x) pty_name
2604#else
2605 char *pty_name = NULL;
2606#define q_ptsname(x) ptsname(x)
2607#endif
ths3b46e622007-09-17 08:09:54 +00002608
aliguori279e6942008-07-28 18:55:32 +00002609 chr = qemu_mallocz(sizeof(CharDriverState));
2610 if (!chr)
2611 return NULL;
2612 s = qemu_mallocz(sizeof(PtyCharDriver));
2613 if (!s) {
2614 qemu_free(chr);
2615 return NULL;
2616 }
2617
blueswir19892fbf2008-08-24 10:34:20 +00002618 if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
bellard82c643f2004-07-14 17:28:13 +00002619 return NULL;
2620 }
ths3b46e622007-09-17 08:09:54 +00002621
aurel3264b7b732008-05-05 10:05:31 +00002622 /* Set raw attributes on the pty. */
2623 cfmakeraw(&tty);
2624 tcsetattr(slave_fd, TCSAFLUSH, &tty);
aliguori279e6942008-07-28 18:55:32 +00002625 close(slave_fd);
bellard91fc2112005-12-18 19:09:37 +00002626
blueswir19892fbf2008-08-24 10:34:20 +00002627 fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
aliguori279e6942008-07-28 18:55:32 +00002628
2629 chr->opaque = s;
2630 chr->chr_write = pty_chr_write;
2631 chr->chr_update_read_handler = pty_chr_update_read_handler;
2632 chr->chr_close = pty_chr_close;
2633
2634 s->timer = qemu_new_timer(rt_clock, pty_chr_timer, chr);
2635
2636 return chr;
bellard82c643f2004-07-14 17:28:13 +00002637}
bellardf8d179e2005-11-08 22:30:36 +00002638
ths5fafdf22007-09-16 21:08:06 +00002639static void tty_serial_init(int fd, int speed,
bellardf8d179e2005-11-08 22:30:36 +00002640 int parity, int data_bits, int stop_bits)
2641{
2642 struct termios tty;
2643 speed_t spd;
2644
bellarde57a8c02005-11-10 23:58:52 +00002645#if 0
ths5fafdf22007-09-16 21:08:06 +00002646 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
bellarde57a8c02005-11-10 23:58:52 +00002647 speed, parity, data_bits, stop_bits);
2648#endif
2649 tcgetattr (fd, &tty);
bellardf8d179e2005-11-08 22:30:36 +00002650
balroga7954212008-01-14 03:41:02 +00002651#define MARGIN 1.1
2652 if (speed <= 50 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002653 spd = B50;
balroga7954212008-01-14 03:41:02 +00002654 else if (speed <= 75 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002655 spd = B75;
balroga7954212008-01-14 03:41:02 +00002656 else if (speed <= 300 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002657 spd = B300;
balroga7954212008-01-14 03:41:02 +00002658 else if (speed <= 600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002659 spd = B600;
balroga7954212008-01-14 03:41:02 +00002660 else if (speed <= 1200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002661 spd = B1200;
balroga7954212008-01-14 03:41:02 +00002662 else if (speed <= 2400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002663 spd = B2400;
balroga7954212008-01-14 03:41:02 +00002664 else if (speed <= 4800 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002665 spd = B4800;
balroga7954212008-01-14 03:41:02 +00002666 else if (speed <= 9600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002667 spd = B9600;
balroga7954212008-01-14 03:41:02 +00002668 else if (speed <= 19200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002669 spd = B19200;
balroga7954212008-01-14 03:41:02 +00002670 else if (speed <= 38400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002671 spd = B38400;
balroga7954212008-01-14 03:41:02 +00002672 else if (speed <= 57600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002673 spd = B57600;
balroga7954212008-01-14 03:41:02 +00002674 else if (speed <= 115200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002675 spd = B115200;
balroga7954212008-01-14 03:41:02 +00002676 else
2677 spd = B115200;
bellardf8d179e2005-11-08 22:30:36 +00002678
2679 cfsetispeed(&tty, spd);
2680 cfsetospeed(&tty, spd);
2681
2682 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2683 |INLCR|IGNCR|ICRNL|IXON);
2684 tty.c_oflag |= OPOST;
2685 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
bellard094eed62006-09-09 11:10:18 +00002686 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
bellardf8d179e2005-11-08 22:30:36 +00002687 switch(data_bits) {
2688 default:
2689 case 8:
2690 tty.c_cflag |= CS8;
2691 break;
2692 case 7:
2693 tty.c_cflag |= CS7;
2694 break;
2695 case 6:
2696 tty.c_cflag |= CS6;
2697 break;
2698 case 5:
2699 tty.c_cflag |= CS5;
2700 break;
2701 }
2702 switch(parity) {
2703 default:
2704 case 'N':
2705 break;
2706 case 'E':
2707 tty.c_cflag |= PARENB;
2708 break;
2709 case 'O':
2710 tty.c_cflag |= PARENB | PARODD;
2711 break;
2712 }
bellard094eed62006-09-09 11:10:18 +00002713 if (stop_bits == 2)
2714 tty.c_cflag |= CSTOPB;
ths3b46e622007-09-17 08:09:54 +00002715
bellardf8d179e2005-11-08 22:30:36 +00002716 tcsetattr (fd, TCSANOW, &tty);
2717}
2718
bellarde57a8c02005-11-10 23:58:52 +00002719static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00002720{
2721 FDCharDriver *s = chr->opaque;
ths3b46e622007-09-17 08:09:54 +00002722
bellarde57a8c02005-11-10 23:58:52 +00002723 switch(cmd) {
2724 case CHR_IOCTL_SERIAL_SET_PARAMS:
2725 {
2726 QEMUSerialSetParams *ssp = arg;
ths5fafdf22007-09-16 21:08:06 +00002727 tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
bellarde57a8c02005-11-10 23:58:52 +00002728 ssp->data_bits, ssp->stop_bits);
2729 }
2730 break;
2731 case CHR_IOCTL_SERIAL_SET_BREAK:
2732 {
2733 int enable = *(int *)arg;
2734 if (enable)
2735 tcsendbreak(s->fd_in, 1);
2736 }
2737 break;
aliguori81174da2008-08-11 14:17:04 +00002738 case CHR_IOCTL_SERIAL_GET_TIOCM:
2739 {
2740 int sarg = 0;
2741 int *targ = (int *)arg;
2742 ioctl(s->fd_in, TIOCMGET, &sarg);
2743 *targ = 0;
2744 if (sarg | TIOCM_CTS)
2745 *targ |= CHR_TIOCM_CTS;
2746 if (sarg | TIOCM_CAR)
2747 *targ |= CHR_TIOCM_CAR;
2748 if (sarg | TIOCM_DSR)
2749 *targ |= CHR_TIOCM_DSR;
2750 if (sarg | TIOCM_RI)
2751 *targ |= CHR_TIOCM_RI;
2752 if (sarg | TIOCM_DTR)
2753 *targ |= CHR_TIOCM_DTR;
2754 if (sarg | TIOCM_RTS)
2755 *targ |= CHR_TIOCM_RTS;
2756 }
2757 break;
2758 case CHR_IOCTL_SERIAL_SET_TIOCM:
2759 {
2760 int sarg = *(int *)arg;
2761 int targ = 0;
2762 if (sarg | CHR_TIOCM_DTR)
2763 targ |= TIOCM_DTR;
2764 if (sarg | CHR_TIOCM_RTS)
2765 targ |= TIOCM_RTS;
2766 ioctl(s->fd_in, TIOCMSET, &targ);
2767 }
2768 break;
bellarde57a8c02005-11-10 23:58:52 +00002769 default:
2770 return -ENOTSUP;
2771 }
2772 return 0;
bellardf8d179e2005-11-08 22:30:36 +00002773}
2774
ths52f61fd2006-12-22 21:20:52 +00002775static CharDriverState *qemu_chr_open_tty(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002776{
2777 CharDriverState *chr;
2778 int fd;
2779
balrogaeb30be2007-07-02 15:03:13 +00002780 TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
bellardf8d179e2005-11-08 22:30:36 +00002781 tty_serial_init(fd, 115200, 'N', 8, 1);
2782 chr = qemu_chr_open_fd(fd, fd);
balrogaeb30be2007-07-02 15:03:13 +00002783 if (!chr) {
2784 close(fd);
bellardf8d179e2005-11-08 22:30:36 +00002785 return NULL;
balrogaeb30be2007-07-02 15:03:13 +00002786 }
bellarde57a8c02005-11-10 23:58:52 +00002787 chr->chr_ioctl = tty_serial_ioctl;
ths86e94de2007-01-05 22:01:59 +00002788 qemu_chr_reset(chr);
bellarde57a8c02005-11-10 23:58:52 +00002789 return chr;
2790}
thsaec62502007-06-25 11:48:07 +00002791#else /* ! __linux__ && ! __sun__ */
2792static CharDriverState *qemu_chr_open_pty(void)
2793{
2794 return NULL;
2795}
2796#endif /* __linux__ || __sun__ */
bellarde57a8c02005-11-10 23:58:52 +00002797
thsaec62502007-06-25 11:48:07 +00002798#if defined(__linux__)
ths5867c882007-02-17 23:44:43 +00002799typedef struct {
2800 int fd;
2801 int mode;
2802} ParallelCharDriver;
2803
2804static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2805{
2806 if (s->mode != mode) {
2807 int m = mode;
2808 if (ioctl(s->fd, PPSETMODE, &m) < 0)
2809 return 0;
2810 s->mode = mode;
2811 }
2812 return 1;
2813}
2814
bellarde57a8c02005-11-10 23:58:52 +00002815static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2816{
ths5867c882007-02-17 23:44:43 +00002817 ParallelCharDriver *drv = chr->opaque;
2818 int fd = drv->fd;
bellarde57a8c02005-11-10 23:58:52 +00002819 uint8_t b;
2820
2821 switch(cmd) {
2822 case CHR_IOCTL_PP_READ_DATA:
2823 if (ioctl(fd, PPRDATA, &b) < 0)
2824 return -ENOTSUP;
2825 *(uint8_t *)arg = b;
2826 break;
2827 case CHR_IOCTL_PP_WRITE_DATA:
2828 b = *(uint8_t *)arg;
2829 if (ioctl(fd, PPWDATA, &b) < 0)
2830 return -ENOTSUP;
2831 break;
2832 case CHR_IOCTL_PP_READ_CONTROL:
2833 if (ioctl(fd, PPRCONTROL, &b) < 0)
2834 return -ENOTSUP;
ths5867c882007-02-17 23:44:43 +00002835 /* Linux gives only the lowest bits, and no way to know data
2836 direction! For better compatibility set the fixed upper
2837 bits. */
2838 *(uint8_t *)arg = b | 0xc0;
bellarde57a8c02005-11-10 23:58:52 +00002839 break;
2840 case CHR_IOCTL_PP_WRITE_CONTROL:
2841 b = *(uint8_t *)arg;
2842 if (ioctl(fd, PPWCONTROL, &b) < 0)
2843 return -ENOTSUP;
2844 break;
2845 case CHR_IOCTL_PP_READ_STATUS:
2846 if (ioctl(fd, PPRSTATUS, &b) < 0)
2847 return -ENOTSUP;
2848 *(uint8_t *)arg = b;
2849 break;
aurel32563e3c62008-08-22 08:57:09 +00002850 case CHR_IOCTL_PP_DATA_DIR:
2851 if (ioctl(fd, PPDATADIR, (int *)arg) < 0)
2852 return -ENOTSUP;
2853 break;
ths5867c882007-02-17 23:44:43 +00002854 case CHR_IOCTL_PP_EPP_READ_ADDR:
2855 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2856 struct ParallelIOArg *parg = arg;
2857 int n = read(fd, parg->buffer, parg->count);
2858 if (n != parg->count) {
2859 return -EIO;
2860 }
2861 }
2862 break;
2863 case CHR_IOCTL_PP_EPP_READ:
2864 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2865 struct ParallelIOArg *parg = arg;
2866 int n = read(fd, parg->buffer, parg->count);
2867 if (n != parg->count) {
2868 return -EIO;
2869 }
2870 }
2871 break;
2872 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2873 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2874 struct ParallelIOArg *parg = arg;
2875 int n = write(fd, parg->buffer, parg->count);
2876 if (n != parg->count) {
2877 return -EIO;
2878 }
2879 }
2880 break;
2881 case CHR_IOCTL_PP_EPP_WRITE:
2882 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2883 struct ParallelIOArg *parg = arg;
2884 int n = write(fd, parg->buffer, parg->count);
2885 if (n != parg->count) {
2886 return -EIO;
2887 }
2888 }
2889 break;
bellarde57a8c02005-11-10 23:58:52 +00002890 default:
2891 return -ENOTSUP;
2892 }
2893 return 0;
2894}
2895
ths5867c882007-02-17 23:44:43 +00002896static void pp_close(CharDriverState *chr)
2897{
2898 ParallelCharDriver *drv = chr->opaque;
2899 int fd = drv->fd;
2900
2901 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2902 ioctl(fd, PPRELEASE);
2903 close(fd);
2904 qemu_free(drv);
2905}
2906
ths52f61fd2006-12-22 21:20:52 +00002907static CharDriverState *qemu_chr_open_pp(const char *filename)
bellarde57a8c02005-11-10 23:58:52 +00002908{
2909 CharDriverState *chr;
ths5867c882007-02-17 23:44:43 +00002910 ParallelCharDriver *drv;
bellarde57a8c02005-11-10 23:58:52 +00002911 int fd;
2912
balrogaeb30be2007-07-02 15:03:13 +00002913 TFR(fd = open(filename, O_RDWR));
bellarde57a8c02005-11-10 23:58:52 +00002914 if (fd < 0)
2915 return NULL;
2916
2917 if (ioctl(fd, PPCLAIM) < 0) {
2918 close(fd);
2919 return NULL;
2920 }
2921
ths5867c882007-02-17 23:44:43 +00002922 drv = qemu_mallocz(sizeof(ParallelCharDriver));
2923 if (!drv) {
bellarde57a8c02005-11-10 23:58:52 +00002924 close(fd);
2925 return NULL;
2926 }
ths5867c882007-02-17 23:44:43 +00002927 drv->fd = fd;
2928 drv->mode = IEEE1284_MODE_COMPAT;
2929
2930 chr = qemu_mallocz(sizeof(CharDriverState));
2931 if (!chr) {
2932 qemu_free(drv);
2933 close(fd);
2934 return NULL;
2935 }
bellarde57a8c02005-11-10 23:58:52 +00002936 chr->chr_write = null_chr_write;
bellarde57a8c02005-11-10 23:58:52 +00002937 chr->chr_ioctl = pp_ioctl;
ths5867c882007-02-17 23:44:43 +00002938 chr->chr_close = pp_close;
2939 chr->opaque = drv;
ths86e94de2007-01-05 22:01:59 +00002940
2941 qemu_chr_reset(chr);
2942
bellardf8d179e2005-11-08 22:30:36 +00002943 return chr;
2944}
thsaec62502007-06-25 11:48:07 +00002945#endif /* __linux__ */
bellardf8d179e2005-11-08 22:30:36 +00002946
thsaec62502007-06-25 11:48:07 +00002947#else /* _WIN32 */
bellard67b915a2004-03-31 23:37:16 +00002948
bellardf3311102006-04-12 20:21:17 +00002949typedef struct {
bellardf3311102006-04-12 20:21:17 +00002950 int max_size;
2951 HANDLE hcom, hrecv, hsend;
2952 OVERLAPPED orecv, osend;
2953 BOOL fpipe;
2954 DWORD len;
2955} WinCharState;
2956
2957#define NSENDBUF 2048
2958#define NRECVBUF 2048
2959#define MAXCONNECT 1
2960#define NTIMEOUT 5000
2961
2962static int win_chr_poll(void *opaque);
2963static int win_chr_pipe_poll(void *opaque);
2964
ths087f4ae2007-02-10 21:50:42 +00002965static void win_chr_close(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002966{
ths087f4ae2007-02-10 21:50:42 +00002967 WinCharState *s = chr->opaque;
2968
bellardf3311102006-04-12 20:21:17 +00002969 if (s->hsend) {
2970 CloseHandle(s->hsend);
2971 s->hsend = NULL;
2972 }
2973 if (s->hrecv) {
2974 CloseHandle(s->hrecv);
2975 s->hrecv = NULL;
2976 }
2977 if (s->hcom) {
2978 CloseHandle(s->hcom);
2979 s->hcom = NULL;
2980 }
2981 if (s->fpipe)
ths087f4ae2007-02-10 21:50:42 +00002982 qemu_del_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002983 else
ths087f4ae2007-02-10 21:50:42 +00002984 qemu_del_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002985}
2986
ths087f4ae2007-02-10 21:50:42 +00002987static int win_chr_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00002988{
2989 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002990 COMMCONFIG comcfg;
2991 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2992 COMSTAT comstat;
2993 DWORD size;
2994 DWORD err;
ths3b46e622007-09-17 08:09:54 +00002995
bellardf3311102006-04-12 20:21:17 +00002996 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2997 if (!s->hsend) {
2998 fprintf(stderr, "Failed CreateEvent\n");
2999 goto fail;
3000 }
3001 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
3002 if (!s->hrecv) {
3003 fprintf(stderr, "Failed CreateEvent\n");
3004 goto fail;
3005 }
3006
3007 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
3008 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
3009 if (s->hcom == INVALID_HANDLE_VALUE) {
3010 fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
3011 s->hcom = NULL;
3012 goto fail;
3013 }
ths3b46e622007-09-17 08:09:54 +00003014
bellardf3311102006-04-12 20:21:17 +00003015 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
3016 fprintf(stderr, "Failed SetupComm\n");
3017 goto fail;
3018 }
ths3b46e622007-09-17 08:09:54 +00003019
bellardf3311102006-04-12 20:21:17 +00003020 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
3021 size = sizeof(COMMCONFIG);
3022 GetDefaultCommConfig(filename, &comcfg, &size);
3023 comcfg.dcb.DCBlength = sizeof(DCB);
3024 CommConfigDialog(filename, NULL, &comcfg);
3025
3026 if (!SetCommState(s->hcom, &comcfg.dcb)) {
3027 fprintf(stderr, "Failed SetCommState\n");
3028 goto fail;
3029 }
3030
3031 if (!SetCommMask(s->hcom, EV_ERR)) {
3032 fprintf(stderr, "Failed SetCommMask\n");
3033 goto fail;
3034 }
3035
3036 cto.ReadIntervalTimeout = MAXDWORD;
3037 if (!SetCommTimeouts(s->hcom, &cto)) {
3038 fprintf(stderr, "Failed SetCommTimeouts\n");
3039 goto fail;
3040 }
ths3b46e622007-09-17 08:09:54 +00003041
bellardf3311102006-04-12 20:21:17 +00003042 if (!ClearCommError(s->hcom, &err, &comstat)) {
3043 fprintf(stderr, "Failed ClearCommError\n");
3044 goto fail;
3045 }
ths087f4ae2007-02-10 21:50:42 +00003046 qemu_add_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00003047 return 0;
3048
3049 fail:
ths087f4ae2007-02-10 21:50:42 +00003050 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00003051 return -1;
3052}
3053
3054static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
3055{
3056 WinCharState *s = chr->opaque;
3057 DWORD len, ret, size, err;
3058
3059 len = len1;
3060 ZeroMemory(&s->osend, sizeof(s->osend));
3061 s->osend.hEvent = s->hsend;
3062 while (len > 0) {
3063 if (s->hsend)
3064 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
3065 else
3066 ret = WriteFile(s->hcom, buf, len, &size, NULL);
3067 if (!ret) {
3068 err = GetLastError();
3069 if (err == ERROR_IO_PENDING) {
3070 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
3071 if (ret) {
3072 buf += size;
3073 len -= size;
3074 } else {
3075 break;
3076 }
3077 } else {
3078 break;
3079 }
3080 } else {
3081 buf += size;
3082 len -= size;
3083 }
3084 }
3085 return len1 - len;
3086}
3087
ths087f4ae2007-02-10 21:50:42 +00003088static int win_chr_read_poll(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003089{
ths087f4ae2007-02-10 21:50:42 +00003090 WinCharState *s = chr->opaque;
3091
3092 s->max_size = qemu_chr_can_read(chr);
bellardf3311102006-04-12 20:21:17 +00003093 return s->max_size;
3094}
pbrooke5b0bc42007-01-27 23:46:43 +00003095
ths087f4ae2007-02-10 21:50:42 +00003096static void win_chr_readfile(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003097{
ths087f4ae2007-02-10 21:50:42 +00003098 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003099 int ret, err;
3100 uint8_t buf[1024];
3101 DWORD size;
ths3b46e622007-09-17 08:09:54 +00003102
bellardf3311102006-04-12 20:21:17 +00003103 ZeroMemory(&s->orecv, sizeof(s->orecv));
3104 s->orecv.hEvent = s->hrecv;
3105 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
3106 if (!ret) {
3107 err = GetLastError();
3108 if (err == ERROR_IO_PENDING) {
3109 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
3110 }
3111 }
3112
3113 if (size > 0) {
ths087f4ae2007-02-10 21:50:42 +00003114 qemu_chr_read(chr, buf, size);
bellardf3311102006-04-12 20:21:17 +00003115 }
3116}
3117
ths087f4ae2007-02-10 21:50:42 +00003118static void win_chr_read(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00003119{
ths087f4ae2007-02-10 21:50:42 +00003120 WinCharState *s = chr->opaque;
3121
bellardf3311102006-04-12 20:21:17 +00003122 if (s->len > s->max_size)
3123 s->len = s->max_size;
3124 if (s->len == 0)
3125 return;
ths3b46e622007-09-17 08:09:54 +00003126
ths087f4ae2007-02-10 21:50:42 +00003127 win_chr_readfile(chr);
bellardf3311102006-04-12 20:21:17 +00003128}
3129
3130static int win_chr_poll(void *opaque)
3131{
ths087f4ae2007-02-10 21:50:42 +00003132 CharDriverState *chr = opaque;
3133 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003134 COMSTAT status;
3135 DWORD comerr;
ths3b46e622007-09-17 08:09:54 +00003136
bellardf3311102006-04-12 20:21:17 +00003137 ClearCommError(s->hcom, &comerr, &status);
3138 if (status.cbInQue > 0) {
3139 s->len = status.cbInQue;
ths087f4ae2007-02-10 21:50:42 +00003140 win_chr_read_poll(chr);
3141 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00003142 return 1;
3143 }
3144 return 0;
3145}
3146
ths52f61fd2006-12-22 21:20:52 +00003147static CharDriverState *qemu_chr_open_win(const char *filename)
bellardf3311102006-04-12 20:21:17 +00003148{
3149 CharDriverState *chr;
3150 WinCharState *s;
ths3b46e622007-09-17 08:09:54 +00003151
bellardf3311102006-04-12 20:21:17 +00003152 chr = qemu_mallocz(sizeof(CharDriverState));
3153 if (!chr)
3154 return NULL;
3155 s = qemu_mallocz(sizeof(WinCharState));
3156 if (!s) {
3157 free(chr);
3158 return NULL;
3159 }
3160 chr->opaque = s;
3161 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00003162 chr->chr_close = win_chr_close;
3163
ths087f4ae2007-02-10 21:50:42 +00003164 if (win_chr_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00003165 free(s);
3166 free(chr);
3167 return NULL;
3168 }
ths86e94de2007-01-05 22:01:59 +00003169 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003170 return chr;
3171}
3172
3173static int win_chr_pipe_poll(void *opaque)
3174{
ths087f4ae2007-02-10 21:50:42 +00003175 CharDriverState *chr = opaque;
3176 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003177 DWORD size;
3178
3179 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
3180 if (size > 0) {
3181 s->len = size;
ths087f4ae2007-02-10 21:50:42 +00003182 win_chr_read_poll(chr);
3183 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00003184 return 1;
3185 }
3186 return 0;
3187}
3188
ths087f4ae2007-02-10 21:50:42 +00003189static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00003190{
ths087f4ae2007-02-10 21:50:42 +00003191 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00003192 OVERLAPPED ov;
3193 int ret;
3194 DWORD size;
3195 char openname[256];
ths3b46e622007-09-17 08:09:54 +00003196
bellardf3311102006-04-12 20:21:17 +00003197 s->fpipe = TRUE;
3198
3199 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
3200 if (!s->hsend) {
3201 fprintf(stderr, "Failed CreateEvent\n");
3202 goto fail;
3203 }
3204 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
3205 if (!s->hrecv) {
3206 fprintf(stderr, "Failed CreateEvent\n");
3207 goto fail;
3208 }
ths3b46e622007-09-17 08:09:54 +00003209
bellardf3311102006-04-12 20:21:17 +00003210 snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
3211 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
3212 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
3213 PIPE_WAIT,
3214 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
3215 if (s->hcom == INVALID_HANDLE_VALUE) {
3216 fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
3217 s->hcom = NULL;
3218 goto fail;
3219 }
3220
3221 ZeroMemory(&ov, sizeof(ov));
3222 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
3223 ret = ConnectNamedPipe(s->hcom, &ov);
3224 if (ret) {
3225 fprintf(stderr, "Failed ConnectNamedPipe\n");
3226 goto fail;
3227 }
3228
3229 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
3230 if (!ret) {
3231 fprintf(stderr, "Failed GetOverlappedResult\n");
3232 if (ov.hEvent) {
3233 CloseHandle(ov.hEvent);
3234 ov.hEvent = NULL;
3235 }
3236 goto fail;
3237 }
3238
3239 if (ov.hEvent) {
3240 CloseHandle(ov.hEvent);
3241 ov.hEvent = NULL;
3242 }
ths087f4ae2007-02-10 21:50:42 +00003243 qemu_add_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00003244 return 0;
3245
3246 fail:
ths087f4ae2007-02-10 21:50:42 +00003247 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00003248 return -1;
3249}
3250
3251
ths52f61fd2006-12-22 21:20:52 +00003252static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
bellardf3311102006-04-12 20:21:17 +00003253{
3254 CharDriverState *chr;
3255 WinCharState *s;
3256
3257 chr = qemu_mallocz(sizeof(CharDriverState));
3258 if (!chr)
3259 return NULL;
3260 s = qemu_mallocz(sizeof(WinCharState));
3261 if (!s) {
3262 free(chr);
3263 return NULL;
3264 }
3265 chr->opaque = s;
3266 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00003267 chr->chr_close = win_chr_close;
ths3b46e622007-09-17 08:09:54 +00003268
ths087f4ae2007-02-10 21:50:42 +00003269 if (win_chr_pipe_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00003270 free(s);
3271 free(chr);
3272 return NULL;
3273 }
ths86e94de2007-01-05 22:01:59 +00003274 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003275 return chr;
3276}
3277
ths52f61fd2006-12-22 21:20:52 +00003278static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
bellardf3311102006-04-12 20:21:17 +00003279{
3280 CharDriverState *chr;
3281 WinCharState *s;
3282
3283 chr = qemu_mallocz(sizeof(CharDriverState));
3284 if (!chr)
3285 return NULL;
3286 s = qemu_mallocz(sizeof(WinCharState));
3287 if (!s) {
3288 free(chr);
3289 return NULL;
3290 }
3291 s->hcom = fd_out;
3292 chr->opaque = s;
3293 chr->chr_write = win_chr_write;
ths86e94de2007-01-05 22:01:59 +00003294 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003295 return chr;
3296}
ths72d46472007-05-13 14:54:54 +00003297
3298static CharDriverState *qemu_chr_open_win_con(const char *filename)
3299{
3300 return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
3301}
3302
ths52f61fd2006-12-22 21:20:52 +00003303static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
bellardf3311102006-04-12 20:21:17 +00003304{
3305 HANDLE fd_out;
ths3b46e622007-09-17 08:09:54 +00003306
bellardf3311102006-04-12 20:21:17 +00003307 fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3308 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3309 if (fd_out == INVALID_HANDLE_VALUE)
3310 return NULL;
3311
3312 return qemu_chr_open_win_file(fd_out);
3313}
thsaec62502007-06-25 11:48:07 +00003314#endif /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003315
bellard0bab00f2006-06-25 14:49:44 +00003316/***********************************************************/
3317/* UDP Net console */
3318
3319typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003320 int fd;
3321 struct sockaddr_in daddr;
ths60fe76f2007-12-16 03:02:09 +00003322 uint8_t buf[1024];
bellard0bab00f2006-06-25 14:49:44 +00003323 int bufcnt;
3324 int bufptr;
3325 int max_size;
3326} NetCharDriver;
3327
3328static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3329{
3330 NetCharDriver *s = chr->opaque;
3331
3332 return sendto(s->fd, buf, len, 0,
3333 (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
3334}
3335
3336static int udp_chr_read_poll(void *opaque)
3337{
3338 CharDriverState *chr = opaque;
3339 NetCharDriver *s = chr->opaque;
3340
pbrooke5b0bc42007-01-27 23:46:43 +00003341 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003342
3343 /* If there were any stray characters in the queue process them
3344 * first
3345 */
3346 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003347 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003348 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003349 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003350 }
3351 return s->max_size;
3352}
3353
3354static void udp_chr_read(void *opaque)
3355{
3356 CharDriverState *chr = opaque;
3357 NetCharDriver *s = chr->opaque;
3358
3359 if (s->max_size == 0)
3360 return;
3361 s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
3362 s->bufptr = s->bufcnt;
3363 if (s->bufcnt <= 0)
3364 return;
3365
3366 s->bufptr = 0;
3367 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003368 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003369 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003370 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003371 }
3372}
3373
pbrooke5b0bc42007-01-27 23:46:43 +00003374static void udp_chr_update_read_handler(CharDriverState *chr)
bellard0bab00f2006-06-25 14:49:44 +00003375{
3376 NetCharDriver *s = chr->opaque;
3377
3378 if (s->fd >= 0) {
bellard0bab00f2006-06-25 14:49:44 +00003379 qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
3380 udp_chr_read, NULL, chr);
3381 }
3382}
3383
3384int parse_host_port(struct sockaddr_in *saddr, const char *str);
ths52f61fd2006-12-22 21:20:52 +00003385#ifndef _WIN32
3386static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3387#endif
bellard951f1352006-06-27 21:02:43 +00003388int parse_host_src_port(struct sockaddr_in *haddr,
3389 struct sockaddr_in *saddr,
3390 const char *str);
bellard0bab00f2006-06-25 14:49:44 +00003391
ths52f61fd2006-12-22 21:20:52 +00003392static CharDriverState *qemu_chr_open_udp(const char *def)
bellard0bab00f2006-06-25 14:49:44 +00003393{
3394 CharDriverState *chr = NULL;
3395 NetCharDriver *s = NULL;
3396 int fd = -1;
bellard951f1352006-06-27 21:02:43 +00003397 struct sockaddr_in saddr;
bellard0bab00f2006-06-25 14:49:44 +00003398
3399 chr = qemu_mallocz(sizeof(CharDriverState));
3400 if (!chr)
3401 goto return_err;
3402 s = qemu_mallocz(sizeof(NetCharDriver));
3403 if (!s)
3404 goto return_err;
3405
3406 fd = socket(PF_INET, SOCK_DGRAM, 0);
3407 if (fd < 0) {
3408 perror("socket(PF_INET, SOCK_DGRAM)");
3409 goto return_err;
3410 }
3411
bellard951f1352006-06-27 21:02:43 +00003412 if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
3413 printf("Could not parse: %s\n", def);
3414 goto return_err;
bellard0bab00f2006-06-25 14:49:44 +00003415 }
3416
bellard951f1352006-06-27 21:02:43 +00003417 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
bellard0bab00f2006-06-25 14:49:44 +00003418 {
3419 perror("bind");
3420 goto return_err;
3421 }
3422
3423 s->fd = fd;
3424 s->bufcnt = 0;
3425 s->bufptr = 0;
3426 chr->opaque = s;
3427 chr->chr_write = udp_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00003428 chr->chr_update_read_handler = udp_chr_update_read_handler;
bellard0bab00f2006-06-25 14:49:44 +00003429 return chr;
3430
3431return_err:
3432 if (chr)
3433 free(chr);
3434 if (s)
3435 free(s);
3436 if (fd >= 0)
3437 closesocket(fd);
3438 return NULL;
3439}
3440
3441/***********************************************************/
3442/* TCP Net console */
3443
3444typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003445 int fd, listen_fd;
3446 int connected;
3447 int max_size;
bellard951f1352006-06-27 21:02:43 +00003448 int do_telnetopt;
pbrooke5b0bc42007-01-27 23:46:43 +00003449 int do_nodelay;
thsffd843b2006-12-21 19:46:43 +00003450 int is_unix;
bellard0bab00f2006-06-25 14:49:44 +00003451} TCPCharDriver;
3452
3453static void tcp_chr_accept(void *opaque);
3454
3455static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3456{
3457 TCPCharDriver *s = chr->opaque;
3458 if (s->connected) {
3459 return send_all(s->fd, buf, len);
3460 } else {
3461 /* XXX: indicate an error ? */
3462 return len;
3463 }
3464}
3465
3466static int tcp_chr_read_poll(void *opaque)
3467{
3468 CharDriverState *chr = opaque;
3469 TCPCharDriver *s = chr->opaque;
3470 if (!s->connected)
3471 return 0;
pbrooke5b0bc42007-01-27 23:46:43 +00003472 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003473 return s->max_size;
3474}
3475
bellard951f1352006-06-27 21:02:43 +00003476#define IAC 255
3477#define IAC_BREAK 243
3478static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
3479 TCPCharDriver *s,
ths60fe76f2007-12-16 03:02:09 +00003480 uint8_t *buf, int *size)
bellard951f1352006-06-27 21:02:43 +00003481{
3482 /* Handle any telnet client's basic IAC options to satisfy char by
3483 * char mode with no echo. All IAC options will be removed from
3484 * the buf and the do_telnetopt variable will be used to track the
3485 * state of the width of the IAC information.
3486 *
3487 * IAC commands come in sets of 3 bytes with the exception of the
3488 * "IAC BREAK" command and the double IAC.
3489 */
3490
3491 int i;
3492 int j = 0;
3493
3494 for (i = 0; i < *size; i++) {
3495 if (s->do_telnetopt > 1) {
3496 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3497 /* Double IAC means send an IAC */
3498 if (j != i)
3499 buf[j] = buf[i];
3500 j++;
3501 s->do_telnetopt = 1;
3502 } else {
3503 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3504 /* Handle IAC break commands by sending a serial break */
pbrooke5b0bc42007-01-27 23:46:43 +00003505 qemu_chr_event(chr, CHR_EVENT_BREAK);
bellard951f1352006-06-27 21:02:43 +00003506 s->do_telnetopt++;
3507 }
3508 s->do_telnetopt++;
3509 }
3510 if (s->do_telnetopt >= 4) {
3511 s->do_telnetopt = 1;
3512 }
3513 } else {
3514 if ((unsigned char)buf[i] == IAC) {
3515 s->do_telnetopt = 2;
3516 } else {
3517 if (j != i)
3518 buf[j] = buf[i];
3519 j++;
3520 }
3521 }
3522 }
3523 *size = j;
3524}
3525
bellard0bab00f2006-06-25 14:49:44 +00003526static void tcp_chr_read(void *opaque)
3527{
3528 CharDriverState *chr = opaque;
3529 TCPCharDriver *s = chr->opaque;
3530 uint8_t buf[1024];
3531 int len, size;
3532
3533 if (!s->connected || s->max_size <= 0)
3534 return;
3535 len = sizeof(buf);
3536 if (len > s->max_size)
3537 len = s->max_size;
3538 size = recv(s->fd, buf, len, 0);
3539 if (size == 0) {
3540 /* connection closed */
3541 s->connected = 0;
3542 if (s->listen_fd >= 0) {
3543 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3544 }
3545 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3546 closesocket(s->fd);
3547 s->fd = -1;
3548 } else if (size > 0) {
bellard951f1352006-06-27 21:02:43 +00003549 if (s->do_telnetopt)
3550 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3551 if (size > 0)
pbrooke5b0bc42007-01-27 23:46:43 +00003552 qemu_chr_read(chr, buf, size);
bellard0bab00f2006-06-25 14:49:44 +00003553 }
3554}
3555
bellard0bab00f2006-06-25 14:49:44 +00003556static void tcp_chr_connect(void *opaque)
3557{
3558 CharDriverState *chr = opaque;
3559 TCPCharDriver *s = chr->opaque;
3560
3561 s->connected = 1;
3562 qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3563 tcp_chr_read, NULL, chr);
ths86e94de2007-01-05 22:01:59 +00003564 qemu_chr_reset(chr);
bellard0bab00f2006-06-25 14:49:44 +00003565}
3566
bellard951f1352006-06-27 21:02:43 +00003567#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3568static void tcp_chr_telnet_init(int fd)
3569{
3570 char buf[3];
3571 /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3572 IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
3573 send(fd, (char *)buf, 3, 0);
3574 IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
3575 send(fd, (char *)buf, 3, 0);
3576 IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
3577 send(fd, (char *)buf, 3, 0);
3578 IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
3579 send(fd, (char *)buf, 3, 0);
3580}
3581
pbrookf7499982007-01-28 00:10:01 +00003582static void socket_set_nodelay(int fd)
3583{
3584 int val = 1;
3585 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3586}
3587
bellard0bab00f2006-06-25 14:49:44 +00003588static void tcp_chr_accept(void *opaque)
3589{
3590 CharDriverState *chr = opaque;
3591 TCPCharDriver *s = chr->opaque;
3592 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003593#ifndef _WIN32
3594 struct sockaddr_un uaddr;
3595#endif
3596 struct sockaddr *addr;
bellard0bab00f2006-06-25 14:49:44 +00003597 socklen_t len;
3598 int fd;
3599
3600 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003601#ifndef _WIN32
3602 if (s->is_unix) {
3603 len = sizeof(uaddr);
3604 addr = (struct sockaddr *)&uaddr;
3605 } else
3606#endif
3607 {
3608 len = sizeof(saddr);
3609 addr = (struct sockaddr *)&saddr;
3610 }
3611 fd = accept(s->listen_fd, addr, &len);
bellard0bab00f2006-06-25 14:49:44 +00003612 if (fd < 0 && errno != EINTR) {
3613 return;
3614 } else if (fd >= 0) {
bellard951f1352006-06-27 21:02:43 +00003615 if (s->do_telnetopt)
3616 tcp_chr_telnet_init(fd);
bellard0bab00f2006-06-25 14:49:44 +00003617 break;
3618 }
3619 }
3620 socket_set_nonblock(fd);
pbrookf7499982007-01-28 00:10:01 +00003621 if (s->do_nodelay)
3622 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003623 s->fd = fd;
3624 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3625 tcp_chr_connect(chr);
3626}
3627
3628static void tcp_chr_close(CharDriverState *chr)
3629{
3630 TCPCharDriver *s = chr->opaque;
3631 if (s->fd >= 0)
3632 closesocket(s->fd);
3633 if (s->listen_fd >= 0)
3634 closesocket(s->listen_fd);
3635 qemu_free(s);
3636}
3637
ths5fafdf22007-09-16 21:08:06 +00003638static CharDriverState *qemu_chr_open_tcp(const char *host_str,
thsffd843b2006-12-21 19:46:43 +00003639 int is_telnet,
3640 int is_unix)
bellard0bab00f2006-06-25 14:49:44 +00003641{
3642 CharDriverState *chr = NULL;
3643 TCPCharDriver *s = NULL;
3644 int fd = -1, ret, err, val;
bellard951f1352006-06-27 21:02:43 +00003645 int is_listen = 0;
3646 int is_waitconnect = 1;
pbrookf7499982007-01-28 00:10:01 +00003647 int do_nodelay = 0;
bellard951f1352006-06-27 21:02:43 +00003648 const char *ptr;
bellard0bab00f2006-06-25 14:49:44 +00003649 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003650#ifndef _WIN32
3651 struct sockaddr_un uaddr;
3652#endif
3653 struct sockaddr *addr;
3654 socklen_t addrlen;
bellard0bab00f2006-06-25 14:49:44 +00003655
thsffd843b2006-12-21 19:46:43 +00003656#ifndef _WIN32
3657 if (is_unix) {
3658 addr = (struct sockaddr *)&uaddr;
3659 addrlen = sizeof(uaddr);
3660 if (parse_unix_path(&uaddr, host_str) < 0)
3661 goto fail;
3662 } else
3663#endif
3664 {
3665 addr = (struct sockaddr *)&saddr;
3666 addrlen = sizeof(saddr);
3667 if (parse_host_port(&saddr, host_str) < 0)
3668 goto fail;
3669 }
bellard0bab00f2006-06-25 14:49:44 +00003670
bellard951f1352006-06-27 21:02:43 +00003671 ptr = host_str;
3672 while((ptr = strchr(ptr,','))) {
3673 ptr++;
3674 if (!strncmp(ptr,"server",6)) {
3675 is_listen = 1;
3676 } else if (!strncmp(ptr,"nowait",6)) {
3677 is_waitconnect = 0;
pbrookf7499982007-01-28 00:10:01 +00003678 } else if (!strncmp(ptr,"nodelay",6)) {
3679 do_nodelay = 1;
bellard951f1352006-06-27 21:02:43 +00003680 } else {
3681 printf("Unknown option: %s\n", ptr);
3682 goto fail;
3683 }
3684 }
3685 if (!is_listen)
3686 is_waitconnect = 0;
3687
bellard0bab00f2006-06-25 14:49:44 +00003688 chr = qemu_mallocz(sizeof(CharDriverState));
3689 if (!chr)
3690 goto fail;
3691 s = qemu_mallocz(sizeof(TCPCharDriver));
3692 if (!s)
3693 goto fail;
thsffd843b2006-12-21 19:46:43 +00003694
3695#ifndef _WIN32
3696 if (is_unix)
3697 fd = socket(PF_UNIX, SOCK_STREAM, 0);
3698 else
3699#endif
3700 fd = socket(PF_INET, SOCK_STREAM, 0);
ths5fafdf22007-09-16 21:08:06 +00003701
3702 if (fd < 0)
bellard0bab00f2006-06-25 14:49:44 +00003703 goto fail;
bellard951f1352006-06-27 21:02:43 +00003704
3705 if (!is_waitconnect)
3706 socket_set_nonblock(fd);
bellard0bab00f2006-06-25 14:49:44 +00003707
3708 s->connected = 0;
3709 s->fd = -1;
3710 s->listen_fd = -1;
thsffd843b2006-12-21 19:46:43 +00003711 s->is_unix = is_unix;
pbrookf7499982007-01-28 00:10:01 +00003712 s->do_nodelay = do_nodelay && !is_unix;
thsffd843b2006-12-21 19:46:43 +00003713
3714 chr->opaque = s;
3715 chr->chr_write = tcp_chr_write;
thsffd843b2006-12-21 19:46:43 +00003716 chr->chr_close = tcp_chr_close;
3717
bellard0bab00f2006-06-25 14:49:44 +00003718 if (is_listen) {
3719 /* allow fast reuse */
thsffd843b2006-12-21 19:46:43 +00003720#ifndef _WIN32
3721 if (is_unix) {
3722 char path[109];
bellardae45d362008-06-11 09:44:44 +00003723 pstrcpy(path, sizeof(path), uaddr.sun_path);
thsffd843b2006-12-21 19:46:43 +00003724 unlink(path);
3725 } else
3726#endif
3727 {
3728 val = 1;
3729 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3730 }
ths3b46e622007-09-17 08:09:54 +00003731
thsffd843b2006-12-21 19:46:43 +00003732 ret = bind(fd, addr, addrlen);
3733 if (ret < 0)
bellard0bab00f2006-06-25 14:49:44 +00003734 goto fail;
thsffd843b2006-12-21 19:46:43 +00003735
bellard0bab00f2006-06-25 14:49:44 +00003736 ret = listen(fd, 0);
3737 if (ret < 0)
3738 goto fail;
thsffd843b2006-12-21 19:46:43 +00003739
bellard0bab00f2006-06-25 14:49:44 +00003740 s->listen_fd = fd;
3741 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
bellard951f1352006-06-27 21:02:43 +00003742 if (is_telnet)
3743 s->do_telnetopt = 1;
bellard0bab00f2006-06-25 14:49:44 +00003744 } else {
3745 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003746 ret = connect(fd, addr, addrlen);
bellard0bab00f2006-06-25 14:49:44 +00003747 if (ret < 0) {
3748 err = socket_error();
3749 if (err == EINTR || err == EWOULDBLOCK) {
3750 } else if (err == EINPROGRESS) {
3751 break;
thsf5b12262007-03-25 15:58:03 +00003752#ifdef _WIN32
3753 } else if (err == WSAEALREADY) {
3754 break;
3755#endif
bellard0bab00f2006-06-25 14:49:44 +00003756 } else {
3757 goto fail;
3758 }
3759 } else {
3760 s->connected = 1;
3761 break;
3762 }
3763 }
3764 s->fd = fd;
pbrookf7499982007-01-28 00:10:01 +00003765 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003766 if (s->connected)
3767 tcp_chr_connect(chr);
3768 else
3769 qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3770 }
ths3b46e622007-09-17 08:09:54 +00003771
bellard951f1352006-06-27 21:02:43 +00003772 if (is_listen && is_waitconnect) {
3773 printf("QEMU waiting for connection on: %s\n", host_str);
3774 tcp_chr_accept(chr);
3775 socket_set_nonblock(s->listen_fd);
3776 }
3777
bellard0bab00f2006-06-25 14:49:44 +00003778 return chr;
3779 fail:
3780 if (fd >= 0)
3781 closesocket(fd);
3782 qemu_free(s);
3783 qemu_free(chr);
3784 return NULL;
3785}
3786
bellard82c643f2004-07-14 17:28:13 +00003787CharDriverState *qemu_chr_open(const char *filename)
3788{
bellardf8d179e2005-11-08 22:30:36 +00003789 const char *p;
bellardfd1dff42006-02-01 21:29:26 +00003790
bellard82c643f2004-07-14 17:28:13 +00003791 if (!strcmp(filename, "vc")) {
thsaf3a9032007-07-11 23:14:59 +00003792 return text_console_init(&display_state, 0);
3793 } else if (strstart(filename, "vc:", &p)) {
3794 return text_console_init(&display_state, p);
bellard82c643f2004-07-14 17:28:13 +00003795 } else if (!strcmp(filename, "null")) {
3796 return qemu_chr_open_null();
ths5fafdf22007-09-16 21:08:06 +00003797 } else
bellard0bab00f2006-06-25 14:49:44 +00003798 if (strstart(filename, "tcp:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003799 return qemu_chr_open_tcp(p, 0, 0);
bellard0bab00f2006-06-25 14:49:44 +00003800 } else
bellard951f1352006-06-27 21:02:43 +00003801 if (strstart(filename, "telnet:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003802 return qemu_chr_open_tcp(p, 1, 0);
bellard0bab00f2006-06-25 14:49:44 +00003803 } else
3804 if (strstart(filename, "udp:", &p)) {
3805 return qemu_chr_open_udp(p);
3806 } else
ths20d8a3e2007-02-18 17:04:49 +00003807 if (strstart(filename, "mon:", &p)) {
3808 CharDriverState *drv = qemu_chr_open(p);
3809 if (drv) {
3810 drv = qemu_chr_open_mux(drv);
3811 monitor_init(drv, !nographic);
3812 return drv;
3813 }
3814 printf("Unable to open driver: %s\n", p);
3815 return 0;
3816 } else
bellard76647282005-11-27 19:10:42 +00003817#ifndef _WIN32
thsffd843b2006-12-21 19:46:43 +00003818 if (strstart(filename, "unix:", &p)) {
3819 return qemu_chr_open_tcp(p, 0, 1);
3820 } else if (strstart(filename, "file:", &p)) {
bellardf8d179e2005-11-08 22:30:36 +00003821 return qemu_chr_open_file_out(p);
3822 } else if (strstart(filename, "pipe:", &p)) {
3823 return qemu_chr_open_pipe(p);
bellard76647282005-11-27 19:10:42 +00003824 } else if (!strcmp(filename, "pty")) {
bellard82c643f2004-07-14 17:28:13 +00003825 return qemu_chr_open_pty();
3826 } else if (!strcmp(filename, "stdio")) {
3827 return qemu_chr_open_stdio();
ths5fafdf22007-09-16 21:08:06 +00003828 } else
bellardf8d179e2005-11-08 22:30:36 +00003829#if defined(__linux__)
bellarde57a8c02005-11-10 23:58:52 +00003830 if (strstart(filename, "/dev/parport", NULL)) {
3831 return qemu_chr_open_pp(filename);
ths5fafdf22007-09-16 21:08:06 +00003832 } else
thsaec62502007-06-25 11:48:07 +00003833#endif
blueswir19892fbf2008-08-24 10:34:20 +00003834#if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
3835 || defined(__NetBSD__) || defined(__OpenBSD__)
bellardf8d179e2005-11-08 22:30:36 +00003836 if (strstart(filename, "/dev/", NULL)) {
3837 return qemu_chr_open_tty(filename);
ths3fda3882007-06-28 15:14:49 +00003838 } else
3839#endif
thsaec62502007-06-25 11:48:07 +00003840#else /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003841 if (strstart(filename, "COM", NULL)) {
3842 return qemu_chr_open_win(filename);
3843 } else
3844 if (strstart(filename, "pipe:", &p)) {
3845 return qemu_chr_open_win_pipe(p);
3846 } else
ths72d46472007-05-13 14:54:54 +00003847 if (strstart(filename, "con:", NULL)) {
3848 return qemu_chr_open_win_con(filename);
3849 } else
bellardf3311102006-04-12 20:21:17 +00003850 if (strstart(filename, "file:", &p)) {
3851 return qemu_chr_open_win_file_out(p);
aurel322e4d9fb2008-04-08 06:01:02 +00003852 } else
3853#endif
3854#ifdef CONFIG_BRLAPI
3855 if (!strcmp(filename, "braille")) {
3856 return chr_baum_init();
3857 } else
bellardf3311102006-04-12 20:21:17 +00003858#endif
bellard82c643f2004-07-14 17:28:13 +00003859 {
3860 return NULL;
3861 }
3862}
3863
bellardf3311102006-04-12 20:21:17 +00003864void qemu_chr_close(CharDriverState *chr)
3865{
3866 if (chr->chr_close)
3867 chr->chr_close(chr);
balroga11d0702008-01-19 13:00:43 +00003868 qemu_free(chr);
bellardf3311102006-04-12 20:21:17 +00003869}
3870
bellardf1510b22003-06-25 00:07:40 +00003871/***********************************************************/
bellard7c9d8e02005-11-15 22:16:05 +00003872/* network device redirectors */
bellardf1510b22003-06-25 00:07:40 +00003873
j_mayer3f4afa12007-11-19 01:05:22 +00003874__attribute__ (( unused ))
pbrook9596ebb2007-11-18 01:44:38 +00003875static void hex_dump(FILE *f, const uint8_t *buf, int size)
bellard67b915a2004-03-31 23:37:16 +00003876{
bellardc20709a2004-04-21 23:27:19 +00003877 int len, i, j, c;
3878
3879 for(i=0;i<size;i+=16) {
3880 len = size - i;
3881 if (len > 16)
3882 len = 16;
3883 fprintf(f, "%08x ", i);
3884 for(j=0;j<16;j++) {
3885 if (j < len)
3886 fprintf(f, " %02x", buf[i+j]);
3887 else
3888 fprintf(f, " ");
3889 }
3890 fprintf(f, " ");
3891 for(j=0;j<len;j++) {
3892 c = buf[i+j];
3893 if (c < ' ' || c > '~')
3894 c = '.';
3895 fprintf(f, "%c", c);
3896 }
3897 fprintf(f, "\n");
3898 }
3899}
3900
bellard7c9d8e02005-11-15 22:16:05 +00003901static int parse_macaddr(uint8_t *macaddr, const char *p)
bellardc20709a2004-04-21 23:27:19 +00003902{
bellard7c9d8e02005-11-15 22:16:05 +00003903 int i;
balrog76ea08f2007-12-16 11:48:54 +00003904 char *last_char;
3905 long int offset;
3906
3907 errno = 0;
3908 offset = strtol(p, &last_char, 0);
3909 if (0 == errno && '\0' == *last_char &&
3910 offset >= 0 && offset <= 0xFFFFFF) {
3911 macaddr[3] = (offset & 0xFF0000) >> 16;
3912 macaddr[4] = (offset & 0xFF00) >> 8;
3913 macaddr[5] = offset & 0xFF;
3914 return 0;
3915 } else {
3916 for(i = 0; i < 6; i++) {
3917 macaddr[i] = strtol(p, (char **)&p, 16);
3918 if (i == 5) {
3919 if (*p != '\0')
3920 return -1;
3921 } else {
3922 if (*p != ':' && *p != '-')
3923 return -1;
3924 p++;
3925 }
bellard7c9d8e02005-11-15 22:16:05 +00003926 }
balrog76ea08f2007-12-16 11:48:54 +00003927 return 0;
bellardc20709a2004-04-21 23:27:19 +00003928 }
balrog76ea08f2007-12-16 11:48:54 +00003929
3930 return -1;
bellardc20709a2004-04-21 23:27:19 +00003931}
3932
bellard9bf05442004-08-25 22:12:49 +00003933static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3934{
3935 const char *p, *p1;
3936 int len;
3937 p = *pp;
3938 p1 = strchr(p, sep);
3939 if (!p1)
3940 return -1;
3941 len = p1 - p;
3942 p1++;
3943 if (buf_size > 0) {
3944 if (len > buf_size - 1)
3945 len = buf_size - 1;
3946 memcpy(buf, p, len);
3947 buf[len] = '\0';
3948 }
3949 *pp = p1;
3950 return 0;
3951}
3952
bellard951f1352006-06-27 21:02:43 +00003953int parse_host_src_port(struct sockaddr_in *haddr,
3954 struct sockaddr_in *saddr,
3955 const char *input_str)
3956{
3957 char *str = strdup(input_str);
3958 char *host_str = str;
3959 char *src_str;
3960 char *ptr;
3961
3962 /*
3963 * Chop off any extra arguments at the end of the string which
3964 * would start with a comma, then fill in the src port information
3965 * if it was provided else use the "any address" and "any port".
3966 */
3967 if ((ptr = strchr(str,',')))
3968 *ptr = '\0';
3969
3970 if ((src_str = strchr(input_str,'@'))) {
3971 *src_str = '\0';
3972 src_str++;
3973 }
3974
3975 if (parse_host_port(haddr, host_str) < 0)
3976 goto fail;
3977
3978 if (!src_str || *src_str == '\0')
3979 src_str = ":0";
3980
3981 if (parse_host_port(saddr, src_str) < 0)
3982 goto fail;
3983
3984 free(str);
3985 return(0);
3986
3987fail:
3988 free(str);
3989 return -1;
3990}
3991
bellard7c9d8e02005-11-15 22:16:05 +00003992int parse_host_port(struct sockaddr_in *saddr, const char *str)
3993{
3994 char buf[512];
3995 struct hostent *he;
3996 const char *p, *r;
3997 int port;
3998
3999 p = str;
4000 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4001 return -1;
4002 saddr->sin_family = AF_INET;
4003 if (buf[0] == '\0') {
4004 saddr->sin_addr.s_addr = 0;
4005 } else {
4006 if (isdigit(buf[0])) {
4007 if (!inet_aton(buf, &saddr->sin_addr))
4008 return -1;
4009 } else {
bellard7c9d8e02005-11-15 22:16:05 +00004010 if ((he = gethostbyname(buf)) == NULL)
4011 return - 1;
4012 saddr->sin_addr = *(struct in_addr *)he->h_addr;
bellard7c9d8e02005-11-15 22:16:05 +00004013 }
4014 }
4015 port = strtol(p, (char **)&r, 0);
4016 if (r == p)
4017 return -1;
4018 saddr->sin_port = htons(port);
4019 return 0;
4020}
4021
ths52f61fd2006-12-22 21:20:52 +00004022#ifndef _WIN32
4023static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
thsffd843b2006-12-21 19:46:43 +00004024{
4025 const char *p;
4026 int len;
4027
4028 len = MIN(108, strlen(str));
4029 p = strchr(str, ',');
4030 if (p)
4031 len = MIN(len, p - str);
4032
4033 memset(uaddr, 0, sizeof(*uaddr));
4034
4035 uaddr->sun_family = AF_UNIX;
4036 memcpy(uaddr->sun_path, str, len);
4037
4038 return 0;
4039}
ths52f61fd2006-12-22 21:20:52 +00004040#endif
thsffd843b2006-12-21 19:46:43 +00004041
bellard7c9d8e02005-11-15 22:16:05 +00004042/* find or alloc a new VLAN */
4043VLANState *qemu_find_vlan(int id)
4044{
4045 VLANState **pvlan, *vlan;
4046 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4047 if (vlan->id == id)
4048 return vlan;
4049 }
4050 vlan = qemu_mallocz(sizeof(VLANState));
4051 if (!vlan)
4052 return NULL;
4053 vlan->id = id;
4054 vlan->next = NULL;
4055 pvlan = &first_vlan;
4056 while (*pvlan != NULL)
4057 pvlan = &(*pvlan)->next;
4058 *pvlan = vlan;
4059 return vlan;
4060}
4061
4062VLANClientState *qemu_new_vlan_client(VLANState *vlan,
pbrookd861b052006-02-04 22:15:28 +00004063 IOReadHandler *fd_read,
4064 IOCanRWHandler *fd_can_read,
4065 void *opaque)
bellard7c9d8e02005-11-15 22:16:05 +00004066{
4067 VLANClientState *vc, **pvc;
4068 vc = qemu_mallocz(sizeof(VLANClientState));
4069 if (!vc)
4070 return NULL;
4071 vc->fd_read = fd_read;
pbrookd861b052006-02-04 22:15:28 +00004072 vc->fd_can_read = fd_can_read;
bellard7c9d8e02005-11-15 22:16:05 +00004073 vc->opaque = opaque;
4074 vc->vlan = vlan;
4075
4076 vc->next = NULL;
4077 pvc = &vlan->first_client;
4078 while (*pvc != NULL)
4079 pvc = &(*pvc)->next;
4080 *pvc = vc;
4081 return vc;
4082}
4083
balrogdcf414d2008-07-17 21:00:05 +00004084void qemu_del_vlan_client(VLANClientState *vc)
4085{
4086 VLANClientState **pvc = &vc->vlan->first_client;
4087
4088 while (*pvc != NULL)
4089 if (*pvc == vc) {
4090 *pvc = vc->next;
4091 free(vc);
4092 break;
4093 } else
4094 pvc = &(*pvc)->next;
4095}
4096
pbrookd861b052006-02-04 22:15:28 +00004097int qemu_can_send_packet(VLANClientState *vc1)
4098{
4099 VLANState *vlan = vc1->vlan;
4100 VLANClientState *vc;
4101
4102 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
4103 if (vc != vc1) {
balrogfbd17112007-07-02 13:31:53 +00004104 if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
4105 return 1;
pbrookd861b052006-02-04 22:15:28 +00004106 }
4107 }
balrogfbd17112007-07-02 13:31:53 +00004108 return 0;
pbrookd861b052006-02-04 22:15:28 +00004109}
4110
bellard7c9d8e02005-11-15 22:16:05 +00004111void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
4112{
4113 VLANState *vlan = vc1->vlan;
4114 VLANClientState *vc;
4115
4116#if 0
4117 printf("vlan %d send:\n", vlan->id);
4118 hex_dump(stdout, buf, size);
4119#endif
4120 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
4121 if (vc != vc1) {
4122 vc->fd_read(vc->opaque, buf, size);
4123 }
4124 }
4125}
4126
4127#if defined(CONFIG_SLIRP)
4128
4129/* slirp network adapter */
4130
4131static int slirp_inited;
4132static VLANClientState *slirp_vc;
4133
4134int slirp_can_output(void)
4135{
pbrook3b7f5d42006-02-10 17:34:02 +00004136 return !slirp_vc || qemu_can_send_packet(slirp_vc);
bellard7c9d8e02005-11-15 22:16:05 +00004137}
4138
4139void slirp_output(const uint8_t *pkt, int pkt_len)
4140{
4141#if 0
4142 printf("slirp output:\n");
4143 hex_dump(stdout, pkt, pkt_len);
4144#endif
pbrook3b7f5d42006-02-10 17:34:02 +00004145 if (!slirp_vc)
4146 return;
bellard7c9d8e02005-11-15 22:16:05 +00004147 qemu_send_packet(slirp_vc, pkt, pkt_len);
4148}
4149
4150static void slirp_receive(void *opaque, const uint8_t *buf, int size)
4151{
4152#if 0
4153 printf("slirp input:\n");
4154 hex_dump(stdout, buf, size);
4155#endif
4156 slirp_input(buf, size);
4157}
4158
4159static int net_slirp_init(VLANState *vlan)
4160{
4161 if (!slirp_inited) {
4162 slirp_inited = 1;
4163 slirp_init();
4164 }
ths5fafdf22007-09-16 21:08:06 +00004165 slirp_vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00004166 slirp_receive, NULL, NULL);
bellard7c9d8e02005-11-15 22:16:05 +00004167 snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
4168 return 0;
4169}
4170
bellard9bf05442004-08-25 22:12:49 +00004171static void net_slirp_redir(const char *redir_str)
4172{
4173 int is_udp;
4174 char buf[256], *r;
4175 const char *p;
4176 struct in_addr guest_addr;
4177 int host_port, guest_port;
ths3b46e622007-09-17 08:09:54 +00004178
bellard9bf05442004-08-25 22:12:49 +00004179 if (!slirp_inited) {
4180 slirp_inited = 1;
4181 slirp_init();
4182 }
4183
4184 p = redir_str;
4185 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4186 goto fail;
4187 if (!strcmp(buf, "tcp")) {
4188 is_udp = 0;
4189 } else if (!strcmp(buf, "udp")) {
4190 is_udp = 1;
4191 } else {
4192 goto fail;
4193 }
4194
4195 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4196 goto fail;
4197 host_port = strtol(buf, &r, 0);
4198 if (r == buf)
4199 goto fail;
4200
4201 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
4202 goto fail;
4203 if (buf[0] == '\0') {
4204 pstrcpy(buf, sizeof(buf), "10.0.2.15");
4205 }
4206 if (!inet_aton(buf, &guest_addr))
4207 goto fail;
ths3b46e622007-09-17 08:09:54 +00004208
bellard9bf05442004-08-25 22:12:49 +00004209 guest_port = strtol(p, &r, 0);
4210 if (r == p)
4211 goto fail;
ths3b46e622007-09-17 08:09:54 +00004212
bellard9bf05442004-08-25 22:12:49 +00004213 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
4214 fprintf(stderr, "qemu: could not set up redirection\n");
4215 exit(1);
4216 }
4217 return;
4218 fail:
4219 fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
4220 exit(1);
4221}
ths3b46e622007-09-17 08:09:54 +00004222
bellardc94c8d62004-09-13 21:37:34 +00004223#ifndef _WIN32
4224
bellard9d728e82004-09-05 23:09:03 +00004225char smb_dir[1024];
4226
balrog044fae82008-01-14 03:11:16 +00004227static void erase_dir(char *dir_name)
bellard9d728e82004-09-05 23:09:03 +00004228{
4229 DIR *d;
4230 struct dirent *de;
4231 char filename[1024];
4232
4233 /* erase all the files in the directory */
balrog044fae82008-01-14 03:11:16 +00004234 if ((d = opendir(dir_name)) != 0) {
4235 for(;;) {
4236 de = readdir(d);
4237 if (!de)
4238 break;
4239 if (strcmp(de->d_name, ".") != 0 &&
4240 strcmp(de->d_name, "..") != 0) {
4241 snprintf(filename, sizeof(filename), "%s/%s",
4242 smb_dir, de->d_name);
4243 if (unlink(filename) != 0) /* is it a directory? */
4244 erase_dir(filename);
4245 }
bellard9d728e82004-09-05 23:09:03 +00004246 }
balrog044fae82008-01-14 03:11:16 +00004247 closedir(d);
4248 rmdir(dir_name);
bellard9d728e82004-09-05 23:09:03 +00004249 }
balrog044fae82008-01-14 03:11:16 +00004250}
4251
4252/* automatic user mode samba server configuration */
4253static void smb_exit(void)
4254{
4255 erase_dir(smb_dir);
bellard9d728e82004-09-05 23:09:03 +00004256}
4257
4258/* automatic user mode samba server configuration */
pbrook9596ebb2007-11-18 01:44:38 +00004259static void net_slirp_smb(const char *exported_dir)
bellard9d728e82004-09-05 23:09:03 +00004260{
4261 char smb_conf[1024];
4262 char smb_cmdline[1024];
4263 FILE *f;
4264
4265 if (!slirp_inited) {
4266 slirp_inited = 1;
4267 slirp_init();
4268 }
4269
4270 /* XXX: better tmp dir construction */
4271 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
4272 if (mkdir(smb_dir, 0700) < 0) {
4273 fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
4274 exit(1);
4275 }
4276 snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
ths3b46e622007-09-17 08:09:54 +00004277
bellard9d728e82004-09-05 23:09:03 +00004278 f = fopen(smb_conf, "w");
4279 if (!f) {
4280 fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
4281 exit(1);
4282 }
ths5fafdf22007-09-16 21:08:06 +00004283 fprintf(f,
bellard9d728e82004-09-05 23:09:03 +00004284 "[global]\n"
bellard157777e2005-03-01 21:28:45 +00004285 "private dir=%s\n"
4286 "smb ports=0\n"
4287 "socket address=127.0.0.1\n"
bellard9d728e82004-09-05 23:09:03 +00004288 "pid directory=%s\n"
4289 "lock directory=%s\n"
4290 "log file=%s/log.smbd\n"
4291 "smb passwd file=%s/smbpasswd\n"
bellard03ffbb62004-09-06 00:14:04 +00004292 "security = share\n"
bellard9d728e82004-09-05 23:09:03 +00004293 "[qemu]\n"
4294 "path=%s\n"
4295 "read only=no\n"
4296 "guest ok=yes\n",
4297 smb_dir,
4298 smb_dir,
4299 smb_dir,
4300 smb_dir,
bellard157777e2005-03-01 21:28:45 +00004301 smb_dir,
bellard9d728e82004-09-05 23:09:03 +00004302 exported_dir
4303 );
4304 fclose(f);
4305 atexit(smb_exit);
4306
pbrooka14d6c82006-12-23 15:37:33 +00004307 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
4308 SMBD_COMMAND, smb_conf);
ths3b46e622007-09-17 08:09:54 +00004309
bellard9d728e82004-09-05 23:09:03 +00004310 slirp_add_exec(0, smb_cmdline, 4, 139);
4311}
bellard9bf05442004-08-25 22:12:49 +00004312
bellardc94c8d62004-09-13 21:37:34 +00004313#endif /* !defined(_WIN32) */
blueswir131a60e22007-10-26 18:42:59 +00004314void do_info_slirp(void)
4315{
4316 slirp_stats();
4317}
bellardc94c8d62004-09-13 21:37:34 +00004318
bellardc20709a2004-04-21 23:27:19 +00004319#endif /* CONFIG_SLIRP */
4320
4321#if !defined(_WIN32)
bellard7c9d8e02005-11-15 22:16:05 +00004322
4323typedef struct TAPState {
4324 VLANClientState *vc;
4325 int fd;
thsb46a8902007-10-21 23:20:45 +00004326 char down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00004327} TAPState;
4328
4329static void tap_receive(void *opaque, const uint8_t *buf, int size)
4330{
4331 TAPState *s = opaque;
4332 int ret;
4333 for(;;) {
4334 ret = write(s->fd, buf, size);
4335 if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
4336 } else {
4337 break;
4338 }
4339 }
4340}
4341
4342static void tap_send(void *opaque)
4343{
4344 TAPState *s = opaque;
4345 uint8_t buf[4096];
4346 int size;
4347
thsd5d10bc2007-02-17 22:54:49 +00004348#ifdef __sun__
4349 struct strbuf sbuf;
4350 int f = 0;
4351 sbuf.maxlen = sizeof(buf);
4352 sbuf.buf = buf;
4353 size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
4354#else
bellard7c9d8e02005-11-15 22:16:05 +00004355 size = read(s->fd, buf, sizeof(buf));
thsd5d10bc2007-02-17 22:54:49 +00004356#endif
bellard7c9d8e02005-11-15 22:16:05 +00004357 if (size > 0) {
4358 qemu_send_packet(s->vc, buf, size);
4359 }
4360}
4361
4362/* fd support */
4363
4364static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
4365{
4366 TAPState *s;
4367
4368 s = qemu_mallocz(sizeof(TAPState));
4369 if (!s)
4370 return NULL;
4371 s->fd = fd;
pbrookd861b052006-02-04 22:15:28 +00004372 s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004373 qemu_set_fd_handler(s->fd, tap_send, NULL, s);
4374 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
4375 return s;
4376}
4377
ths5c40d2b2007-06-23 16:03:36 +00004378#if defined (_BSD) || defined (__FreeBSD_kernel__)
bellard7c9d8e02005-11-15 22:16:05 +00004379static int tap_open(char *ifname, int ifname_size)
bellard7d3505c2004-05-12 19:32:15 +00004380{
4381 int fd;
4382 char *dev;
4383 struct stat s;
bellard67b915a2004-03-31 23:37:16 +00004384
balrogaeb30be2007-07-02 15:03:13 +00004385 TFR(fd = open("/dev/tap", O_RDWR));
bellard7d3505c2004-05-12 19:32:15 +00004386 if (fd < 0) {
4387 fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
4388 return -1;
4389 }
4390
4391 fstat(fd, &s);
4392 dev = devname(s.st_rdev, S_IFCHR);
4393 pstrcpy(ifname, ifname_size, dev);
4394
4395 fcntl(fd, F_SETFL, O_NONBLOCK);
4396 return fd;
4397}
bellardec530c82006-04-25 22:36:06 +00004398#elif defined(__sun__)
thsd5d10bc2007-02-17 22:54:49 +00004399#define TUNNEWPPA (('T'<<16) | 0x0001)
ths5fafdf22007-09-16 21:08:06 +00004400/*
4401 * Allocate TAP device, returns opened fd.
thsd5d10bc2007-02-17 22:54:49 +00004402 * Stores dev name in the first arg(must be large enough).
ths3b46e622007-09-17 08:09:54 +00004403 */
blueswir1363a37d2008-08-21 17:58:08 +00004404int tap_alloc(char *dev, size_t dev_size)
thsd5d10bc2007-02-17 22:54:49 +00004405{
4406 int tap_fd, if_fd, ppa = -1;
4407 static int ip_fd = 0;
4408 char *ptr;
4409
4410 static int arp_fd = 0;
4411 int ip_muxid, arp_muxid;
4412 struct strioctl strioc_if, strioc_ppa;
4413 int link_type = I_PLINK;;
4414 struct lifreq ifr;
4415 char actual_name[32] = "";
4416
4417 memset(&ifr, 0x0, sizeof(ifr));
4418
4419 if( *dev ){
ths5fafdf22007-09-16 21:08:06 +00004420 ptr = dev;
4421 while( *ptr && !isdigit((int)*ptr) ) ptr++;
thsd5d10bc2007-02-17 22:54:49 +00004422 ppa = atoi(ptr);
4423 }
4424
4425 /* Check if IP device was opened */
4426 if( ip_fd )
4427 close(ip_fd);
4428
balrogaeb30be2007-07-02 15:03:13 +00004429 TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
4430 if (ip_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004431 syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
4432 return -1;
4433 }
4434
balrogaeb30be2007-07-02 15:03:13 +00004435 TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
4436 if (tap_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004437 syslog(LOG_ERR, "Can't open /dev/tap");
4438 return -1;
4439 }
4440
4441 /* Assign a new PPA and get its unit number. */
4442 strioc_ppa.ic_cmd = TUNNEWPPA;
4443 strioc_ppa.ic_timout = 0;
4444 strioc_ppa.ic_len = sizeof(ppa);
4445 strioc_ppa.ic_dp = (char *)&ppa;
4446 if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
4447 syslog (LOG_ERR, "Can't assign new interface");
4448
balrogaeb30be2007-07-02 15:03:13 +00004449 TFR(if_fd = open("/dev/tap", O_RDWR, 0));
4450 if (if_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004451 syslog(LOG_ERR, "Can't open /dev/tap (2)");
4452 return -1;
4453 }
4454 if(ioctl(if_fd, I_PUSH, "ip") < 0){
4455 syslog(LOG_ERR, "Can't push IP module");
4456 return -1;
4457 }
4458
4459 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
4460 syslog(LOG_ERR, "Can't get flags\n");
4461
4462 snprintf (actual_name, 32, "tap%d", ppa);
4463 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4464
4465 ifr.lifr_ppa = ppa;
4466 /* Assign ppa according to the unit number returned by tun device */
4467
4468 if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
4469 syslog (LOG_ERR, "Can't set PPA %d", ppa);
4470 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
4471 syslog (LOG_ERR, "Can't get flags\n");
4472 /* Push arp module to if_fd */
4473 if (ioctl (if_fd, I_PUSH, "arp") < 0)
4474 syslog (LOG_ERR, "Can't push ARP module (2)");
4475
4476 /* Push arp module to ip_fd */
4477 if (ioctl (ip_fd, I_POP, NULL) < 0)
4478 syslog (LOG_ERR, "I_POP failed\n");
4479 if (ioctl (ip_fd, I_PUSH, "arp") < 0)
4480 syslog (LOG_ERR, "Can't push ARP module (3)\n");
4481 /* Open arp_fd */
balrogaeb30be2007-07-02 15:03:13 +00004482 TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
4483 if (arp_fd < 0)
thsd5d10bc2007-02-17 22:54:49 +00004484 syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
4485
4486 /* Set ifname to arp */
4487 strioc_if.ic_cmd = SIOCSLIFNAME;
4488 strioc_if.ic_timout = 0;
4489 strioc_if.ic_len = sizeof(ifr);
4490 strioc_if.ic_dp = (char *)&ifr;
4491 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
4492 syslog (LOG_ERR, "Can't set ifname to arp\n");
4493 }
4494
4495 if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
4496 syslog(LOG_ERR, "Can't link TAP device to IP");
4497 return -1;
4498 }
4499
4500 if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
4501 syslog (LOG_ERR, "Can't link TAP device to ARP");
4502
4503 close (if_fd);
4504
4505 memset(&ifr, 0x0, sizeof(ifr));
4506 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4507 ifr.lifr_ip_muxid = ip_muxid;
4508 ifr.lifr_arp_muxid = arp_muxid;
4509
4510 if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
4511 {
4512 ioctl (ip_fd, I_PUNLINK , arp_muxid);
4513 ioctl (ip_fd, I_PUNLINK, ip_muxid);
4514 syslog (LOG_ERR, "Can't set multiplexor id");
4515 }
4516
blueswir1363a37d2008-08-21 17:58:08 +00004517 snprintf(dev, dev_size, "tap%d", ppa);
thsd5d10bc2007-02-17 22:54:49 +00004518 return tap_fd;
4519}
4520
bellardec530c82006-04-25 22:36:06 +00004521static int tap_open(char *ifname, int ifname_size)
4522{
thsd5d10bc2007-02-17 22:54:49 +00004523 char dev[10]="";
4524 int fd;
blueswir1363a37d2008-08-21 17:58:08 +00004525 if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){
thsd5d10bc2007-02-17 22:54:49 +00004526 fprintf(stderr, "Cannot allocate TAP device\n");
4527 return -1;
4528 }
4529 pstrcpy(ifname, ifname_size, dev);
4530 fcntl(fd, F_SETFL, O_NONBLOCK);
4531 return fd;
bellardec530c82006-04-25 22:36:06 +00004532}
bellard7d3505c2004-05-12 19:32:15 +00004533#else
bellard7c9d8e02005-11-15 22:16:05 +00004534static int tap_open(char *ifname, int ifname_size)
bellardf1510b22003-06-25 00:07:40 +00004535{
4536 struct ifreq ifr;
bellardc4b1fcc2004-03-14 21:44:30 +00004537 int fd, ret;
ths3b46e622007-09-17 08:09:54 +00004538
balrogaeb30be2007-07-02 15:03:13 +00004539 TFR(fd = open("/dev/net/tun", O_RDWR));
bellardf1510b22003-06-25 00:07:40 +00004540 if (fd < 0) {
4541 fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4542 return -1;
4543 }
4544 memset(&ifr, 0, sizeof(ifr));
4545 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
bellard7c9d8e02005-11-15 22:16:05 +00004546 if (ifname[0] != '\0')
4547 pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4548 else
4549 pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
bellardf1510b22003-06-25 00:07:40 +00004550 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4551 if (ret != 0) {
4552 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4553 close(fd);
4554 return -1;
4555 }
bellardc4b1fcc2004-03-14 21:44:30 +00004556 pstrcpy(ifname, ifname_size, ifr.ifr_name);
bellardf1510b22003-06-25 00:07:40 +00004557 fcntl(fd, F_SETFL, O_NONBLOCK);
bellardc4b1fcc2004-03-14 21:44:30 +00004558 return fd;
4559}
bellard7d3505c2004-05-12 19:32:15 +00004560#endif
bellardf1510b22003-06-25 00:07:40 +00004561
thsb46a8902007-10-21 23:20:45 +00004562static int launch_script(const char *setup_script, const char *ifname, int fd)
bellardc4b1fcc2004-03-14 21:44:30 +00004563{
thsb46a8902007-10-21 23:20:45 +00004564 int pid, status;
bellardc20709a2004-04-21 23:27:19 +00004565 char *args[3];
4566 char **parg;
4567
thsb46a8902007-10-21 23:20:45 +00004568 /* try to launch network script */
bellard7c9d8e02005-11-15 22:16:05 +00004569 pid = fork();
4570 if (pid >= 0) {
4571 if (pid == 0) {
ths50d3eea2007-03-19 16:36:43 +00004572 int open_max = sysconf (_SC_OPEN_MAX), i;
4573 for (i = 0; i < open_max; i++)
4574 if (i != STDIN_FILENO &&
4575 i != STDOUT_FILENO &&
4576 i != STDERR_FILENO &&
4577 i != fd)
4578 close(i);
4579
bellard7c9d8e02005-11-15 22:16:05 +00004580 parg = args;
4581 *parg++ = (char *)setup_script;
thsb46a8902007-10-21 23:20:45 +00004582 *parg++ = (char *)ifname;
bellard7c9d8e02005-11-15 22:16:05 +00004583 *parg++ = NULL;
4584 execv(setup_script, args);
bellard4a389402005-11-26 20:10:07 +00004585 _exit(1);
bellard7c9d8e02005-11-15 22:16:05 +00004586 }
4587 while (waitpid(pid, &status, 0) != pid);
4588 if (!WIFEXITED(status) ||
4589 WEXITSTATUS(status) != 0) {
4590 fprintf(stderr, "%s: could not launch network script\n",
4591 setup_script);
4592 return -1;
4593 }
bellardc20709a2004-04-21 23:27:19 +00004594 }
thsb46a8902007-10-21 23:20:45 +00004595 return 0;
4596}
4597
4598static int net_tap_init(VLANState *vlan, const char *ifname1,
4599 const char *setup_script, const char *down_script)
4600{
4601 TAPState *s;
4602 int fd;
4603 char ifname[128];
4604
4605 if (ifname1 != NULL)
4606 pstrcpy(ifname, sizeof(ifname), ifname1);
4607 else
4608 ifname[0] = '\0';
4609 TFR(fd = tap_open(ifname, sizeof(ifname)));
4610 if (fd < 0)
4611 return -1;
4612
4613 if (!setup_script || !strcmp(setup_script, "no"))
4614 setup_script = "";
4615 if (setup_script[0] != '\0') {
4616 if (launch_script(setup_script, ifname, fd))
4617 return -1;
bellardc20709a2004-04-21 23:27:19 +00004618 }
bellard7c9d8e02005-11-15 22:16:05 +00004619 s = net_tap_fd_init(vlan, fd);
4620 if (!s)
4621 return -1;
ths5fafdf22007-09-16 21:08:06 +00004622 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
bellard7c9d8e02005-11-15 22:16:05 +00004623 "tap: ifname=%s setup_script=%s", ifname, setup_script);
thsb46a8902007-10-21 23:20:45 +00004624 if (down_script && strcmp(down_script, "no"))
4625 snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
bellardc20709a2004-04-21 23:27:19 +00004626 return 0;
4627}
4628
bellardfd1dff42006-02-01 21:29:26 +00004629#endif /* !_WIN32 */
4630
ths8a16d272008-07-19 09:56:24 +00004631#if defined(CONFIG_VDE)
4632typedef struct VDEState {
4633 VLANClientState *vc;
4634 VDECONN *vde;
4635} VDEState;
4636
4637static void vde_to_qemu(void *opaque)
4638{
4639 VDEState *s = opaque;
4640 uint8_t buf[4096];
4641 int size;
4642
4643 size = vde_recv(s->vde, buf, sizeof(buf), 0);
4644 if (size > 0) {
4645 qemu_send_packet(s->vc, buf, size);
4646 }
4647}
4648
4649static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)
4650{
4651 VDEState *s = opaque;
4652 int ret;
4653 for(;;) {
4654 ret = vde_send(s->vde, buf, size, 0);
4655 if (ret < 0 && errno == EINTR) {
4656 } else {
4657 break;
4658 }
4659 }
4660}
4661
4662static int net_vde_init(VLANState *vlan, const char *sock, int port,
4663 const char *group, int mode)
4664{
4665 VDEState *s;
4666 char *init_group = strlen(group) ? (char *)group : NULL;
4667 char *init_sock = strlen(sock) ? (char *)sock : NULL;
4668
4669 struct vde_open_args args = {
4670 .port = port,
4671 .group = init_group,
4672 .mode = mode,
4673 };
4674
4675 s = qemu_mallocz(sizeof(VDEState));
4676 if (!s)
4677 return -1;
4678 s->vde = vde_open(init_sock, "QEMU", &args);
4679 if (!s->vde){
4680 free(s);
4681 return -1;
4682 }
4683 s->vc = qemu_new_vlan_client(vlan, vde_from_qemu, NULL, s);
4684 qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
4685 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "vde: sock=%s fd=%d",
4686 sock, vde_datafd(s->vde));
4687 return 0;
4688}
4689#endif
4690
bellard7c9d8e02005-11-15 22:16:05 +00004691/* network connection */
4692typedef struct NetSocketState {
4693 VLANClientState *vc;
4694 int fd;
4695 int state; /* 0 = getting length, 1 = getting data */
4696 int index;
4697 int packet_len;
4698 uint8_t buf[4096];
bellard3d830452005-12-18 16:36:49 +00004699 struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
bellard7c9d8e02005-11-15 22:16:05 +00004700} NetSocketState;
4701
4702typedef struct NetSocketListenState {
4703 VLANState *vlan;
4704 int fd;
4705} NetSocketListenState;
4706
4707/* XXX: we consider we can send the whole packet without blocking */
4708static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
bellardc20709a2004-04-21 23:27:19 +00004709{
bellard7c9d8e02005-11-15 22:16:05 +00004710 NetSocketState *s = opaque;
4711 uint32_t len;
4712 len = htonl(size);
4713
bellardfd1dff42006-02-01 21:29:26 +00004714 send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4715 send_all(s->fd, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00004716}
4717
bellard3d830452005-12-18 16:36:49 +00004718static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4719{
4720 NetSocketState *s = opaque;
ths5fafdf22007-09-16 21:08:06 +00004721 sendto(s->fd, buf, size, 0,
bellard3d830452005-12-18 16:36:49 +00004722 (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4723}
4724
bellard7c9d8e02005-11-15 22:16:05 +00004725static void net_socket_send(void *opaque)
4726{
4727 NetSocketState *s = opaque;
bellardfd1dff42006-02-01 21:29:26 +00004728 int l, size, err;
bellard7c9d8e02005-11-15 22:16:05 +00004729 uint8_t buf1[4096];
4730 const uint8_t *buf;
4731
bellardfd1dff42006-02-01 21:29:26 +00004732 size = recv(s->fd, buf1, sizeof(buf1), 0);
4733 if (size < 0) {
4734 err = socket_error();
ths5fafdf22007-09-16 21:08:06 +00004735 if (err != EWOULDBLOCK)
bellardfd1dff42006-02-01 21:29:26 +00004736 goto eoc;
4737 } else if (size == 0) {
bellard7c9d8e02005-11-15 22:16:05 +00004738 /* end of connection */
bellardfd1dff42006-02-01 21:29:26 +00004739 eoc:
bellard7c9d8e02005-11-15 22:16:05 +00004740 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
bellardfd1dff42006-02-01 21:29:26 +00004741 closesocket(s->fd);
bellard7c9d8e02005-11-15 22:16:05 +00004742 return;
4743 }
4744 buf = buf1;
4745 while (size > 0) {
4746 /* reassemble a packet from the network */
4747 switch(s->state) {
4748 case 0:
4749 l = 4 - s->index;
4750 if (l > size)
4751 l = size;
4752 memcpy(s->buf + s->index, buf, l);
4753 buf += l;
4754 size -= l;
4755 s->index += l;
4756 if (s->index == 4) {
4757 /* got length */
4758 s->packet_len = ntohl(*(uint32_t *)s->buf);
4759 s->index = 0;
4760 s->state = 1;
4761 }
4762 break;
4763 case 1:
4764 l = s->packet_len - s->index;
4765 if (l > size)
4766 l = size;
4767 memcpy(s->buf + s->index, buf, l);
4768 s->index += l;
4769 buf += l;
4770 size -= l;
4771 if (s->index >= s->packet_len) {
4772 qemu_send_packet(s->vc, s->buf, s->packet_len);
4773 s->index = 0;
4774 s->state = 0;
4775 }
4776 break;
4777 }
4778 }
4779}
4780
bellard3d830452005-12-18 16:36:49 +00004781static void net_socket_send_dgram(void *opaque)
4782{
4783 NetSocketState *s = opaque;
4784 int size;
4785
4786 size = recv(s->fd, s->buf, sizeof(s->buf), 0);
ths5fafdf22007-09-16 21:08:06 +00004787 if (size < 0)
bellard3d830452005-12-18 16:36:49 +00004788 return;
4789 if (size == 0) {
4790 /* end of connection */
4791 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4792 return;
4793 }
4794 qemu_send_packet(s->vc, s->buf, size);
4795}
4796
4797static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4798{
4799 struct ip_mreq imr;
4800 int fd;
4801 int val, ret;
4802 if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4803 fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
ths5fafdf22007-09-16 21:08:06 +00004804 inet_ntoa(mcastaddr->sin_addr),
bellardfd1dff42006-02-01 21:29:26 +00004805 (int)ntohl(mcastaddr->sin_addr.s_addr));
bellard3d830452005-12-18 16:36:49 +00004806 return -1;
4807
4808 }
4809 fd = socket(PF_INET, SOCK_DGRAM, 0);
4810 if (fd < 0) {
4811 perror("socket(PF_INET, SOCK_DGRAM)");
4812 return -1;
4813 }
4814
bellardfd1dff42006-02-01 21:29:26 +00004815 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004816 ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
bellardfd1dff42006-02-01 21:29:26 +00004817 (const char *)&val, sizeof(val));
4818 if (ret < 0) {
4819 perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4820 goto fail;
4821 }
4822
4823 ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4824 if (ret < 0) {
4825 perror("bind");
4826 goto fail;
4827 }
ths3b46e622007-09-17 08:09:54 +00004828
bellard3d830452005-12-18 16:36:49 +00004829 /* Add host to multicast group */
4830 imr.imr_multiaddr = mcastaddr->sin_addr;
4831 imr.imr_interface.s_addr = htonl(INADDR_ANY);
4832
ths5fafdf22007-09-16 21:08:06 +00004833 ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
bellardfd1dff42006-02-01 21:29:26 +00004834 (const char *)&imr, sizeof(struct ip_mreq));
bellard3d830452005-12-18 16:36:49 +00004835 if (ret < 0) {
4836 perror("setsockopt(IP_ADD_MEMBERSHIP)");
4837 goto fail;
4838 }
4839
4840 /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4841 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004842 ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
bellardfd1dff42006-02-01 21:29:26 +00004843 (const char *)&val, sizeof(val));
bellard3d830452005-12-18 16:36:49 +00004844 if (ret < 0) {
4845 perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4846 goto fail;
4847 }
4848
bellardfd1dff42006-02-01 21:29:26 +00004849 socket_set_nonblock(fd);
bellard3d830452005-12-18 16:36:49 +00004850 return fd;
4851fail:
ths5fafdf22007-09-16 21:08:06 +00004852 if (fd >= 0)
bellard0bab00f2006-06-25 14:49:44 +00004853 closesocket(fd);
bellard3d830452005-12-18 16:36:49 +00004854 return -1;
4855}
4856
ths5fafdf22007-09-16 21:08:06 +00004857static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004858 int is_connected)
4859{
4860 struct sockaddr_in saddr;
4861 int newfd;
4862 socklen_t saddr_len;
4863 NetSocketState *s;
4864
4865 /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
ths5fafdf22007-09-16 21:08:06 +00004866 * Because this may be "shared" socket from a "master" process, datagrams would be recv()
bellard3d830452005-12-18 16:36:49 +00004867 * by ONLY ONE process: we must "clone" this dgram socket --jjo
4868 */
4869
4870 if (is_connected) {
4871 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4872 /* must be bound */
4873 if (saddr.sin_addr.s_addr==0) {
4874 fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4875 fd);
4876 return NULL;
4877 }
4878 /* clone dgram socket */
4879 newfd = net_socket_mcast_create(&saddr);
4880 if (newfd < 0) {
4881 /* error already reported by net_socket_mcast_create() */
4882 close(fd);
4883 return NULL;
4884 }
4885 /* clone newfd to fd, close newfd */
4886 dup2(newfd, fd);
4887 close(newfd);
ths5fafdf22007-09-16 21:08:06 +00004888
bellard3d830452005-12-18 16:36:49 +00004889 } else {
4890 fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4891 fd, strerror(errno));
4892 return NULL;
4893 }
4894 }
4895
4896 s = qemu_mallocz(sizeof(NetSocketState));
4897 if (!s)
4898 return NULL;
4899 s->fd = fd;
4900
pbrookd861b052006-02-04 22:15:28 +00004901 s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
bellard3d830452005-12-18 16:36:49 +00004902 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4903
4904 /* mcast: save bound address as dst */
4905 if (is_connected) s->dgram_dst=saddr;
4906
4907 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004908 "socket: fd=%d (%s mcast=%s:%d)",
bellard3d830452005-12-18 16:36:49 +00004909 fd, is_connected? "cloned" : "",
4910 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4911 return s;
4912}
4913
bellard7c9d8e02005-11-15 22:16:05 +00004914static void net_socket_connect(void *opaque)
4915{
4916 NetSocketState *s = opaque;
4917 qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4918}
4919
ths5fafdf22007-09-16 21:08:06 +00004920static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
bellard7c9d8e02005-11-15 22:16:05 +00004921 int is_connected)
4922{
4923 NetSocketState *s;
4924 s = qemu_mallocz(sizeof(NetSocketState));
4925 if (!s)
4926 return NULL;
4927 s->fd = fd;
ths5fafdf22007-09-16 21:08:06 +00004928 s->vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00004929 net_socket_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004930 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4931 "socket: fd=%d", fd);
4932 if (is_connected) {
4933 net_socket_connect(s);
4934 } else {
4935 qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4936 }
4937 return s;
4938}
4939
ths5fafdf22007-09-16 21:08:06 +00004940static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004941 int is_connected)
4942{
4943 int so_type=-1, optlen=sizeof(so_type);
4944
ths69b34972007-12-17 03:15:52 +00004945 if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
4946 (socklen_t *)&optlen)< 0) {
ths931f03e2007-04-28 20:49:36 +00004947 fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
bellard3d830452005-12-18 16:36:49 +00004948 return NULL;
4949 }
4950 switch(so_type) {
4951 case SOCK_DGRAM:
4952 return net_socket_fd_init_dgram(vlan, fd, is_connected);
4953 case SOCK_STREAM:
4954 return net_socket_fd_init_stream(vlan, fd, is_connected);
4955 default:
4956 /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4957 fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4958 return net_socket_fd_init_stream(vlan, fd, is_connected);
4959 }
4960 return NULL;
4961}
4962
bellard7c9d8e02005-11-15 22:16:05 +00004963static void net_socket_accept(void *opaque)
4964{
ths3b46e622007-09-17 08:09:54 +00004965 NetSocketListenState *s = opaque;
bellard7c9d8e02005-11-15 22:16:05 +00004966 NetSocketState *s1;
4967 struct sockaddr_in saddr;
4968 socklen_t len;
4969 int fd;
4970
4971 for(;;) {
4972 len = sizeof(saddr);
4973 fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4974 if (fd < 0 && errno != EINTR) {
4975 return;
4976 } else if (fd >= 0) {
4977 break;
4978 }
4979 }
ths5fafdf22007-09-16 21:08:06 +00004980 s1 = net_socket_fd_init(s->vlan, fd, 1);
bellard7c9d8e02005-11-15 22:16:05 +00004981 if (!s1) {
bellard0bab00f2006-06-25 14:49:44 +00004982 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004983 } else {
4984 snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004985 "socket: connection from %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00004986 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4987 }
4988}
4989
4990static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4991{
4992 NetSocketListenState *s;
4993 int fd, val, ret;
4994 struct sockaddr_in saddr;
4995
4996 if (parse_host_port(&saddr, host_str) < 0)
4997 return -1;
ths3b46e622007-09-17 08:09:54 +00004998
bellard7c9d8e02005-11-15 22:16:05 +00004999 s = qemu_mallocz(sizeof(NetSocketListenState));
5000 if (!s)
5001 return -1;
5002
5003 fd = socket(PF_INET, SOCK_STREAM, 0);
5004 if (fd < 0) {
5005 perror("socket");
5006 return -1;
5007 }
bellardfd1dff42006-02-01 21:29:26 +00005008 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00005009
5010 /* allow fast reuse */
5011 val = 1;
bellardfd1dff42006-02-01 21:29:26 +00005012 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
ths3b46e622007-09-17 08:09:54 +00005013
bellard7c9d8e02005-11-15 22:16:05 +00005014 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
5015 if (ret < 0) {
5016 perror("bind");
5017 return -1;
5018 }
5019 ret = listen(fd, 0);
5020 if (ret < 0) {
5021 perror("listen");
5022 return -1;
5023 }
5024 s->vlan = vlan;
5025 s->fd = fd;
5026 qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
5027 return 0;
5028}
5029
5030static int net_socket_connect_init(VLANState *vlan, const char *host_str)
5031{
5032 NetSocketState *s;
bellardfd1dff42006-02-01 21:29:26 +00005033 int fd, connected, ret, err;
bellard7c9d8e02005-11-15 22:16:05 +00005034 struct sockaddr_in saddr;
5035
5036 if (parse_host_port(&saddr, host_str) < 0)
5037 return -1;
5038
5039 fd = socket(PF_INET, SOCK_STREAM, 0);
5040 if (fd < 0) {
5041 perror("socket");
5042 return -1;
5043 }
bellardfd1dff42006-02-01 21:29:26 +00005044 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00005045
5046 connected = 0;
5047 for(;;) {
5048 ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
5049 if (ret < 0) {
bellardfd1dff42006-02-01 21:29:26 +00005050 err = socket_error();
5051 if (err == EINTR || err == EWOULDBLOCK) {
5052 } else if (err == EINPROGRESS) {
bellard7c9d8e02005-11-15 22:16:05 +00005053 break;
thsf5b12262007-03-25 15:58:03 +00005054#ifdef _WIN32
5055 } else if (err == WSAEALREADY) {
5056 break;
5057#endif
bellard7c9d8e02005-11-15 22:16:05 +00005058 } else {
5059 perror("connect");
bellardfd1dff42006-02-01 21:29:26 +00005060 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00005061 return -1;
5062 }
5063 } else {
5064 connected = 1;
5065 break;
5066 }
5067 }
5068 s = net_socket_fd_init(vlan, fd, connected);
5069 if (!s)
5070 return -1;
5071 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00005072 "socket: connect to %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00005073 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
bellardc20709a2004-04-21 23:27:19 +00005074 return 0;
5075}
5076
bellard3d830452005-12-18 16:36:49 +00005077static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
5078{
5079 NetSocketState *s;
5080 int fd;
5081 struct sockaddr_in saddr;
5082
5083 if (parse_host_port(&saddr, host_str) < 0)
5084 return -1;
5085
5086
5087 fd = net_socket_mcast_create(&saddr);
5088 if (fd < 0)
5089 return -1;
5090
5091 s = net_socket_fd_init(vlan, fd, 0);
5092 if (!s)
5093 return -1;
5094
5095 s->dgram_dst = saddr;
ths3b46e622007-09-17 08:09:54 +00005096
bellard3d830452005-12-18 16:36:49 +00005097 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00005098 "socket: mcast=%s:%d",
bellard3d830452005-12-18 16:36:49 +00005099 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
5100 return 0;
5101
5102}
5103
balrog609497a2008-01-14 02:56:53 +00005104static const char *get_opt_name(char *buf, int buf_size, const char *p)
thse4bcb142007-12-02 04:51:10 +00005105{
5106 char *q;
thse4bcb142007-12-02 04:51:10 +00005107
balrog609497a2008-01-14 02:56:53 +00005108 q = buf;
5109 while (*p != '\0' && *p != '=') {
5110 if (q && (q - buf) < buf_size - 1)
5111 *q++ = *p;
5112 p++;
5113 }
5114 if (q)
5115 *q = '\0';
5116
5117 return p;
5118}
5119
5120static const char *get_opt_value(char *buf, int buf_size, const char *p)
5121{
5122 char *q;
5123
thse4bcb142007-12-02 04:51:10 +00005124 q = buf;
5125 while (*p != '\0') {
balrog609497a2008-01-14 02:56:53 +00005126 if (*p == ',') {
5127 if (*(p + 1) != ',')
thse4bcb142007-12-02 04:51:10 +00005128 break;
thse4bcb142007-12-02 04:51:10 +00005129 p++;
balrog609497a2008-01-14 02:56:53 +00005130 }
thse4bcb142007-12-02 04:51:10 +00005131 if (q && (q - buf) < buf_size - 1)
5132 *q++ = *p;
5133 p++;
5134 }
5135 if (q)
5136 *q = '\0';
5137
5138 return p;
5139}
5140
bellard7c9d8e02005-11-15 22:16:05 +00005141static int get_param_value(char *buf, int buf_size,
5142 const char *tag, const char *str)
5143{
5144 const char *p;
bellard7c9d8e02005-11-15 22:16:05 +00005145 char option[128];
5146
5147 p = str;
5148 for(;;) {
balrog609497a2008-01-14 02:56:53 +00005149 p = get_opt_name(option, sizeof(option), p);
bellard7c9d8e02005-11-15 22:16:05 +00005150 if (*p != '=')
5151 break;
5152 p++;
5153 if (!strcmp(tag, option)) {
balrog609497a2008-01-14 02:56:53 +00005154 (void)get_opt_value(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00005155 return strlen(buf);
bellard7c9d8e02005-11-15 22:16:05 +00005156 } else {
balrog609497a2008-01-14 02:56:53 +00005157 p = get_opt_value(NULL, 0, p);
bellard7c9d8e02005-11-15 22:16:05 +00005158 }
5159 if (*p != ',')
5160 break;
5161 p++;
5162 }
5163 return 0;
5164}
5165
thse4bcb142007-12-02 04:51:10 +00005166static int check_params(char *buf, int buf_size,
5167 char **params, const char *str)
5168{
5169 const char *p;
5170 int i;
5171
5172 p = str;
5173 for(;;) {
balrog609497a2008-01-14 02:56:53 +00005174 p = get_opt_name(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00005175 if (*p != '=')
5176 return -1;
5177 p++;
5178 for(i = 0; params[i] != NULL; i++)
5179 if (!strcmp(params[i], buf))
5180 break;
5181 if (params[i] == NULL)
5182 return -1;
balrog609497a2008-01-14 02:56:53 +00005183 p = get_opt_value(NULL, 0, p);
thse4bcb142007-12-02 04:51:10 +00005184 if (*p != ',')
5185 break;
5186 p++;
5187 }
5188 return 0;
5189}
5190
balrog9ad97e62008-07-29 13:16:31 +00005191static int net_client_init(const char *device, const char *p)
bellard7c9d8e02005-11-15 22:16:05 +00005192{
bellard7c9d8e02005-11-15 22:16:05 +00005193 char buf[1024];
5194 int vlan_id, ret;
5195 VLANState *vlan;
5196
bellard7c9d8e02005-11-15 22:16:05 +00005197 vlan_id = 0;
5198 if (get_param_value(buf, sizeof(buf), "vlan", p)) {
5199 vlan_id = strtol(buf, NULL, 0);
5200 }
5201 vlan = qemu_find_vlan(vlan_id);
5202 if (!vlan) {
5203 fprintf(stderr, "Could not create vlan %d\n", vlan_id);
5204 return -1;
5205 }
5206 if (!strcmp(device, "nic")) {
5207 NICInfo *nd;
5208 uint8_t *macaddr;
5209
5210 if (nb_nics >= MAX_NICS) {
5211 fprintf(stderr, "Too Many NICs\n");
5212 return -1;
5213 }
5214 nd = &nd_table[nb_nics];
5215 macaddr = nd->macaddr;
5216 macaddr[0] = 0x52;
5217 macaddr[1] = 0x54;
5218 macaddr[2] = 0x00;
5219 macaddr[3] = 0x12;
5220 macaddr[4] = 0x34;
5221 macaddr[5] = 0x56 + nb_nics;
5222
5223 if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
5224 if (parse_macaddr(macaddr, buf) < 0) {
5225 fprintf(stderr, "invalid syntax for ethernet address\n");
5226 return -1;
5227 }
5228 }
pbrooka41b2ff2006-02-05 04:14:41 +00005229 if (get_param_value(buf, sizeof(buf), "model", p)) {
5230 nd->model = strdup(buf);
5231 }
bellard7c9d8e02005-11-15 22:16:05 +00005232 nd->vlan = vlan;
5233 nb_nics++;
blueswir1833c7172007-05-27 19:36:43 +00005234 vlan->nb_guest_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005235 ret = 0;
5236 } else
5237 if (!strcmp(device, "none")) {
5238 /* does nothing. It is needed to signal that no network cards
5239 are wanted */
5240 ret = 0;
5241 } else
5242#ifdef CONFIG_SLIRP
5243 if (!strcmp(device, "user")) {
pbrook115defd2006-04-16 11:06:58 +00005244 if (get_param_value(buf, sizeof(buf), "hostname", p)) {
bellard3f423c92006-04-30 21:34:15 +00005245 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
pbrook115defd2006-04-16 11:06:58 +00005246 }
blueswir1833c7172007-05-27 19:36:43 +00005247 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005248 ret = net_slirp_init(vlan);
5249 } else
5250#endif
bellard7fb843f2006-02-01 23:06:55 +00005251#ifdef _WIN32
5252 if (!strcmp(device, "tap")) {
5253 char ifname[64];
5254 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
5255 fprintf(stderr, "tap: no interface name\n");
5256 return -1;
5257 }
blueswir1833c7172007-05-27 19:36:43 +00005258 vlan->nb_host_devs++;
bellard7fb843f2006-02-01 23:06:55 +00005259 ret = tap_win32_init(vlan, ifname);
5260 } else
5261#else
bellard7c9d8e02005-11-15 22:16:05 +00005262 if (!strcmp(device, "tap")) {
5263 char ifname[64];
thsb46a8902007-10-21 23:20:45 +00005264 char setup_script[1024], down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00005265 int fd;
pbrook4f010352007-05-28 02:29:59 +00005266 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005267 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
5268 fd = strtol(buf, NULL, 0);
pbrook64538cd2008-03-24 02:31:33 +00005269 fcntl(fd, F_SETFL, O_NONBLOCK);
bellard7c9d8e02005-11-15 22:16:05 +00005270 ret = -1;
5271 if (net_tap_fd_init(vlan, fd))
5272 ret = 0;
5273 } else {
bellardbf8c5342007-01-09 19:44:41 +00005274 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
5275 ifname[0] = '\0';
5276 }
bellard7c9d8e02005-11-15 22:16:05 +00005277 if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
5278 pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
5279 }
thsb46a8902007-10-21 23:20:45 +00005280 if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
5281 pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
5282 }
5283 ret = net_tap_init(vlan, ifname, setup_script, down_script);
bellard7c9d8e02005-11-15 22:16:05 +00005284 }
5285 } else
bellardfd1dff42006-02-01 21:29:26 +00005286#endif
bellard7c9d8e02005-11-15 22:16:05 +00005287 if (!strcmp(device, "socket")) {
5288 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
5289 int fd;
5290 fd = strtol(buf, NULL, 0);
5291 ret = -1;
5292 if (net_socket_fd_init(vlan, fd, 1))
5293 ret = 0;
5294 } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
5295 ret = net_socket_listen_init(vlan, buf);
5296 } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
5297 ret = net_socket_connect_init(vlan, buf);
bellard3d830452005-12-18 16:36:49 +00005298 } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
5299 ret = net_socket_mcast_init(vlan, buf);
bellard7c9d8e02005-11-15 22:16:05 +00005300 } else {
5301 fprintf(stderr, "Unknown socket options: %s\n", p);
5302 return -1;
5303 }
blueswir1833c7172007-05-27 19:36:43 +00005304 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005305 } else
ths8a16d272008-07-19 09:56:24 +00005306#ifdef CONFIG_VDE
5307 if (!strcmp(device, "vde")) {
5308 char vde_sock[1024], vde_group[512];
5309 int vde_port, vde_mode;
5310 vlan->nb_host_devs++;
5311 if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {
5312 vde_sock[0] = '\0';
5313 }
5314 if (get_param_value(buf, sizeof(buf), "port", p) > 0) {
5315 vde_port = strtol(buf, NULL, 10);
5316 } else {
5317 vde_port = 0;
5318 }
5319 if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {
5320 vde_group[0] = '\0';
5321 }
5322 if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {
5323 vde_mode = strtol(buf, NULL, 8);
5324 } else {
5325 vde_mode = 0700;
5326 }
5327 ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode);
5328 } else
5329#endif
bellard7c9d8e02005-11-15 22:16:05 +00005330 {
5331 fprintf(stderr, "Unknown network device: %s\n", device);
5332 return -1;
5333 }
5334 if (ret < 0) {
5335 fprintf(stderr, "Could not initialize device '%s'\n", device);
5336 }
ths3b46e622007-09-17 08:09:54 +00005337
bellard7c9d8e02005-11-15 22:16:05 +00005338 return ret;
5339}
5340
balrog9ad97e62008-07-29 13:16:31 +00005341static int net_client_parse(const char *str)
5342{
5343 const char *p;
5344 char *q;
5345 char device[64];
5346
5347 p = str;
5348 q = device;
5349 while (*p != '\0' && *p != ',') {
5350 if ((q - device) < sizeof(device) - 1)
5351 *q++ = *p;
5352 p++;
5353 }
5354 *q = '\0';
5355 if (*p == ',')
5356 p++;
5357
5358 return net_client_init(device, p);
5359}
5360
bellard7c9d8e02005-11-15 22:16:05 +00005361void do_info_network(void)
5362{
5363 VLANState *vlan;
5364 VLANClientState *vc;
5365
5366 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
5367 term_printf("VLAN %d devices:\n", vlan->id);
5368 for(vc = vlan->first_client; vc != NULL; vc = vc->next)
5369 term_printf(" %s\n", vc->info_str);
5370 }
5371}
ths42550fd2006-12-22 16:34:12 +00005372
balrog609497a2008-01-14 02:56:53 +00005373#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00005374#ifdef TARGET_PPC
5375#define CDROM_ALIAS "index=1,media=cdrom"
5376#else
5377#define CDROM_ALIAS "index=2,media=cdrom"
5378#endif
5379#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00005380#define PFLASH_ALIAS "if=pflash"
5381#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00005382#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00005383
balrog609497a2008-01-14 02:56:53 +00005384static int drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00005385{
5386 va_list ap;
5387
5388 if (nb_drives_opt >= MAX_DRIVES) {
5389 fprintf(stderr, "qemu: too many drives\n");
5390 exit(1);
5391 }
5392
balrog609497a2008-01-14 02:56:53 +00005393 drives_opt[nb_drives_opt].file = file;
thse4bcb142007-12-02 04:51:10 +00005394 va_start(ap, fmt);
balrog609497a2008-01-14 02:56:53 +00005395 vsnprintf(drives_opt[nb_drives_opt].opt,
5396 sizeof(drives_opt[0].opt), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00005397 va_end(ap);
5398
5399 return nb_drives_opt++;
5400}
5401
thsf60d39b2007-12-17 03:55:57 +00005402int drive_get_index(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00005403{
5404 int index;
5405
5406 /* seek interface, bus and unit */
5407
5408 for (index = 0; index < nb_drives; index++)
thsf60d39b2007-12-17 03:55:57 +00005409 if (drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005410 drives_table[index].bus == bus &&
5411 drives_table[index].unit == unit)
5412 return index;
5413
5414 return -1;
5415}
5416
thsf60d39b2007-12-17 03:55:57 +00005417int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00005418{
5419 int max_bus;
5420 int index;
5421
5422 max_bus = -1;
5423 for (index = 0; index < nb_drives; index++) {
thsf60d39b2007-12-17 03:55:57 +00005424 if(drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005425 drives_table[index].bus > max_bus)
5426 max_bus = drives_table[index].bus;
5427 }
5428 return max_bus;
5429}
5430
aurel32a1620fa2008-04-29 05:58:01 +00005431static void bdrv_format_print(void *opaque, const char *name)
5432{
5433 fprintf(stderr, " %s", name);
5434}
5435
balrog609497a2008-01-14 02:56:53 +00005436static int drive_init(struct drive_opt *arg, int snapshot,
5437 QEMUMachine *machine)
thse4bcb142007-12-02 04:51:10 +00005438{
5439 char buf[128];
5440 char file[1024];
balrogc8522bd2007-12-06 22:11:20 +00005441 char devname[128];
5442 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00005443 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00005444 enum { MEDIA_DISK, MEDIA_CDROM } media;
5445 int bus_id, unit_id;
5446 int cyls, heads, secs, translation;
5447 BlockDriverState *bdrv;
aurel321e72d3b2008-04-28 20:26:45 +00005448 BlockDriver *drv = NULL;
thse4bcb142007-12-02 04:51:10 +00005449 int max_devs;
5450 int index;
balrog33f00272007-12-24 14:33:24 +00005451 int cache;
5452 int bdrv_flags;
balrog609497a2008-01-14 02:56:53 +00005453 char *str = arg->opt;
thse4bcb142007-12-02 04:51:10 +00005454 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
balrog33f00272007-12-24 14:33:24 +00005455 "secs", "trans", "media", "snapshot", "file",
aurel321e72d3b2008-04-28 20:26:45 +00005456 "cache", "format", NULL };
thse4bcb142007-12-02 04:51:10 +00005457
5458 if (check_params(buf, sizeof(buf), params, str) < 0) {
balrogff993632008-02-10 13:21:25 +00005459 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
thse4bcb142007-12-02 04:51:10 +00005460 buf, str);
5461 return -1;
5462 }
5463
5464 file[0] = 0;
5465 cyls = heads = secs = 0;
5466 bus_id = 0;
5467 unit_id = -1;
5468 translation = BIOS_ATA_TRANSLATION_AUTO;
5469 index = -1;
balrog33f00272007-12-24 14:33:24 +00005470 cache = 1;
thse4bcb142007-12-02 04:51:10 +00005471
5472 if (!strcmp(machine->name, "realview") ||
5473 !strcmp(machine->name, "SS-5") ||
5474 !strcmp(machine->name, "SS-10") ||
5475 !strcmp(machine->name, "SS-600MP") ||
5476 !strcmp(machine->name, "versatilepb") ||
5477 !strcmp(machine->name, "versatileab")) {
thsf60d39b2007-12-17 03:55:57 +00005478 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005479 max_devs = MAX_SCSI_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00005480 pstrcpy(devname, sizeof(devname), "scsi");
thse4bcb142007-12-02 04:51:10 +00005481 } else {
thsf60d39b2007-12-17 03:55:57 +00005482 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005483 max_devs = MAX_IDE_DEVS;
blueswir1363a37d2008-08-21 17:58:08 +00005484 pstrcpy(devname, sizeof(devname), "ide");
thse4bcb142007-12-02 04:51:10 +00005485 }
5486 media = MEDIA_DISK;
5487
5488 /* extract parameters */
5489
5490 if (get_param_value(buf, sizeof(buf), "bus", str)) {
5491 bus_id = strtol(buf, NULL, 0);
5492 if (bus_id < 0) {
5493 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
5494 return -1;
5495 }
5496 }
5497
5498 if (get_param_value(buf, sizeof(buf), "unit", str)) {
5499 unit_id = strtol(buf, NULL, 0);
5500 if (unit_id < 0) {
5501 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
5502 return -1;
5503 }
5504 }
5505
5506 if (get_param_value(buf, sizeof(buf), "if", str)) {
bellardae45d362008-06-11 09:44:44 +00005507 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00005508 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00005509 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005510 max_devs = MAX_IDE_DEVS;
5511 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00005512 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005513 max_devs = MAX_SCSI_DEVS;
5514 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00005515 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00005516 max_devs = 0;
5517 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00005518 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00005519 max_devs = 0;
5520 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00005521 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00005522 max_devs = 0;
5523 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00005524 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00005525 max_devs = 0;
5526 } else {
5527 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
5528 return -1;
5529 }
5530 }
5531
5532 if (get_param_value(buf, sizeof(buf), "index", str)) {
5533 index = strtol(buf, NULL, 0);
5534 if (index < 0) {
5535 fprintf(stderr, "qemu: '%s' invalid index\n", str);
5536 return -1;
5537 }
5538 }
5539
5540 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
5541 cyls = strtol(buf, NULL, 0);
5542 }
5543
5544 if (get_param_value(buf, sizeof(buf), "heads", str)) {
5545 heads = strtol(buf, NULL, 0);
5546 }
5547
5548 if (get_param_value(buf, sizeof(buf), "secs", str)) {
5549 secs = strtol(buf, NULL, 0);
5550 }
5551
5552 if (cyls || heads || secs) {
5553 if (cyls < 1 || cyls > 16383) {
5554 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
5555 return -1;
5556 }
5557 if (heads < 1 || heads > 16) {
5558 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
5559 return -1;
5560 }
5561 if (secs < 1 || secs > 63) {
5562 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
5563 return -1;
5564 }
5565 }
5566
5567 if (get_param_value(buf, sizeof(buf), "trans", str)) {
5568 if (!cyls) {
5569 fprintf(stderr,
5570 "qemu: '%s' trans must be used with cyls,heads and secs\n",
5571 str);
5572 return -1;
5573 }
5574 if (!strcmp(buf, "none"))
5575 translation = BIOS_ATA_TRANSLATION_NONE;
5576 else if (!strcmp(buf, "lba"))
5577 translation = BIOS_ATA_TRANSLATION_LBA;
5578 else if (!strcmp(buf, "auto"))
5579 translation = BIOS_ATA_TRANSLATION_AUTO;
5580 else {
5581 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
5582 return -1;
5583 }
5584 }
5585
5586 if (get_param_value(buf, sizeof(buf), "media", str)) {
5587 if (!strcmp(buf, "disk")) {
5588 media = MEDIA_DISK;
5589 } else if (!strcmp(buf, "cdrom")) {
5590 if (cyls || secs || heads) {
5591 fprintf(stderr,
5592 "qemu: '%s' invalid physical CHS format\n", str);
5593 return -1;
5594 }
5595 media = MEDIA_CDROM;
5596 } else {
5597 fprintf(stderr, "qemu: '%s' invalid media\n", str);
5598 return -1;
5599 }
5600 }
5601
5602 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
5603 if (!strcmp(buf, "on"))
5604 snapshot = 1;
5605 else if (!strcmp(buf, "off"))
5606 snapshot = 0;
5607 else {
5608 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
5609 return -1;
5610 }
5611 }
5612
balrog33f00272007-12-24 14:33:24 +00005613 if (get_param_value(buf, sizeof(buf), "cache", str)) {
5614 if (!strcmp(buf, "off"))
5615 cache = 0;
5616 else if (!strcmp(buf, "on"))
5617 cache = 1;
5618 else {
5619 fprintf(stderr, "qemu: invalid cache option\n");
5620 return -1;
5621 }
5622 }
5623
aurel321e72d3b2008-04-28 20:26:45 +00005624 if (get_param_value(buf, sizeof(buf), "format", str)) {
aurel32a1620fa2008-04-29 05:58:01 +00005625 if (strcmp(buf, "?") == 0) {
5626 fprintf(stderr, "qemu: Supported formats:");
5627 bdrv_iterate_format(bdrv_format_print, NULL);
5628 fprintf(stderr, "\n");
5629 return -1;
5630 }
aurel321e72d3b2008-04-28 20:26:45 +00005631 drv = bdrv_find_format(buf);
5632 if (!drv) {
5633 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
5634 return -1;
5635 }
5636 }
5637
balrog609497a2008-01-14 02:56:53 +00005638 if (arg->file == NULL)
5639 get_param_value(file, sizeof(file), "file", str);
5640 else
5641 pstrcpy(file, sizeof(file), arg->file);
thse4bcb142007-12-02 04:51:10 +00005642
5643 /* compute bus and unit according index */
5644
5645 if (index != -1) {
5646 if (bus_id != 0 || unit_id != -1) {
5647 fprintf(stderr,
5648 "qemu: '%s' index cannot be used with bus and unit\n", str);
5649 return -1;
5650 }
5651 if (max_devs == 0)
5652 {
5653 unit_id = index;
5654 bus_id = 0;
5655 } else {
5656 unit_id = index % max_devs;
5657 bus_id = index / max_devs;
5658 }
5659 }
5660
5661 /* if user doesn't specify a unit_id,
5662 * try to find the first free
5663 */
5664
5665 if (unit_id == -1) {
5666 unit_id = 0;
thsf60d39b2007-12-17 03:55:57 +00005667 while (drive_get_index(type, bus_id, unit_id) != -1) {
thse4bcb142007-12-02 04:51:10 +00005668 unit_id++;
5669 if (max_devs && unit_id >= max_devs) {
5670 unit_id -= max_devs;
5671 bus_id++;
5672 }
5673 }
5674 }
5675
5676 /* check unit id */
5677
5678 if (max_devs && unit_id >= max_devs) {
5679 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
5680 str, unit_id, max_devs - 1);
5681 return -1;
5682 }
5683
5684 /*
5685 * ignore multiple definitions
5686 */
5687
thsf60d39b2007-12-17 03:55:57 +00005688 if (drive_get_index(type, bus_id, unit_id) != -1)
thse4bcb142007-12-02 04:51:10 +00005689 return 0;
5690
5691 /* init */
5692
thsf60d39b2007-12-17 03:55:57 +00005693 if (type == IF_IDE || type == IF_SCSI)
balrogc8522bd2007-12-06 22:11:20 +00005694 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
balroge6198a72007-12-24 13:58:47 +00005695 if (max_devs)
5696 snprintf(buf, sizeof(buf), "%s%i%s%i",
5697 devname, bus_id, mediastr, unit_id);
5698 else
5699 snprintf(buf, sizeof(buf), "%s%s%i",
5700 devname, mediastr, unit_id);
thse4bcb142007-12-02 04:51:10 +00005701 bdrv = bdrv_new(buf);
5702 drives_table[nb_drives].bdrv = bdrv;
thsf60d39b2007-12-17 03:55:57 +00005703 drives_table[nb_drives].type = type;
thse4bcb142007-12-02 04:51:10 +00005704 drives_table[nb_drives].bus = bus_id;
5705 drives_table[nb_drives].unit = unit_id;
5706 nb_drives++;
5707
thsf60d39b2007-12-17 03:55:57 +00005708 switch(type) {
thse4bcb142007-12-02 04:51:10 +00005709 case IF_IDE:
5710 case IF_SCSI:
5711 switch(media) {
5712 case MEDIA_DISK:
5713 if (cyls != 0) {
5714 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
5715 bdrv_set_translation_hint(bdrv, translation);
5716 }
5717 break;
5718 case MEDIA_CDROM:
5719 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
5720 break;
5721 }
5722 break;
5723 case IF_SD:
5724 /* FIXME: This isn't really a floppy, but it's a reasonable
5725 approximation. */
5726 case IF_FLOPPY:
5727 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
5728 break;
5729 case IF_PFLASH:
5730 case IF_MTD:
5731 break;
5732 }
5733 if (!file[0])
5734 return 0;
balrog33f00272007-12-24 14:33:24 +00005735 bdrv_flags = 0;
5736 if (snapshot)
5737 bdrv_flags |= BDRV_O_SNAPSHOT;
5738 if (!cache)
5739 bdrv_flags |= BDRV_O_DIRECT;
aliguori83ab7952008-08-19 14:44:22 +00005740 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
thse4bcb142007-12-02 04:51:10 +00005741 fprintf(stderr, "qemu: could not open disk image %s\n",
5742 file);
5743 return -1;
5744 }
5745 return 0;
5746}
5747
bellard330d0412003-07-26 18:11:40 +00005748/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00005749/* USB devices */
5750
pbrook0d92ed32006-05-21 16:30:15 +00005751static USBPort *used_usb_ports;
5752static USBPort *free_usb_ports;
5753
5754/* ??? Maybe change this to register a hub to keep track of the topology. */
5755void qemu_register_usb_port(USBPort *port, void *opaque, int index,
5756 usb_attachfn attach)
5757{
5758 port->opaque = opaque;
5759 port->index = index;
5760 port->attach = attach;
5761 port->next = free_usb_ports;
5762 free_usb_ports = port;
5763}
5764
aliguori4b096fc2008-08-21 19:28:55 +00005765int usb_device_add_dev(USBDevice *dev)
5766{
5767 USBPort *port;
5768
5769 /* Find a USB port to add the device to. */
5770 port = free_usb_ports;
5771 if (!port->next) {
5772 USBDevice *hub;
5773
5774 /* Create a new hub and chain it on. */
5775 free_usb_ports = NULL;
5776 port->next = used_usb_ports;
5777 used_usb_ports = port;
5778
5779 hub = usb_hub_init(VM_USB_HUB_SIZE);
5780 usb_attach(port, hub);
5781 port = free_usb_ports;
5782 }
5783
5784 free_usb_ports = port->next;
5785 port->next = used_usb_ports;
5786 used_usb_ports = port;
5787 usb_attach(port, dev);
5788 return 0;
5789}
5790
bellarda594cfb2005-11-06 16:13:29 +00005791static int usb_device_add(const char *devname)
5792{
5793 const char *p;
5794 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00005795
pbrook0d92ed32006-05-21 16:30:15 +00005796 if (!free_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005797 return -1;
5798
5799 if (strstart(devname, "host:", &p)) {
5800 dev = usb_host_device_open(p);
bellarda594cfb2005-11-06 16:13:29 +00005801 } else if (!strcmp(devname, "mouse")) {
5802 dev = usb_mouse_init();
bellard09b26c52006-04-12 21:09:08 +00005803 } else if (!strcmp(devname, "tablet")) {
balrog47b2d332007-06-22 08:16:00 +00005804 dev = usb_tablet_init();
5805 } else if (!strcmp(devname, "keyboard")) {
5806 dev = usb_keyboard_init();
pbrook2e5d83b2006-05-25 23:58:51 +00005807 } else if (strstart(devname, "disk:", &p)) {
5808 dev = usb_msd_init(p);
balrogf6d2a312007-06-10 19:21:04 +00005809 } else if (!strcmp(devname, "wacom-tablet")) {
5810 dev = usb_wacom_init();
balroga7954212008-01-14 03:41:02 +00005811 } else if (strstart(devname, "serial:", &p)) {
5812 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00005813#ifdef CONFIG_BRLAPI
5814 } else if (!strcmp(devname, "braille")) {
5815 dev = usb_baum_init();
5816#endif
balrog6c9f8862008-07-17 20:47:13 +00005817 } else if (strstart(devname, "net:", &p)) {
balrog9ad97e62008-07-29 13:16:31 +00005818 int nic = nb_nics;
balrog6c9f8862008-07-17 20:47:13 +00005819
balrog9ad97e62008-07-29 13:16:31 +00005820 if (net_client_init("nic", p) < 0)
balrog6c9f8862008-07-17 20:47:13 +00005821 return -1;
balrog9ad97e62008-07-29 13:16:31 +00005822 nd_table[nic].model = "usb";
5823 dev = usb_net_init(&nd_table[nic]);
bellarda594cfb2005-11-06 16:13:29 +00005824 } else {
5825 return -1;
5826 }
pbrook0d92ed32006-05-21 16:30:15 +00005827 if (!dev)
5828 return -1;
5829
aliguori4b096fc2008-08-21 19:28:55 +00005830 return usb_device_add_dev(dev);
bellarda594cfb2005-11-06 16:13:29 +00005831}
5832
aliguori1f3870a2008-08-21 19:27:48 +00005833int usb_device_del_addr(int bus_num, int addr)
bellarda594cfb2005-11-06 16:13:29 +00005834{
pbrook0d92ed32006-05-21 16:30:15 +00005835 USBPort *port;
5836 USBPort **lastp;
bellard059809e2006-07-19 18:06:15 +00005837 USBDevice *dev;
bellarda594cfb2005-11-06 16:13:29 +00005838
pbrook0d92ed32006-05-21 16:30:15 +00005839 if (!used_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005840 return -1;
5841
bellarda594cfb2005-11-06 16:13:29 +00005842 if (bus_num != 0)
5843 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005844
5845 lastp = &used_usb_ports;
5846 port = used_usb_ports;
5847 while (port && port->dev->addr != addr) {
5848 lastp = &port->next;
5849 port = port->next;
bellarda594cfb2005-11-06 16:13:29 +00005850 }
pbrook0d92ed32006-05-21 16:30:15 +00005851
5852 if (!port)
bellarda594cfb2005-11-06 16:13:29 +00005853 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005854
bellard059809e2006-07-19 18:06:15 +00005855 dev = port->dev;
pbrook0d92ed32006-05-21 16:30:15 +00005856 *lastp = port->next;
5857 usb_attach(port, NULL);
bellard059809e2006-07-19 18:06:15 +00005858 dev->handle_destroy(dev);
pbrook0d92ed32006-05-21 16:30:15 +00005859 port->next = free_usb_ports;
5860 free_usb_ports = port;
bellarda594cfb2005-11-06 16:13:29 +00005861 return 0;
5862}
5863
aliguori1f3870a2008-08-21 19:27:48 +00005864static int usb_device_del(const char *devname)
5865{
5866 int bus_num, addr;
5867 const char *p;
5868
aliguori5d0c5752008-09-14 01:07:41 +00005869 if (strstart(devname, "host:", &p))
5870 return usb_host_device_close(p);
5871
aliguori1f3870a2008-08-21 19:27:48 +00005872 if (!used_usb_ports)
5873 return -1;
5874
5875 p = strchr(devname, '.');
5876 if (!p)
5877 return -1;
5878 bus_num = strtoul(devname, NULL, 0);
5879 addr = strtoul(p + 1, NULL, 0);
5880
5881 return usb_device_del_addr(bus_num, addr);
5882}
5883
bellarda594cfb2005-11-06 16:13:29 +00005884void do_usb_add(const char *devname)
5885{
aliguori4b096fc2008-08-21 19:28:55 +00005886 usb_device_add(devname);
bellarda594cfb2005-11-06 16:13:29 +00005887}
5888
5889void do_usb_del(const char *devname)
5890{
aliguori4b096fc2008-08-21 19:28:55 +00005891 usb_device_del(devname);
bellarda594cfb2005-11-06 16:13:29 +00005892}
5893
5894void usb_info(void)
5895{
5896 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00005897 USBPort *port;
bellarda594cfb2005-11-06 16:13:29 +00005898 const char *speed_str;
5899
pbrook0d92ed32006-05-21 16:30:15 +00005900 if (!usb_enabled) {
bellarda594cfb2005-11-06 16:13:29 +00005901 term_printf("USB support not enabled\n");
5902 return;
5903 }
5904
pbrook0d92ed32006-05-21 16:30:15 +00005905 for (port = used_usb_ports; port; port = port->next) {
5906 dev = port->dev;
5907 if (!dev)
5908 continue;
5909 switch(dev->speed) {
ths5fafdf22007-09-16 21:08:06 +00005910 case USB_SPEED_LOW:
5911 speed_str = "1.5";
pbrook0d92ed32006-05-21 16:30:15 +00005912 break;
ths5fafdf22007-09-16 21:08:06 +00005913 case USB_SPEED_FULL:
5914 speed_str = "12";
pbrook0d92ed32006-05-21 16:30:15 +00005915 break;
ths5fafdf22007-09-16 21:08:06 +00005916 case USB_SPEED_HIGH:
5917 speed_str = "480";
pbrook0d92ed32006-05-21 16:30:15 +00005918 break;
5919 default:
ths5fafdf22007-09-16 21:08:06 +00005920 speed_str = "?";
pbrook0d92ed32006-05-21 16:30:15 +00005921 break;
bellarda594cfb2005-11-06 16:13:29 +00005922 }
ths5fafdf22007-09-16 21:08:06 +00005923 term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
bellard1f6e24e2006-06-26 21:00:51 +00005924 0, dev->addr, speed_str, dev->devname);
bellarda594cfb2005-11-06 16:13:29 +00005925 }
5926}
5927
bellardf7cce892004-12-08 22:21:25 +00005928/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00005929/* PCMCIA/Cardbus */
5930
5931static struct pcmcia_socket_entry_s {
5932 struct pcmcia_socket_s *socket;
5933 struct pcmcia_socket_entry_s *next;
5934} *pcmcia_sockets = 0;
5935
5936void pcmcia_socket_register(struct pcmcia_socket_s *socket)
5937{
5938 struct pcmcia_socket_entry_s *entry;
5939
5940 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
5941 entry->socket = socket;
5942 entry->next = pcmcia_sockets;
5943 pcmcia_sockets = entry;
5944}
5945
5946void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
5947{
5948 struct pcmcia_socket_entry_s *entry, **ptr;
5949
5950 ptr = &pcmcia_sockets;
5951 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
5952 if (entry->socket == socket) {
5953 *ptr = entry->next;
5954 qemu_free(entry);
5955 }
5956}
5957
5958void pcmcia_info(void)
5959{
5960 struct pcmcia_socket_entry_s *iter;
5961 if (!pcmcia_sockets)
5962 term_printf("No PCMCIA sockets\n");
5963
5964 for (iter = pcmcia_sockets; iter; iter = iter->next)
5965 term_printf("%s: %s\n", iter->socket->slot_string,
5966 iter->socket->attached ? iter->socket->card_string :
5967 "Empty");
5968}
5969
5970/***********************************************************/
ths2ff89792007-06-21 23:34:19 +00005971/* dumb display */
5972
5973static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
5974{
5975}
5976
5977static void dumb_resize(DisplayState *ds, int w, int h)
5978{
5979}
5980
5981static void dumb_refresh(DisplayState *ds)
5982{
5983#if defined(CONFIG_SDL)
5984 vga_hw_update();
5985#endif
5986}
5987
5988static void dumb_display_init(DisplayState *ds)
5989{
5990 ds->data = NULL;
5991 ds->linesize = 0;
5992 ds->depth = 0;
5993 ds->dpy_update = dumb_update;
5994 ds->dpy_resize = dumb_resize;
5995 ds->dpy_refresh = dumb_refresh;
aliguoribcfad702008-08-21 20:08:55 +00005996 ds->gui_timer_interval = 500;
5997 ds->idle = 1;
ths2ff89792007-06-21 23:34:19 +00005998}
5999
6000/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006001/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00006002
bellardc4b1fcc2004-03-14 21:44:30 +00006003#define MAX_IO_HANDLERS 64
6004
6005typedef struct IOHandlerRecord {
6006 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00006007 IOCanRWHandler *fd_read_poll;
6008 IOHandler *fd_read;
6009 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00006010 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00006011 void *opaque;
6012 /* temporary data */
6013 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00006014 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00006015} IOHandlerRecord;
6016
bellard8a7ddc32004-03-31 19:00:16 +00006017static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00006018
bellard7c9d8e02005-11-15 22:16:05 +00006019/* XXX: fd_read_poll should be suppressed, but an API change is
6020 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00006021int qemu_set_fd_handler2(int fd,
6022 IOCanRWHandler *fd_read_poll,
6023 IOHandler *fd_read,
6024 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00006025 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00006026{
bellard8a7ddc32004-03-31 19:00:16 +00006027 IOHandlerRecord **pioh, *ioh;
6028
bellard7c9d8e02005-11-15 22:16:05 +00006029 if (!fd_read && !fd_write) {
6030 pioh = &first_io_handler;
6031 for(;;) {
6032 ioh = *pioh;
6033 if (ioh == NULL)
6034 break;
6035 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00006036 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00006037 break;
6038 }
6039 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00006040 }
bellard7c9d8e02005-11-15 22:16:05 +00006041 } else {
6042 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6043 if (ioh->fd == fd)
6044 goto found;
6045 }
6046 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
6047 if (!ioh)
6048 return -1;
6049 ioh->next = first_io_handler;
6050 first_io_handler = ioh;
6051 found:
6052 ioh->fd = fd;
6053 ioh->fd_read_poll = fd_read_poll;
6054 ioh->fd_read = fd_read;
6055 ioh->fd_write = fd_write;
6056 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00006057 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00006058 }
bellard7c9d8e02005-11-15 22:16:05 +00006059 return 0;
6060}
6061
ths5fafdf22007-09-16 21:08:06 +00006062int qemu_set_fd_handler(int fd,
6063 IOHandler *fd_read,
6064 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00006065 void *opaque)
6066{
6067 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00006068}
6069
bellard8a7ddc32004-03-31 19:00:16 +00006070/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00006071/* Polling handling */
6072
6073typedef struct PollingEntry {
6074 PollingFunc *func;
6075 void *opaque;
6076 struct PollingEntry *next;
6077} PollingEntry;
6078
6079static PollingEntry *first_polling_entry;
6080
6081int qemu_add_polling_cb(PollingFunc *func, void *opaque)
6082{
6083 PollingEntry **ppe, *pe;
6084 pe = qemu_mallocz(sizeof(PollingEntry));
6085 if (!pe)
6086 return -1;
6087 pe->func = func;
6088 pe->opaque = opaque;
6089 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
6090 *ppe = pe;
6091 return 0;
6092}
6093
6094void qemu_del_polling_cb(PollingFunc *func, void *opaque)
6095{
6096 PollingEntry **ppe, *pe;
6097 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
6098 pe = *ppe;
6099 if (pe->func == func && pe->opaque == opaque) {
6100 *ppe = pe->next;
6101 qemu_free(pe);
6102 break;
6103 }
6104 }
6105}
6106
bellarda18e5242006-06-25 17:18:27 +00006107#ifdef _WIN32
6108/***********************************************************/
6109/* Wait objects support */
6110typedef struct WaitObjects {
6111 int num;
6112 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
6113 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
6114 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
6115} WaitObjects;
6116
6117static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00006118
bellarda18e5242006-06-25 17:18:27 +00006119int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
6120{
6121 WaitObjects *w = &wait_objects;
6122
6123 if (w->num >= MAXIMUM_WAIT_OBJECTS)
6124 return -1;
6125 w->events[w->num] = handle;
6126 w->func[w->num] = func;
6127 w->opaque[w->num] = opaque;
6128 w->num++;
6129 return 0;
6130}
6131
6132void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
6133{
6134 int i, found;
6135 WaitObjects *w = &wait_objects;
6136
6137 found = 0;
6138 for (i = 0; i < w->num; i++) {
6139 if (w->events[i] == handle)
6140 found = 1;
6141 if (found) {
6142 w->events[i] = w->events[i + 1];
6143 w->func[i] = w->func[i + 1];
6144 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00006145 }
bellarda18e5242006-06-25 17:18:27 +00006146 }
6147 if (found)
6148 w->num--;
6149}
6150#endif
6151
bellardf3311102006-04-12 20:21:17 +00006152/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006153/* savevm/loadvm support */
bellardb4608c02003-06-27 17:34:32 +00006154
bellardfaea38e2006-08-05 21:31:00 +00006155#define IO_BUF_SIZE 32768
6156
6157struct QEMUFile {
6158 FILE *outfile;
6159 BlockDriverState *bs;
6160 int is_file;
6161 int is_writable;
6162 int64_t base_offset;
6163 int64_t buf_offset; /* start of buffer when writing, end of buffer
6164 when reading */
6165 int buf_index;
6166 int buf_size; /* 0 when writing */
6167 uint8_t buf[IO_BUF_SIZE];
6168};
6169
6170QEMUFile *qemu_fopen(const char *filename, const char *mode)
6171{
6172 QEMUFile *f;
6173
6174 f = qemu_mallocz(sizeof(QEMUFile));
6175 if (!f)
6176 return NULL;
6177 if (!strcmp(mode, "wb")) {
6178 f->is_writable = 1;
6179 } else if (!strcmp(mode, "rb")) {
6180 f->is_writable = 0;
6181 } else {
6182 goto fail;
6183 }
6184 f->outfile = fopen(filename, mode);
6185 if (!f->outfile)
6186 goto fail;
6187 f->is_file = 1;
6188 return f;
6189 fail:
6190 if (f->outfile)
6191 fclose(f->outfile);
6192 qemu_free(f);
6193 return NULL;
6194}
6195
pbrook9596ebb2007-11-18 01:44:38 +00006196static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
bellardfaea38e2006-08-05 21:31:00 +00006197{
6198 QEMUFile *f;
6199
6200 f = qemu_mallocz(sizeof(QEMUFile));
6201 if (!f)
6202 return NULL;
6203 f->is_file = 0;
6204 f->bs = bs;
6205 f->is_writable = is_writable;
6206 f->base_offset = offset;
6207 return f;
6208}
6209
6210void qemu_fflush(QEMUFile *f)
6211{
6212 if (!f->is_writable)
6213 return;
6214 if (f->buf_index > 0) {
6215 if (f->is_file) {
6216 fseek(f->outfile, f->buf_offset, SEEK_SET);
6217 fwrite(f->buf, 1, f->buf_index, f->outfile);
6218 } else {
ths5fafdf22007-09-16 21:08:06 +00006219 bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00006220 f->buf, f->buf_index);
6221 }
6222 f->buf_offset += f->buf_index;
6223 f->buf_index = 0;
6224 }
6225}
6226
6227static void qemu_fill_buffer(QEMUFile *f)
6228{
6229 int len;
6230
6231 if (f->is_writable)
6232 return;
6233 if (f->is_file) {
6234 fseek(f->outfile, f->buf_offset, SEEK_SET);
6235 len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
6236 if (len < 0)
6237 len = 0;
6238 } else {
ths5fafdf22007-09-16 21:08:06 +00006239 len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00006240 f->buf, IO_BUF_SIZE);
6241 if (len < 0)
6242 len = 0;
6243 }
6244 f->buf_index = 0;
6245 f->buf_size = len;
6246 f->buf_offset += len;
6247}
6248
6249void qemu_fclose(QEMUFile *f)
6250{
6251 if (f->is_writable)
6252 qemu_fflush(f);
6253 if (f->is_file) {
6254 fclose(f->outfile);
6255 }
6256 qemu_free(f);
6257}
6258
bellard8a7ddc32004-03-31 19:00:16 +00006259void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
6260{
bellardfaea38e2006-08-05 21:31:00 +00006261 int l;
6262 while (size > 0) {
6263 l = IO_BUF_SIZE - f->buf_index;
6264 if (l > size)
6265 l = size;
6266 memcpy(f->buf + f->buf_index, buf, l);
6267 f->buf_index += l;
6268 buf += l;
6269 size -= l;
6270 if (f->buf_index >= IO_BUF_SIZE)
6271 qemu_fflush(f);
6272 }
bellard8a7ddc32004-03-31 19:00:16 +00006273}
6274
6275void qemu_put_byte(QEMUFile *f, int v)
6276{
bellardfaea38e2006-08-05 21:31:00 +00006277 f->buf[f->buf_index++] = v;
6278 if (f->buf_index >= IO_BUF_SIZE)
6279 qemu_fflush(f);
6280}
6281
6282int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
6283{
6284 int size, l;
6285
6286 size = size1;
6287 while (size > 0) {
6288 l = f->buf_size - f->buf_index;
6289 if (l == 0) {
6290 qemu_fill_buffer(f);
6291 l = f->buf_size - f->buf_index;
6292 if (l == 0)
6293 break;
6294 }
6295 if (l > size)
6296 l = size;
6297 memcpy(buf, f->buf + f->buf_index, l);
6298 f->buf_index += l;
6299 buf += l;
6300 size -= l;
6301 }
6302 return size1 - size;
6303}
6304
6305int qemu_get_byte(QEMUFile *f)
6306{
6307 if (f->buf_index >= f->buf_size) {
6308 qemu_fill_buffer(f);
6309 if (f->buf_index >= f->buf_size)
6310 return 0;
6311 }
6312 return f->buf[f->buf_index++];
6313}
6314
6315int64_t qemu_ftell(QEMUFile *f)
6316{
6317 return f->buf_offset - f->buf_size + f->buf_index;
6318}
6319
6320int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
6321{
6322 if (whence == SEEK_SET) {
6323 /* nothing to do */
6324 } else if (whence == SEEK_CUR) {
6325 pos += qemu_ftell(f);
6326 } else {
6327 /* SEEK_END not supported */
6328 return -1;
6329 }
6330 if (f->is_writable) {
6331 qemu_fflush(f);
6332 f->buf_offset = pos;
6333 } else {
6334 f->buf_offset = pos;
6335 f->buf_index = 0;
6336 f->buf_size = 0;
6337 }
6338 return pos;
bellard8a7ddc32004-03-31 19:00:16 +00006339}
6340
6341void qemu_put_be16(QEMUFile *f, unsigned int v)
6342{
6343 qemu_put_byte(f, v >> 8);
6344 qemu_put_byte(f, v);
6345}
6346
6347void qemu_put_be32(QEMUFile *f, unsigned int v)
6348{
6349 qemu_put_byte(f, v >> 24);
6350 qemu_put_byte(f, v >> 16);
6351 qemu_put_byte(f, v >> 8);
6352 qemu_put_byte(f, v);
6353}
6354
6355void qemu_put_be64(QEMUFile *f, uint64_t v)
6356{
6357 qemu_put_be32(f, v >> 32);
6358 qemu_put_be32(f, v);
6359}
6360
bellard8a7ddc32004-03-31 19:00:16 +00006361unsigned int qemu_get_be16(QEMUFile *f)
6362{
6363 unsigned int v;
6364 v = qemu_get_byte(f) << 8;
6365 v |= qemu_get_byte(f);
6366 return v;
6367}
6368
6369unsigned int qemu_get_be32(QEMUFile *f)
6370{
6371 unsigned int v;
6372 v = qemu_get_byte(f) << 24;
6373 v |= qemu_get_byte(f) << 16;
6374 v |= qemu_get_byte(f) << 8;
6375 v |= qemu_get_byte(f);
6376 return v;
6377}
6378
6379uint64_t qemu_get_be64(QEMUFile *f)
6380{
6381 uint64_t v;
6382 v = (uint64_t)qemu_get_be32(f) << 32;
6383 v |= qemu_get_be32(f);
6384 return v;
6385}
6386
bellard8a7ddc32004-03-31 19:00:16 +00006387typedef struct SaveStateEntry {
6388 char idstr[256];
6389 int instance_id;
6390 int version_id;
6391 SaveStateHandler *save_state;
6392 LoadStateHandler *load_state;
6393 void *opaque;
6394 struct SaveStateEntry *next;
6395} SaveStateEntry;
6396
6397static SaveStateEntry *first_se;
6398
pbrook18be5182008-07-01 21:31:54 +00006399/* TODO: Individual devices generally have very little idea about the rest
ths18fdb1c2008-07-18 18:02:34 +00006400 of the system, so instance_id should be removed/replaced.
6401 Meanwhile pass -1 as instance_id if you do not already have a clearly
6402 distinguishing id for all instances of your device class. */
ths5fafdf22007-09-16 21:08:06 +00006403int register_savevm(const char *idstr,
6404 int instance_id,
bellard8a7ddc32004-03-31 19:00:16 +00006405 int version_id,
6406 SaveStateHandler *save_state,
6407 LoadStateHandler *load_state,
6408 void *opaque)
6409{
6410 SaveStateEntry *se, **pse;
6411
6412 se = qemu_malloc(sizeof(SaveStateEntry));
6413 if (!se)
6414 return -1;
6415 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
pbrook18be5182008-07-01 21:31:54 +00006416 se->instance_id = (instance_id == -1) ? 0 : instance_id;
bellard8a7ddc32004-03-31 19:00:16 +00006417 se->version_id = version_id;
6418 se->save_state = save_state;
6419 se->load_state = load_state;
6420 se->opaque = opaque;
6421 se->next = NULL;
6422
6423 /* add at the end of list */
6424 pse = &first_se;
pbrook18be5182008-07-01 21:31:54 +00006425 while (*pse != NULL) {
6426 if (instance_id == -1
6427 && strcmp(se->idstr, (*pse)->idstr) == 0
6428 && se->instance_id <= (*pse)->instance_id)
6429 se->instance_id = (*pse)->instance_id + 1;
bellard8a7ddc32004-03-31 19:00:16 +00006430 pse = &(*pse)->next;
pbrook18be5182008-07-01 21:31:54 +00006431 }
bellard8a7ddc32004-03-31 19:00:16 +00006432 *pse = se;
6433 return 0;
6434}
6435
6436#define QEMU_VM_FILE_MAGIC 0x5145564d
bellardfaea38e2006-08-05 21:31:00 +00006437#define QEMU_VM_FILE_VERSION 0x00000002
bellard8a7ddc32004-03-31 19:00:16 +00006438
pbrook9596ebb2007-11-18 01:44:38 +00006439static int qemu_savevm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006440{
6441 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006442 int len, ret;
6443 int64_t cur_pos, len_pos, total_len_pos;
bellard313aa562003-08-10 21:52:11 +00006444
bellard8a7ddc32004-03-31 19:00:16 +00006445 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
6446 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
bellardfaea38e2006-08-05 21:31:00 +00006447 total_len_pos = qemu_ftell(f);
6448 qemu_put_be64(f, 0); /* total size */
bellard8a7ddc32004-03-31 19:00:16 +00006449
6450 for(se = first_se; se != NULL; se = se->next) {
aurel32d978c022008-06-18 22:10:21 +00006451 if (se->save_state == NULL)
6452 /* this one has a loader only, for backwards compatibility */
6453 continue;
6454
bellard8a7ddc32004-03-31 19:00:16 +00006455 /* ID string */
6456 len = strlen(se->idstr);
6457 qemu_put_byte(f, len);
thsffe8ab82007-12-16 03:16:05 +00006458 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006459
6460 qemu_put_be32(f, se->instance_id);
6461 qemu_put_be32(f, se->version_id);
6462
6463 /* record size: filled later */
bellardfaea38e2006-08-05 21:31:00 +00006464 len_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006465 qemu_put_be32(f, 0);
bellard8a7ddc32004-03-31 19:00:16 +00006466 se->save_state(f, se->opaque);
6467
6468 /* fill record size */
bellardfaea38e2006-08-05 21:31:00 +00006469 cur_pos = qemu_ftell(f);
6470 len = cur_pos - len_pos - 4;
6471 qemu_fseek(f, len_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006472 qemu_put_be32(f, len);
bellardfaea38e2006-08-05 21:31:00 +00006473 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006474 }
bellardfaea38e2006-08-05 21:31:00 +00006475 cur_pos = qemu_ftell(f);
6476 qemu_fseek(f, total_len_pos, SEEK_SET);
6477 qemu_put_be64(f, cur_pos - total_len_pos - 8);
6478 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006479
bellard8a7ddc32004-03-31 19:00:16 +00006480 ret = 0;
bellard8a7ddc32004-03-31 19:00:16 +00006481 return ret;
6482}
6483
6484static SaveStateEntry *find_se(const char *idstr, int instance_id)
6485{
6486 SaveStateEntry *se;
6487
6488 for(se = first_se; se != NULL; se = se->next) {
ths5fafdf22007-09-16 21:08:06 +00006489 if (!strcmp(se->idstr, idstr) &&
bellard8a7ddc32004-03-31 19:00:16 +00006490 instance_id == se->instance_id)
6491 return se;
6492 }
6493 return NULL;
6494}
6495
pbrook9596ebb2007-11-18 01:44:38 +00006496static int qemu_loadvm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006497{
6498 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006499 int len, ret, instance_id, record_len, version_id;
6500 int64_t total_len, end_pos, cur_pos;
bellard8a7ddc32004-03-31 19:00:16 +00006501 unsigned int v;
6502 char idstr[256];
ths3b46e622007-09-17 08:09:54 +00006503
bellard8a7ddc32004-03-31 19:00:16 +00006504 v = qemu_get_be32(f);
6505 if (v != QEMU_VM_FILE_MAGIC)
6506 goto fail;
6507 v = qemu_get_be32(f);
6508 if (v != QEMU_VM_FILE_VERSION) {
6509 fail:
bellard8a7ddc32004-03-31 19:00:16 +00006510 ret = -1;
6511 goto the_end;
6512 }
bellardfaea38e2006-08-05 21:31:00 +00006513 total_len = qemu_get_be64(f);
6514 end_pos = total_len + qemu_ftell(f);
bellardb4608c02003-06-27 17:34:32 +00006515 for(;;) {
bellardfaea38e2006-08-05 21:31:00 +00006516 if (qemu_ftell(f) >= end_pos)
bellard8a7ddc32004-03-31 19:00:16 +00006517 break;
bellardfaea38e2006-08-05 21:31:00 +00006518 len = qemu_get_byte(f);
thsffe8ab82007-12-16 03:16:05 +00006519 qemu_get_buffer(f, (uint8_t *)idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006520 idstr[len] = '\0';
6521 instance_id = qemu_get_be32(f);
6522 version_id = qemu_get_be32(f);
6523 record_len = qemu_get_be32(f);
6524#if 0
ths5fafdf22007-09-16 21:08:06 +00006525 printf("idstr=%s instance=0x%x version=%d len=%d\n",
bellard8a7ddc32004-03-31 19:00:16 +00006526 idstr, instance_id, version_id, record_len);
bellardc45886d2004-01-05 00:02:06 +00006527#endif
bellardfaea38e2006-08-05 21:31:00 +00006528 cur_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006529 se = find_se(idstr, instance_id);
6530 if (!se) {
ths5fafdf22007-09-16 21:08:06 +00006531 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
bellard8a7ddc32004-03-31 19:00:16 +00006532 instance_id, idstr);
6533 } else {
6534 ret = se->load_state(f, se->opaque, version_id);
6535 if (ret < 0) {
ths5fafdf22007-09-16 21:08:06 +00006536 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
bellard8a7ddc32004-03-31 19:00:16 +00006537 instance_id, idstr);
6538 }
bellard34865132003-10-05 14:28:56 +00006539 }
bellard8a7ddc32004-03-31 19:00:16 +00006540 /* always seek to exact end of record */
6541 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
6542 }
bellard8a7ddc32004-03-31 19:00:16 +00006543 ret = 0;
6544 the_end:
bellardfaea38e2006-08-05 21:31:00 +00006545 return ret;
6546}
6547
6548/* device can contain snapshots */
6549static int bdrv_can_snapshot(BlockDriverState *bs)
6550{
6551 return (bs &&
6552 !bdrv_is_removable(bs) &&
6553 !bdrv_is_read_only(bs));
6554}
6555
6556/* device must be snapshots in order to have a reliable snapshot */
6557static int bdrv_has_snapshot(BlockDriverState *bs)
6558{
6559 return (bs &&
6560 !bdrv_is_removable(bs) &&
6561 !bdrv_is_read_only(bs));
6562}
6563
6564static BlockDriverState *get_bs_snapshots(void)
6565{
6566 BlockDriverState *bs;
6567 int i;
6568
6569 if (bs_snapshots)
6570 return bs_snapshots;
thse4bcb142007-12-02 04:51:10 +00006571 for(i = 0; i <= nb_drives; i++) {
6572 bs = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006573 if (bdrv_can_snapshot(bs))
6574 goto ok;
6575 }
6576 return NULL;
6577 ok:
6578 bs_snapshots = bs;
6579 return bs;
6580}
6581
6582static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
6583 const char *name)
6584{
6585 QEMUSnapshotInfo *sn_tab, *sn;
6586 int nb_sns, i, ret;
ths3b46e622007-09-17 08:09:54 +00006587
bellardfaea38e2006-08-05 21:31:00 +00006588 ret = -ENOENT;
6589 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6590 if (nb_sns < 0)
6591 return ret;
6592 for(i = 0; i < nb_sns; i++) {
6593 sn = &sn_tab[i];
6594 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
6595 *sn_info = *sn;
6596 ret = 0;
6597 break;
6598 }
6599 }
6600 qemu_free(sn_tab);
6601 return ret;
6602}
6603
6604void do_savevm(const char *name)
6605{
6606 BlockDriverState *bs, *bs1;
6607 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
6608 int must_delete, ret, i;
6609 BlockDriverInfo bdi1, *bdi = &bdi1;
6610 QEMUFile *f;
6611 int saved_vm_running;
bellard4c279bd2006-08-17 09:43:50 +00006612#ifdef _WIN32
6613 struct _timeb tb;
6614#else
bellardfaea38e2006-08-05 21:31:00 +00006615 struct timeval tv;
bellard4c279bd2006-08-17 09:43:50 +00006616#endif
bellardfaea38e2006-08-05 21:31:00 +00006617
6618 bs = get_bs_snapshots();
6619 if (!bs) {
6620 term_printf("No block device can accept snapshots\n");
6621 return;
6622 }
6623
pbrook6192bc32006-09-03 12:08:37 +00006624 /* ??? Should this occur after vm_stop? */
6625 qemu_aio_flush();
6626
bellardfaea38e2006-08-05 21:31:00 +00006627 saved_vm_running = vm_running;
6628 vm_stop(0);
ths3b46e622007-09-17 08:09:54 +00006629
bellardfaea38e2006-08-05 21:31:00 +00006630 must_delete = 0;
6631 if (name) {
6632 ret = bdrv_snapshot_find(bs, old_sn, name);
6633 if (ret >= 0) {
6634 must_delete = 1;
6635 }
6636 }
6637 memset(sn, 0, sizeof(*sn));
6638 if (must_delete) {
6639 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
6640 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
6641 } else {
6642 if (name)
6643 pstrcpy(sn->name, sizeof(sn->name), name);
6644 }
6645
6646 /* fill auxiliary fields */
bellard4c279bd2006-08-17 09:43:50 +00006647#ifdef _WIN32
6648 _ftime(&tb);
6649 sn->date_sec = tb.time;
6650 sn->date_nsec = tb.millitm * 1000000;
6651#else
bellardfaea38e2006-08-05 21:31:00 +00006652 gettimeofday(&tv, NULL);
6653 sn->date_sec = tv.tv_sec;
6654 sn->date_nsec = tv.tv_usec * 1000;
bellard4c279bd2006-08-17 09:43:50 +00006655#endif
bellardfaea38e2006-08-05 21:31:00 +00006656 sn->vm_clock_nsec = qemu_get_clock(vm_clock);
ths3b46e622007-09-17 08:09:54 +00006657
bellardfaea38e2006-08-05 21:31:00 +00006658 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6659 term_printf("Device %s does not support VM state snapshots\n",
6660 bdrv_get_device_name(bs));
6661 goto the_end;
6662 }
ths3b46e622007-09-17 08:09:54 +00006663
bellardfaea38e2006-08-05 21:31:00 +00006664 /* save the VM state */
6665 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
6666 if (!f) {
6667 term_printf("Could not open VM state file\n");
6668 goto the_end;
6669 }
6670 ret = qemu_savevm_state(f);
6671 sn->vm_state_size = qemu_ftell(f);
6672 qemu_fclose(f);
6673 if (ret < 0) {
6674 term_printf("Error %d while writing VM\n", ret);
6675 goto the_end;
6676 }
ths3b46e622007-09-17 08:09:54 +00006677
bellardfaea38e2006-08-05 21:31:00 +00006678 /* create the snapshots */
6679
thse4bcb142007-12-02 04:51:10 +00006680 for(i = 0; i < nb_drives; i++) {
6681 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006682 if (bdrv_has_snapshot(bs1)) {
6683 if (must_delete) {
6684 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
6685 if (ret < 0) {
6686 term_printf("Error while deleting snapshot on '%s'\n",
6687 bdrv_get_device_name(bs1));
6688 }
6689 }
6690 ret = bdrv_snapshot_create(bs1, sn);
6691 if (ret < 0) {
6692 term_printf("Error while creating snapshot on '%s'\n",
6693 bdrv_get_device_name(bs1));
6694 }
6695 }
6696 }
6697
6698 the_end:
bellard8a7ddc32004-03-31 19:00:16 +00006699 if (saved_vm_running)
6700 vm_start();
bellardfaea38e2006-08-05 21:31:00 +00006701}
6702
6703void do_loadvm(const char *name)
6704{
6705 BlockDriverState *bs, *bs1;
6706 BlockDriverInfo bdi1, *bdi = &bdi1;
6707 QEMUFile *f;
6708 int i, ret;
6709 int saved_vm_running;
6710
6711 bs = get_bs_snapshots();
6712 if (!bs) {
6713 term_printf("No block device supports snapshots\n");
6714 return;
6715 }
ths3b46e622007-09-17 08:09:54 +00006716
pbrook6192bc32006-09-03 12:08:37 +00006717 /* Flush all IO requests so they don't interfere with the new state. */
6718 qemu_aio_flush();
6719
bellardfaea38e2006-08-05 21:31:00 +00006720 saved_vm_running = vm_running;
6721 vm_stop(0);
6722
thse4bcb142007-12-02 04:51:10 +00006723 for(i = 0; i <= nb_drives; i++) {
6724 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006725 if (bdrv_has_snapshot(bs1)) {
6726 ret = bdrv_snapshot_goto(bs1, name);
6727 if (ret < 0) {
6728 if (bs != bs1)
6729 term_printf("Warning: ");
6730 switch(ret) {
6731 case -ENOTSUP:
6732 term_printf("Snapshots not supported on device '%s'\n",
6733 bdrv_get_device_name(bs1));
6734 break;
6735 case -ENOENT:
6736 term_printf("Could not find snapshot '%s' on device '%s'\n",
6737 name, bdrv_get_device_name(bs1));
6738 break;
6739 default:
6740 term_printf("Error %d while activating snapshot on '%s'\n",
6741 ret, bdrv_get_device_name(bs1));
6742 break;
6743 }
6744 /* fatal on snapshot block device */
6745 if (bs == bs1)
6746 goto the_end;
6747 }
6748 }
6749 }
6750
6751 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6752 term_printf("Device %s does not support VM state snapshots\n",
6753 bdrv_get_device_name(bs));
6754 return;
6755 }
ths3b46e622007-09-17 08:09:54 +00006756
bellardfaea38e2006-08-05 21:31:00 +00006757 /* restore the VM state */
6758 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
6759 if (!f) {
6760 term_printf("Could not open VM state file\n");
6761 goto the_end;
6762 }
6763 ret = qemu_loadvm_state(f);
6764 qemu_fclose(f);
6765 if (ret < 0) {
6766 term_printf("Error %d while loading VM state\n", ret);
6767 }
6768 the_end:
6769 if (saved_vm_running)
6770 vm_start();
6771}
6772
6773void do_delvm(const char *name)
6774{
6775 BlockDriverState *bs, *bs1;
6776 int i, ret;
6777
6778 bs = get_bs_snapshots();
6779 if (!bs) {
6780 term_printf("No block device supports snapshots\n");
6781 return;
6782 }
ths3b46e622007-09-17 08:09:54 +00006783
thse4bcb142007-12-02 04:51:10 +00006784 for(i = 0; i <= nb_drives; i++) {
6785 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006786 if (bdrv_has_snapshot(bs1)) {
6787 ret = bdrv_snapshot_delete(bs1, name);
6788 if (ret < 0) {
6789 if (ret == -ENOTSUP)
6790 term_printf("Snapshots not supported on device '%s'\n",
6791 bdrv_get_device_name(bs1));
6792 else
6793 term_printf("Error %d while deleting snapshot on '%s'\n",
6794 ret, bdrv_get_device_name(bs1));
6795 }
6796 }
6797 }
6798}
6799
6800void do_info_snapshots(void)
6801{
6802 BlockDriverState *bs, *bs1;
6803 QEMUSnapshotInfo *sn_tab, *sn;
6804 int nb_sns, i;
6805 char buf[256];
6806
6807 bs = get_bs_snapshots();
6808 if (!bs) {
6809 term_printf("No available block device supports snapshots\n");
6810 return;
6811 }
6812 term_printf("Snapshot devices:");
thse4bcb142007-12-02 04:51:10 +00006813 for(i = 0; i <= nb_drives; i++) {
6814 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006815 if (bdrv_has_snapshot(bs1)) {
6816 if (bs == bs1)
6817 term_printf(" %s", bdrv_get_device_name(bs1));
6818 }
6819 }
6820 term_printf("\n");
6821
6822 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6823 if (nb_sns < 0) {
6824 term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
6825 return;
6826 }
6827 term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
6828 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
6829 for(i = 0; i < nb_sns; i++) {
6830 sn = &sn_tab[i];
6831 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
6832 }
6833 qemu_free(sn_tab);
bellard8a7ddc32004-03-31 19:00:16 +00006834}
6835
6836/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006837/* ram save/restore */
6838
bellard8a7ddc32004-03-31 19:00:16 +00006839static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6840{
6841 int v;
6842
6843 v = qemu_get_byte(f);
6844 switch(v) {
6845 case 0:
6846 if (qemu_get_buffer(f, buf, len) != len)
6847 return -EIO;
6848 break;
6849 case 1:
6850 v = qemu_get_byte(f);
6851 memset(buf, v, len);
6852 break;
6853 default:
6854 return -EINVAL;
6855 }
6856 return 0;
6857}
6858
bellardc88676f2006-08-06 13:36:11 +00006859static int ram_load_v1(QEMUFile *f, void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00006860{
aurel3200f82b82008-04-27 21:12:55 +00006861 int ret;
6862 ram_addr_t i;
bellard8a7ddc32004-03-31 19:00:16 +00006863
bellard8a7ddc32004-03-31 19:00:16 +00006864 if (qemu_get_be32(f) != phys_ram_size)
6865 return -EINVAL;
6866 for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6867 ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6868 if (ret)
6869 return ret;
6870 }
6871 return 0;
6872}
6873
bellardc88676f2006-08-06 13:36:11 +00006874#define BDRV_HASH_BLOCK_SIZE 1024
6875#define IOBUF_SIZE 4096
6876#define RAM_CBLOCK_MAGIC 0xfabe
6877
6878typedef struct RamCompressState {
6879 z_stream zstream;
6880 QEMUFile *f;
6881 uint8_t buf[IOBUF_SIZE];
6882} RamCompressState;
6883
6884static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6885{
6886 int ret;
6887 memset(s, 0, sizeof(*s));
6888 s->f = f;
6889 ret = deflateInit2(&s->zstream, 1,
ths5fafdf22007-09-16 21:08:06 +00006890 Z_DEFLATED, 15,
bellardc88676f2006-08-06 13:36:11 +00006891 9, Z_DEFAULT_STRATEGY);
6892 if (ret != Z_OK)
6893 return -1;
6894 s->zstream.avail_out = IOBUF_SIZE;
6895 s->zstream.next_out = s->buf;
6896 return 0;
6897}
6898
6899static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6900{
6901 qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6902 qemu_put_be16(s->f, len);
6903 qemu_put_buffer(s->f, buf, len);
6904}
6905
6906static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6907{
6908 int ret;
6909
6910 s->zstream.avail_in = len;
6911 s->zstream.next_in = (uint8_t *)buf;
6912 while (s->zstream.avail_in > 0) {
6913 ret = deflate(&s->zstream, Z_NO_FLUSH);
6914 if (ret != Z_OK)
6915 return -1;
6916 if (s->zstream.avail_out == 0) {
6917 ram_put_cblock(s, s->buf, IOBUF_SIZE);
6918 s->zstream.avail_out = IOBUF_SIZE;
6919 s->zstream.next_out = s->buf;
6920 }
6921 }
6922 return 0;
6923}
6924
6925static void ram_compress_close(RamCompressState *s)
6926{
6927 int len, ret;
6928
6929 /* compress last bytes */
6930 for(;;) {
6931 ret = deflate(&s->zstream, Z_FINISH);
6932 if (ret == Z_OK || ret == Z_STREAM_END) {
6933 len = IOBUF_SIZE - s->zstream.avail_out;
6934 if (len > 0) {
6935 ram_put_cblock(s, s->buf, len);
6936 }
6937 s->zstream.avail_out = IOBUF_SIZE;
6938 s->zstream.next_out = s->buf;
6939 if (ret == Z_STREAM_END)
6940 break;
6941 } else {
6942 goto fail;
6943 }
6944 }
6945fail:
6946 deflateEnd(&s->zstream);
6947}
6948
6949typedef struct RamDecompressState {
6950 z_stream zstream;
6951 QEMUFile *f;
6952 uint8_t buf[IOBUF_SIZE];
6953} RamDecompressState;
6954
6955static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6956{
6957 int ret;
6958 memset(s, 0, sizeof(*s));
6959 s->f = f;
6960 ret = inflateInit(&s->zstream);
6961 if (ret != Z_OK)
6962 return -1;
6963 return 0;
6964}
6965
6966static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6967{
6968 int ret, clen;
6969
6970 s->zstream.avail_out = len;
6971 s->zstream.next_out = buf;
6972 while (s->zstream.avail_out > 0) {
6973 if (s->zstream.avail_in == 0) {
6974 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6975 return -1;
6976 clen = qemu_get_be16(s->f);
6977 if (clen > IOBUF_SIZE)
6978 return -1;
6979 qemu_get_buffer(s->f, s->buf, clen);
6980 s->zstream.avail_in = clen;
6981 s->zstream.next_in = s->buf;
6982 }
6983 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6984 if (ret != Z_OK && ret != Z_STREAM_END) {
6985 return -1;
6986 }
6987 }
6988 return 0;
6989}
6990
6991static void ram_decompress_close(RamDecompressState *s)
6992{
6993 inflateEnd(&s->zstream);
6994}
6995
6996static void ram_save(QEMUFile *f, void *opaque)
6997{
aurel3200f82b82008-04-27 21:12:55 +00006998 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00006999 RamCompressState s1, *s = &s1;
7000 uint8_t buf[10];
ths3b46e622007-09-17 08:09:54 +00007001
bellardc88676f2006-08-06 13:36:11 +00007002 qemu_put_be32(f, phys_ram_size);
7003 if (ram_compress_open(s, f) < 0)
7004 return;
7005 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
7006#if 0
7007 if (tight_savevm_enabled) {
7008 int64_t sector_num;
7009 int j;
7010
7011 /* find if the memory block is available on a virtual
7012 block device */
7013 sector_num = -1;
thse4bcb142007-12-02 04:51:10 +00007014 for(j = 0; j < nb_drives; j++) {
7015 sector_num = bdrv_hash_find(drives_table[j].bdrv,
7016 phys_ram_base + i,
7017 BDRV_HASH_BLOCK_SIZE);
7018 if (sector_num >= 0)
7019 break;
bellardc88676f2006-08-06 13:36:11 +00007020 }
thse4bcb142007-12-02 04:51:10 +00007021 if (j == nb_drives)
bellardc88676f2006-08-06 13:36:11 +00007022 goto normal_compress;
7023 buf[0] = 1;
7024 buf[1] = j;
7025 cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
7026 ram_compress_buf(s, buf, 10);
ths5fafdf22007-09-16 21:08:06 +00007027 } else
bellardc88676f2006-08-06 13:36:11 +00007028#endif
7029 {
7030 // normal_compress:
7031 buf[0] = 0;
7032 ram_compress_buf(s, buf, 1);
7033 ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
7034 }
7035 }
7036 ram_compress_close(s);
7037}
7038
7039static int ram_load(QEMUFile *f, void *opaque, int version_id)
7040{
7041 RamDecompressState s1, *s = &s1;
7042 uint8_t buf[10];
aurel3200f82b82008-04-27 21:12:55 +00007043 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00007044
7045 if (version_id == 1)
7046 return ram_load_v1(f, opaque);
7047 if (version_id != 2)
7048 return -EINVAL;
7049 if (qemu_get_be32(f) != phys_ram_size)
7050 return -EINVAL;
7051 if (ram_decompress_open(s, f) < 0)
7052 return -EINVAL;
7053 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
7054 if (ram_decompress_buf(s, buf, 1) < 0) {
7055 fprintf(stderr, "Error while reading ram block header\n");
7056 goto error;
7057 }
7058 if (buf[0] == 0) {
7059 if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
aurel3200f82b82008-04-27 21:12:55 +00007060 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
bellardc88676f2006-08-06 13:36:11 +00007061 goto error;
7062 }
ths5fafdf22007-09-16 21:08:06 +00007063 } else
bellardc88676f2006-08-06 13:36:11 +00007064#if 0
7065 if (buf[0] == 1) {
7066 int bs_index;
7067 int64_t sector_num;
7068
7069 ram_decompress_buf(s, buf + 1, 9);
7070 bs_index = buf[1];
7071 sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
thse4bcb142007-12-02 04:51:10 +00007072 if (bs_index >= nb_drives) {
bellardc88676f2006-08-06 13:36:11 +00007073 fprintf(stderr, "Invalid block device index %d\n", bs_index);
7074 goto error;
7075 }
thse4bcb142007-12-02 04:51:10 +00007076 if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
7077 phys_ram_base + i,
bellardc88676f2006-08-06 13:36:11 +00007078 BDRV_HASH_BLOCK_SIZE / 512) < 0) {
ths5fafdf22007-09-16 21:08:06 +00007079 fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
bellardc88676f2006-08-06 13:36:11 +00007080 bs_index, sector_num);
7081 goto error;
7082 }
ths5fafdf22007-09-16 21:08:06 +00007083 } else
bellardc88676f2006-08-06 13:36:11 +00007084#endif
7085 {
7086 error:
7087 printf("Error block header\n");
7088 return -EINVAL;
7089 }
7090 }
7091 ram_decompress_close(s);
7092 return 0;
7093}
7094
bellard8a7ddc32004-03-31 19:00:16 +00007095/***********************************************************/
bellard83f64092006-08-01 16:21:11 +00007096/* bottom halves (can be seen as timers which expire ASAP) */
7097
7098struct QEMUBH {
7099 QEMUBHFunc *cb;
7100 void *opaque;
7101 int scheduled;
7102 QEMUBH *next;
7103};
7104
7105static QEMUBH *first_bh = NULL;
7106
7107QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
7108{
7109 QEMUBH *bh;
7110 bh = qemu_mallocz(sizeof(QEMUBH));
7111 if (!bh)
7112 return NULL;
7113 bh->cb = cb;
7114 bh->opaque = opaque;
7115 return bh;
7116}
7117
bellard6eb57332006-08-06 09:51:25 +00007118int qemu_bh_poll(void)
bellard83f64092006-08-01 16:21:11 +00007119{
7120 QEMUBH *bh, **pbh;
bellard6eb57332006-08-06 09:51:25 +00007121 int ret;
bellard83f64092006-08-01 16:21:11 +00007122
bellard6eb57332006-08-06 09:51:25 +00007123 ret = 0;
bellard83f64092006-08-01 16:21:11 +00007124 for(;;) {
7125 pbh = &first_bh;
7126 bh = *pbh;
7127 if (!bh)
7128 break;
bellard6eb57332006-08-06 09:51:25 +00007129 ret = 1;
bellard83f64092006-08-01 16:21:11 +00007130 *pbh = bh->next;
7131 bh->scheduled = 0;
7132 bh->cb(bh->opaque);
7133 }
bellard6eb57332006-08-06 09:51:25 +00007134 return ret;
bellard83f64092006-08-01 16:21:11 +00007135}
7136
7137void qemu_bh_schedule(QEMUBH *bh)
7138{
7139 CPUState *env = cpu_single_env;
7140 if (bh->scheduled)
7141 return;
7142 bh->scheduled = 1;
7143 bh->next = first_bh;
7144 first_bh = bh;
7145
7146 /* stop the currently executing CPU to execute the BH ASAP */
7147 if (env) {
7148 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
7149 }
7150}
7151
7152void qemu_bh_cancel(QEMUBH *bh)
7153{
7154 QEMUBH **pbh;
7155 if (bh->scheduled) {
7156 pbh = &first_bh;
7157 while (*pbh != bh)
7158 pbh = &(*pbh)->next;
7159 *pbh = bh->next;
7160 bh->scheduled = 0;
7161 }
7162}
7163
7164void qemu_bh_delete(QEMUBH *bh)
7165{
7166 qemu_bh_cancel(bh);
7167 qemu_free(bh);
7168}
7169
7170/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00007171/* machine registration */
7172
7173QEMUMachine *first_machine = NULL;
7174
7175int qemu_register_machine(QEMUMachine *m)
7176{
7177 QEMUMachine **pm;
7178 pm = &first_machine;
7179 while (*pm != NULL)
7180 pm = &(*pm)->next;
7181 m->next = NULL;
7182 *pm = m;
7183 return 0;
7184}
7185
pbrook9596ebb2007-11-18 01:44:38 +00007186static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00007187{
7188 QEMUMachine *m;
7189
7190 for(m = first_machine; m != NULL; m = m->next) {
7191 if (!strcmp(m->name, name))
7192 return m;
7193 }
7194 return NULL;
7195}
7196
7197/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00007198/* main execution loop */
7199
pbrook9596ebb2007-11-18 01:44:38 +00007200static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00007201{
ths740733b2007-06-08 01:57:56 +00007202 DisplayState *ds = opaque;
7203 ds->dpy_refresh(ds);
aurel32f442e082008-03-13 19:20:33 +00007204 qemu_mod_timer(ds->gui_timer,
7205 (ds->gui_timer_interval ?
7206 ds->gui_timer_interval :
7207 GUI_REFRESH_INTERVAL)
7208 + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00007209}
7210
bellard0bd48852005-11-11 00:00:47 +00007211struct vm_change_state_entry {
7212 VMChangeStateHandler *cb;
7213 void *opaque;
7214 LIST_ENTRY (vm_change_state_entry) entries;
7215};
7216
7217static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
7218
7219VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
7220 void *opaque)
7221{
7222 VMChangeStateEntry *e;
7223
7224 e = qemu_mallocz(sizeof (*e));
7225 if (!e)
7226 return NULL;
7227
7228 e->cb = cb;
7229 e->opaque = opaque;
7230 LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
7231 return e;
7232}
7233
7234void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
7235{
7236 LIST_REMOVE (e, entries);
7237 qemu_free (e);
7238}
7239
7240static void vm_state_notify(int running)
7241{
7242 VMChangeStateEntry *e;
7243
7244 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
7245 e->cb(e->opaque, running);
7246 }
7247}
7248
bellard8a7ddc32004-03-31 19:00:16 +00007249/* XXX: support several handlers */
bellard0bd48852005-11-11 00:00:47 +00007250static VMStopHandler *vm_stop_cb;
7251static void *vm_stop_opaque;
bellard8a7ddc32004-03-31 19:00:16 +00007252
7253int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
7254{
7255 vm_stop_cb = cb;
7256 vm_stop_opaque = opaque;
7257 return 0;
7258}
7259
7260void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
7261{
7262 vm_stop_cb = NULL;
7263}
7264
7265void vm_start(void)
7266{
7267 if (!vm_running) {
7268 cpu_enable_ticks();
7269 vm_running = 1;
bellard0bd48852005-11-11 00:00:47 +00007270 vm_state_notify(1);
thsefe75412007-08-24 01:36:32 +00007271 qemu_rearm_alarm_timer(alarm_timer);
bellard8a7ddc32004-03-31 19:00:16 +00007272 }
7273}
7274
ths5fafdf22007-09-16 21:08:06 +00007275void vm_stop(int reason)
bellard8a7ddc32004-03-31 19:00:16 +00007276{
7277 if (vm_running) {
7278 cpu_disable_ticks();
7279 vm_running = 0;
7280 if (reason != 0) {
7281 if (vm_stop_cb) {
7282 vm_stop_cb(vm_stop_opaque, reason);
7283 }
7284 }
bellard0bd48852005-11-11 00:00:47 +00007285 vm_state_notify(0);
bellard8a7ddc32004-03-31 19:00:16 +00007286 }
7287}
7288
bellardbb0c6722004-06-20 12:37:32 +00007289/* reset/shutdown handler */
7290
7291typedef struct QEMUResetEntry {
7292 QEMUResetHandler *func;
7293 void *opaque;
7294 struct QEMUResetEntry *next;
7295} QEMUResetEntry;
7296
7297static QEMUResetEntry *first_reset_entry;
7298static int reset_requested;
7299static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00007300static int powerdown_requested;
bellardbb0c6722004-06-20 12:37:32 +00007301
aurel32cf7a2fe2008-03-18 06:53:05 +00007302int qemu_shutdown_requested(void)
7303{
7304 int r = shutdown_requested;
7305 shutdown_requested = 0;
7306 return r;
7307}
7308
7309int qemu_reset_requested(void)
7310{
7311 int r = reset_requested;
7312 reset_requested = 0;
7313 return r;
7314}
7315
7316int qemu_powerdown_requested(void)
7317{
7318 int r = powerdown_requested;
7319 powerdown_requested = 0;
7320 return r;
7321}
7322
bellardbb0c6722004-06-20 12:37:32 +00007323void qemu_register_reset(QEMUResetHandler *func, void *opaque)
7324{
7325 QEMUResetEntry **pre, *re;
7326
7327 pre = &first_reset_entry;
7328 while (*pre != NULL)
7329 pre = &(*pre)->next;
7330 re = qemu_mallocz(sizeof(QEMUResetEntry));
7331 re->func = func;
7332 re->opaque = opaque;
7333 re->next = NULL;
7334 *pre = re;
7335}
7336
aurel32cf7a2fe2008-03-18 06:53:05 +00007337void qemu_system_reset(void)
bellardbb0c6722004-06-20 12:37:32 +00007338{
7339 QEMUResetEntry *re;
7340
7341 /* reset all devices */
7342 for(re = first_reset_entry; re != NULL; re = re->next) {
7343 re->func(re->opaque);
7344 }
7345}
7346
7347void qemu_system_reset_request(void)
7348{
bellardd1beab82006-10-02 19:44:22 +00007349 if (no_reboot) {
7350 shutdown_requested = 1;
7351 } else {
7352 reset_requested = 1;
7353 }
bellard6a00d602005-11-21 23:25:50 +00007354 if (cpu_single_env)
7355 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007356}
7357
7358void qemu_system_shutdown_request(void)
7359{
7360 shutdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007361 if (cpu_single_env)
7362 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007363}
7364
bellard34751872005-07-02 14:31:34 +00007365void qemu_system_powerdown_request(void)
7366{
7367 powerdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007368 if (cpu_single_env)
7369 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007370}
7371
bellard5905b2e2004-08-01 21:53:26 +00007372void main_loop_wait(int timeout)
bellard8a7ddc32004-03-31 19:00:16 +00007373{
thscafffd42007-02-28 21:59:44 +00007374 IOHandlerRecord *ioh;
bellarde0356492006-05-01 13:33:02 +00007375 fd_set rfds, wfds, xfds;
ths877cf882007-04-18 18:11:47 +00007376 int ret, nfds;
7377#ifdef _WIN32
7378 int ret2, i;
7379#endif
bellardfd1dff42006-02-01 21:29:26 +00007380 struct timeval tv;
bellardf3311102006-04-12 20:21:17 +00007381 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00007382
bellardf3311102006-04-12 20:21:17 +00007383
7384 /* XXX: need to suppress polling by better using win32 events */
7385 ret = 0;
7386 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
7387 ret |= pe->func(pe->opaque);
7388 }
bellard38e205a2004-04-06 19:29:17 +00007389#ifdef _WIN32
thse6b1e552007-04-18 17:56:02 +00007390 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00007391 int err;
7392 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00007393
bellarda18e5242006-06-25 17:18:27 +00007394 ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
7395 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
7396 if (w->func[ret - WAIT_OBJECT_0])
7397 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00007398
ths5fafdf22007-09-16 21:08:06 +00007399 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00007400 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00007401
thse6b1e552007-04-18 17:56:02 +00007402 /* Check if event is signaled */
7403 ret2 = WaitForSingleObject(w->events[i], 0);
7404 if(ret2 == WAIT_OBJECT_0) {
7405 if (w->func[i])
7406 w->func[i](w->opaque[i]);
7407 } else if (ret2 == WAIT_TIMEOUT) {
7408 } else {
7409 err = GetLastError();
7410 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00007411 }
7412 }
bellarda18e5242006-06-25 17:18:27 +00007413 } else if (ret == WAIT_TIMEOUT) {
7414 } else {
7415 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00007416 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00007417 }
bellardf3311102006-04-12 20:21:17 +00007418 }
bellardfd1dff42006-02-01 21:29:26 +00007419#endif
7420 /* poll any events */
7421 /* XXX: separate device handlers from system ones */
7422 nfds = -1;
7423 FD_ZERO(&rfds);
7424 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00007425 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00007426 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00007427 if (ioh->deleted)
7428 continue;
bellardfd1dff42006-02-01 21:29:26 +00007429 if (ioh->fd_read &&
7430 (!ioh->fd_read_poll ||
7431 ioh->fd_read_poll(ioh->opaque) != 0)) {
7432 FD_SET(ioh->fd, &rfds);
7433 if (ioh->fd > nfds)
7434 nfds = ioh->fd;
7435 }
7436 if (ioh->fd_write) {
7437 FD_SET(ioh->fd, &wfds);
7438 if (ioh->fd > nfds)
7439 nfds = ioh->fd;
7440 }
7441 }
ths3b46e622007-09-17 08:09:54 +00007442
bellardfd1dff42006-02-01 21:29:26 +00007443 tv.tv_sec = 0;
7444#ifdef _WIN32
7445 tv.tv_usec = 0;
bellard38e205a2004-04-06 19:29:17 +00007446#else
bellardfd1dff42006-02-01 21:29:26 +00007447 tv.tv_usec = timeout * 1000;
7448#endif
bellarde0356492006-05-01 13:33:02 +00007449#if defined(CONFIG_SLIRP)
7450 if (slirp_inited) {
7451 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
7452 }
7453#endif
7454 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
bellardfd1dff42006-02-01 21:29:26 +00007455 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00007456 IOHandlerRecord **pioh;
7457
7458 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00007459 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007460 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00007461 }
ths6ab43fd2007-08-25 01:34:19 +00007462 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007463 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00007464 }
7465 }
thscafffd42007-02-28 21:59:44 +00007466
7467 /* remove deleted IO handlers */
7468 pioh = &first_io_handler;
7469 while (*pioh) {
7470 ioh = *pioh;
7471 if (ioh->deleted) {
7472 *pioh = ioh->next;
7473 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00007474 } else
thscafffd42007-02-28 21:59:44 +00007475 pioh = &ioh->next;
7476 }
bellardfd1dff42006-02-01 21:29:26 +00007477 }
bellarde0356492006-05-01 13:33:02 +00007478#if defined(CONFIG_SLIRP)
7479 if (slirp_inited) {
7480 if (ret < 0) {
7481 FD_ZERO(&rfds);
7482 FD_ZERO(&wfds);
7483 FD_ZERO(&xfds);
7484 }
7485 slirp_select_poll(&rfds, &wfds, &xfds);
7486 }
7487#endif
bellardc20709a2004-04-21 23:27:19 +00007488
bellardfd1dff42006-02-01 21:29:26 +00007489 if (vm_running) {
edgar_igl21b20812008-05-15 19:54:00 +00007490 if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
ths5fafdf22007-09-16 21:08:06 +00007491 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
bellardfd1dff42006-02-01 21:29:26 +00007492 qemu_get_clock(vm_clock));
7493 /* run dma transfers, if any */
7494 DMA_run();
7495 }
pbrook423f0742007-05-23 00:06:54 +00007496
bellardfd1dff42006-02-01 21:29:26 +00007497 /* real time timers */
ths5fafdf22007-09-16 21:08:06 +00007498 qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
bellardfd1dff42006-02-01 21:29:26 +00007499 qemu_get_clock(rt_clock));
pbrook423f0742007-05-23 00:06:54 +00007500
balrogd5d08332008-01-05 19:41:47 +00007501 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
7502 alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED);
7503 qemu_rearm_alarm_timer(alarm_timer);
7504 }
balrogb99dc0d2007-12-16 13:17:12 +00007505
pbrook423f0742007-05-23 00:06:54 +00007506 /* Check bottom-halves last in case any of the earlier events triggered
7507 them. */
7508 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00007509
bellard5905b2e2004-08-01 21:53:26 +00007510}
7511
pbrook9596ebb2007-11-18 01:44:38 +00007512static int main_loop(void)
bellard5905b2e2004-08-01 21:53:26 +00007513{
7514 int ret, timeout;
bellard89bfc102006-02-08 22:46:31 +00007515#ifdef CONFIG_PROFILER
7516 int64_t ti;
7517#endif
bellard6a00d602005-11-21 23:25:50 +00007518 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00007519
bellard6a00d602005-11-21 23:25:50 +00007520 cur_cpu = first_cpu;
balrogee5605e2007-12-03 03:01:40 +00007521 next_cpu = cur_cpu->next_cpu ?: first_cpu;
bellard5905b2e2004-08-01 21:53:26 +00007522 for(;;) {
7523 if (vm_running) {
bellard15a76442005-11-23 21:01:03 +00007524
bellard15a76442005-11-23 21:01:03 +00007525 for(;;) {
7526 /* get next cpu */
balrogee5605e2007-12-03 03:01:40 +00007527 env = next_cpu;
bellard89bfc102006-02-08 22:46:31 +00007528#ifdef CONFIG_PROFILER
7529 ti = profile_getclock();
7530#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007531 if (use_icount) {
7532 int64_t count;
7533 int decr;
7534 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
7535 env->icount_decr.u16.low = 0;
7536 env->icount_extra = 0;
7537 count = qemu_next_deadline();
7538 count = (count + (1 << icount_time_shift) - 1)
7539 >> icount_time_shift;
7540 qemu_icount += count;
7541 decr = (count > 0xffff) ? 0xffff : count;
7542 count -= decr;
7543 env->icount_decr.u16.low = decr;
7544 env->icount_extra = count;
7545 }
bellard6a00d602005-11-21 23:25:50 +00007546 ret = cpu_exec(env);
bellard89bfc102006-02-08 22:46:31 +00007547#ifdef CONFIG_PROFILER
7548 qemu_time += profile_getclock() - ti;
7549#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007550 if (use_icount) {
7551 /* Fold pending instructions back into the
7552 instruction counter, and clear the interrupt flag. */
7553 qemu_icount -= (env->icount_decr.u16.low
7554 + env->icount_extra);
7555 env->icount_decr.u32 = 0;
7556 env->icount_extra = 0;
7557 }
balrogee5605e2007-12-03 03:01:40 +00007558 next_cpu = env->next_cpu ?: first_cpu;
aurel3295b01002008-04-04 17:16:35 +00007559 if (event_pending && likely(ret != EXCP_DEBUG)) {
balrogee5605e2007-12-03 03:01:40 +00007560 ret = EXCP_INTERRUPT;
7561 event_pending = 0;
7562 break;
7563 }
pbrookbd967e02007-03-11 18:54:57 +00007564 if (ret == EXCP_HLT) {
7565 /* Give the next CPU a chance to run. */
7566 cur_cpu = env;
7567 continue;
7568 }
bellard15a76442005-11-23 21:01:03 +00007569 if (ret != EXCP_HALTED)
7570 break;
7571 /* all CPUs are halted ? */
pbrookbd967e02007-03-11 18:54:57 +00007572 if (env == cur_cpu)
bellard15a76442005-11-23 21:01:03 +00007573 break;
bellard15a76442005-11-23 21:01:03 +00007574 }
7575 cur_cpu = env;
7576
bellard5905b2e2004-08-01 21:53:26 +00007577 if (shutdown_requested) {
bellard34751872005-07-02 14:31:34 +00007578 ret = EXCP_INTERRUPT;
aurel32b2f76162008-04-11 21:35:52 +00007579 if (no_shutdown) {
7580 vm_stop(0);
7581 no_shutdown = 0;
7582 }
7583 else
7584 break;
bellard5905b2e2004-08-01 21:53:26 +00007585 }
7586 if (reset_requested) {
7587 reset_requested = 0;
7588 qemu_system_reset();
bellard34751872005-07-02 14:31:34 +00007589 ret = EXCP_INTERRUPT;
7590 }
7591 if (powerdown_requested) {
7592 powerdown_requested = 0;
7593 qemu_system_powerdown();
7594 ret = EXCP_INTERRUPT;
bellard5905b2e2004-08-01 21:53:26 +00007595 }
aurel3295b01002008-04-04 17:16:35 +00007596 if (unlikely(ret == EXCP_DEBUG)) {
bellard5905b2e2004-08-01 21:53:26 +00007597 vm_stop(EXCP_DEBUG);
7598 }
pbrookbd967e02007-03-11 18:54:57 +00007599 /* If all cpus are halted then wait until the next IRQ */
bellard5905b2e2004-08-01 21:53:26 +00007600 /* XXX: use timeout computed from timers */
pbrook2e70f6e2008-06-29 01:03:05 +00007601 if (ret == EXCP_HALTED) {
7602 if (use_icount) {
7603 int64_t add;
7604 int64_t delta;
7605 /* Advance virtual time to the next event. */
7606 if (use_icount == 1) {
7607 /* When not using an adaptive execution frequency
7608 we tend to get badly out of sync with real time,
thsbf20dc02008-06-30 17:22:19 +00007609 so just delay for a reasonable amount of time. */
pbrook2e70f6e2008-06-29 01:03:05 +00007610 delta = 0;
7611 } else {
7612 delta = cpu_get_icount() - cpu_get_clock();
7613 }
7614 if (delta > 0) {
7615 /* If virtual time is ahead of real time then just
7616 wait for IO. */
7617 timeout = (delta / 1000000) + 1;
7618 } else {
7619 /* Wait for either IO to occur or the next
7620 timer event. */
7621 add = qemu_next_deadline();
7622 /* We advance the timer before checking for IO.
7623 Limit the amount we advance so that early IO
7624 activity won't get the guest too far ahead. */
7625 if (add > 10000000)
7626 add = 10000000;
7627 delta += add;
7628 add = (add + (1 << icount_time_shift) - 1)
7629 >> icount_time_shift;
7630 qemu_icount += add;
7631 timeout = delta / 1000000;
7632 if (timeout < 0)
7633 timeout = 0;
7634 }
7635 } else {
7636 timeout = 10;
7637 }
7638 } else {
bellard5905b2e2004-08-01 21:53:26 +00007639 timeout = 0;
pbrook2e70f6e2008-06-29 01:03:05 +00007640 }
bellard5905b2e2004-08-01 21:53:26 +00007641 } else {
aliguori5b08fc12008-08-21 20:08:03 +00007642 if (shutdown_requested)
7643 break;
bellard5905b2e2004-08-01 21:53:26 +00007644 timeout = 10;
7645 }
bellard89bfc102006-02-08 22:46:31 +00007646#ifdef CONFIG_PROFILER
7647 ti = profile_getclock();
7648#endif
bellard5905b2e2004-08-01 21:53:26 +00007649 main_loop_wait(timeout);
bellard89bfc102006-02-08 22:46:31 +00007650#ifdef CONFIG_PROFILER
7651 dev_time += profile_getclock() - ti;
7652#endif
bellardb4608c02003-06-27 17:34:32 +00007653 }
bellard34865132003-10-05 14:28:56 +00007654 cpu_disable_ticks();
7655 return ret;
bellardb4608c02003-06-27 17:34:32 +00007656}
7657
ths15f82202007-06-29 23:26:08 +00007658static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00007659{
bellard68d0f702008-01-06 17:21:48 +00007660 printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
bellard0db63472003-10-27 21:37:46 +00007661 "usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00007662 "\n"
bellarda20dd502003-09-30 21:07:02 +00007663 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00007664 "\n"
bellarda20dd502003-09-30 21:07:02 +00007665 "Standard options:\n"
bellardcc1daa42005-06-05 14:49:17 +00007666 "-M machine select emulated machine (-M ? for list)\n"
pbrook5adb4832007-03-08 03:15:18 +00007667 "-cpu cpu select CPU (-cpu ? for list)\n"
bellardc45886d2004-01-05 00:02:06 +00007668 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
bellard36b486b2003-11-11 13:36:08 +00007669 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
7670 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007671 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
aurel32a1620fa2008-04-29 05:58:01 +00007672 "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
7673 " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
7674 " [,cache=on|off][,format=f]\n"
thse4bcb142007-12-02 04:51:10 +00007675 " use 'file' as a drive image\n"
balrog3e3d5812007-04-30 02:09:25 +00007676 "-mtdblock file use 'file' as on-board Flash memory image\n"
pbrooka1bb27b2007-04-06 16:49:48 +00007677 "-sd file use 'file' as SecureDigital card image\n"
j_mayer86f55662007-04-24 06:52:59 +00007678 "-pflash file use 'file' as a parallel flash image\n"
thseec85c22007-01-05 17:41:07 +00007679 "-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 +00007680 "-snapshot write to temporary files instead of disk image files\n"
7681#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007682 "-no-frame open SDL window without a frame and window decorations\n"
ths3780e192007-06-21 21:08:02 +00007683 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
ths667acca2006-12-11 02:08:05 +00007684 "-no-quit disable SDL window close capability\n"
7685#endif
bellard52ca8d62006-06-14 16:03:05 +00007686#ifdef TARGET_I386
7687 "-no-fd-bootchk disable boot signature checking for floppy disks\n"
7688#endif
bellarda00bad72004-05-22 21:39:06 +00007689 "-m megs set virtual RAM size to megs MB [default=%d]\n"
bellard91fc2112005-12-18 19:09:37 +00007690 "-smp n set the number of CPUs to 'n' [default=1]\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007691 "-nographic disable graphical output and redirect serial I/Os to console\n"
balroga171fe32007-04-30 01:48:07 +00007692 "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
bellard4ca00742004-12-12 22:20:04 +00007693#ifndef _WIN32
ths667acca2006-12-11 02:08:05 +00007694 "-k language use keyboard layout (for example \"fr\" for French)\n"
bellard4ca00742004-12-12 22:20:04 +00007695#endif
bellard1d14ffa2005-10-30 18:58:22 +00007696#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007697 "-audio-help print list of audio drivers and their options\n"
bellardc0fe3822005-11-05 18:55:28 +00007698 "-soundhw c1,... enable audio support\n"
7699 " and only specified sound cards (comma separated list)\n"
7700 " use -soundhw ? to get the list of supported cards\n"
bellard6a36d842005-12-18 20:34:32 +00007701 " use -soundhw all to enable all of them\n"
bellard1d14ffa2005-10-30 18:58:22 +00007702#endif
bellard89980282004-06-03 14:04:03 +00007703 "-localtime set the real time clock to local time [default=utc]\n"
bellardd63d3072004-10-03 13:29:03 +00007704 "-full-screen start in full screen\n"
bellarda09db212005-04-30 16:10:35 +00007705#ifdef TARGET_I386
7706 "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
7707#endif
bellardb389dbf2005-11-06 16:49:55 +00007708 "-usb enable the USB driver (will be the default soon)\n"
7709 "-usbdevice name add the host or guest USB device 'name'\n"
bellard6f7e9ae2005-03-13 09:43:36 +00007710#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7711 "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
bellardbb0c6722004-06-20 12:37:32 +00007712#endif
thsc35734b2007-03-19 15:17:08 +00007713 "-name string set the name of the guest\n"
bellarda20dd502003-09-30 21:07:02 +00007714 "\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007715 "Network options:\n"
pbrooka41b2ff2006-02-05 04:14:41 +00007716 "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007717 " create a new Network Interface Card and connect it to VLAN 'n'\n"
bellardc20709a2004-04-21 23:27:19 +00007718#ifdef CONFIG_SLIRP
pbrook115defd2006-04-16 11:06:58 +00007719 "-net user[,vlan=n][,hostname=host]\n"
7720 " connect the user mode network stack to VLAN 'n' and send\n"
7721 " hostname 'host' to DHCP clients\n"
bellard7c9d8e02005-11-15 22:16:05 +00007722#endif
bellard7fb843f2006-02-01 23:06:55 +00007723#ifdef _WIN32
7724 "-net tap[,vlan=n],ifname=name\n"
7725 " connect the host TAP network interface to VLAN 'n'\n"
7726#else
thsb46a8902007-10-21 23:20:45 +00007727 "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7728 " connect the host TAP network interface to VLAN 'n' and use the\n"
7729 " network scripts 'file' (default=%s)\n"
7730 " and 'dfile' (default=%s);\n"
7731 " use '[down]script=no' to disable script execution;\n"
bellard7c9d8e02005-11-15 22:16:05 +00007732 " use 'fd=h' to connect to an already opened TAP interface\n"
bellard7fb843f2006-02-01 23:06:55 +00007733#endif
bellard6a00d602005-11-21 23:25:50 +00007734 "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007735 " connect the vlan 'n' to another VLAN using a socket connection\n"
bellard3d830452005-12-18 16:36:49 +00007736 "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7737 " connect the vlan 'n' to multicast maddr and port\n"
ths8a16d272008-07-19 09:56:24 +00007738#ifdef CONFIG_VDE
7739 "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
7740 " connect the vlan 'n' to port 'n' of a vde switch running\n"
7741 " on host and listening for incoming connections on 'socketpath'.\n"
7742 " Use group 'groupname' and mode 'octalmode' to change default\n"
7743 " ownership and permissions for communication port.\n"
7744#endif
bellard7c9d8e02005-11-15 22:16:05 +00007745 "-net none use it alone to have zero network devices; if no -net option\n"
7746 " is provided, the default is '-net nic -net user'\n"
7747 "\n"
7748#ifdef CONFIG_SLIRP
ths0db11372007-02-20 00:12:07 +00007749 "-tftp dir allow tftp access to files in dir [-net user]\n"
ths47d5d012007-02-20 00:05:08 +00007750 "-bootp file advertise file in BOOTP replies\n"
bellard7c9d8e02005-11-15 22:16:05 +00007751#ifndef _WIN32
7752 "-smb dir allow SMB access to files in 'dir' [-net user]\n"
bellardc94c8d62004-09-13 21:37:34 +00007753#endif
bellard9bf05442004-08-25 22:12:49 +00007754 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
bellard7c9d8e02005-11-15 22:16:05 +00007755 " redirect TCP or UDP connections from host to guest [-net user]\n"
bellardc20709a2004-04-21 23:27:19 +00007756#endif
bellardc4b1fcc2004-03-14 21:44:30 +00007757 "\n"
7758 "Linux boot specific:\n"
bellarda20dd502003-09-30 21:07:02 +00007759 "-kernel bzImage use 'bzImage' as kernel image\n"
7760 "-append cmdline use 'cmdline' as kernel command line\n"
7761 "-initrd file use 'file' as initial ram disk\n"
bellardfc01f7e2003-06-30 10:03:06 +00007762 "\n"
bellard330d0412003-07-26 18:11:40 +00007763 "Debug/Expert options:\n"
bellard82c643f2004-07-14 17:28:13 +00007764 "-monitor dev redirect the monitor to char device 'dev'\n"
7765 "-serial dev redirect the serial port to char device 'dev'\n"
bellard6508fe52005-01-15 12:02:56 +00007766 "-parallel dev redirect the parallel port to char device 'dev'\n"
bellardf7cce892004-12-08 22:21:25 +00007767 "-pidfile file Write PID to 'file'\n"
bellardcd6f1162004-05-13 22:02:20 +00007768 "-S freeze CPU at startup (use 'c' to start execution)\n"
pbrookcfc34752007-02-22 01:48:01 +00007769 "-s wait gdb connection to port\n"
7770 "-p port set gdb connection port [default=%s]\n"
bellardf193c792004-03-21 17:06:25 +00007771 "-d item1,... output log to %s (use -d ? for a list of log items)\n"
bellard46d47672004-11-16 01:45:27 +00007772 "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
7773 " translation (t=none or lba) (usually qemu can guess them)\n"
bellard87b47352006-08-17 17:22:54 +00007774 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
bellardd993e022005-02-10 22:00:06 +00007775#ifdef USE_KQEMU
bellard6515b202006-05-03 22:02:44 +00007776 "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
bellardd993e022005-02-10 22:00:06 +00007777 "-no-kqemu disable KQEMU kernel module usage\n"
7778#endif
bellardbb0c6722004-06-20 12:37:32 +00007779#ifdef TARGET_I386
bellard1bfe8562004-07-08 21:17:50 +00007780 "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
7781 " (default is CL-GD5446 PCI VGA)\n"
bellard6515b202006-05-03 22:02:44 +00007782 "-no-acpi disable ACPI\n"
bellardbb0c6722004-06-20 12:37:32 +00007783#endif
balrog4d3b6f62008-02-10 16:33:14 +00007784#ifdef CONFIG_CURSES
7785 "-curses use a curses/ncurses interface instead of SDL\n"
7786#endif
bellardd1beab82006-10-02 19:44:22 +00007787 "-no-reboot exit instead of rebooting\n"
aurel32b2f76162008-04-11 21:35:52 +00007788 "-no-shutdown stop before shutdown\n"
aurel32a8080002008-05-10 23:28:26 +00007789 "-loadvm [tag|id] start right away with a saved state (loadvm in monitor)\n"
bellard24236862006-04-30 21:28:36 +00007790 "-vnc display start a VNC server on display\n"
ths71e3ceb2006-12-22 02:11:31 +00007791#ifndef _WIN32
7792 "-daemonize daemonize QEMU after initializing\n"
7793#endif
ths9ae02552007-01-05 17:39:04 +00007794 "-option-rom rom load a file, rom, into the option ROM space\n"
blueswir166508602007-05-01 14:16:52 +00007795#ifdef TARGET_SPARC
7796 "-prom-env variable=value set OpenBIOS nvram variables\n"
7797#endif
thsf3dcfad2007-08-24 01:26:02 +00007798 "-clock force the use of the given methods for timer alarm.\n"
aurel323adda042008-03-09 23:43:49 +00007799 " To see what timers are available use -clock ?\n"
bellardbce61842008-02-01 22:18:51 +00007800 "-startdate select initial date of the clock\n"
pbrook2e70f6e2008-06-29 01:03:05 +00007801 "-icount [N|auto]\n"
pbrookdd5d6fe2008-06-29 10:43:16 +00007802 " Enable virtual instruction counter with 2^N clock ticks per instruction\n"
bellard0824d6f2003-06-24 13:42:40 +00007803 "\n"
bellard82c643f2004-07-14 17:28:13 +00007804 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00007805 "ctrl-alt-f toggle full screen\n"
7806 "ctrl-alt-n switch to virtual console 'n'\n"
7807 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00007808 "\n"
7809 "When using -nographic, press 'ctrl-a h' to get some help.\n"
7810 ,
bellard0db63472003-10-27 21:37:46 +00007811 "qemu",
bellarda00bad72004-05-22 21:39:06 +00007812 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00007813#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00007814 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00007815 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00007816#endif
bellard6e44ba72004-01-18 21:56:49 +00007817 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00007818 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00007819 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00007820}
7821
bellardcd6f1162004-05-13 22:02:20 +00007822#define HAS_ARG 0x0001
7823
7824enum {
7825 QEMU_OPTION_h,
7826
bellardcc1daa42005-06-05 14:49:17 +00007827 QEMU_OPTION_M,
j_mayer94fc95c2007-03-05 19:44:02 +00007828 QEMU_OPTION_cpu,
bellardcd6f1162004-05-13 22:02:20 +00007829 QEMU_OPTION_fda,
7830 QEMU_OPTION_fdb,
7831 QEMU_OPTION_hda,
7832 QEMU_OPTION_hdb,
7833 QEMU_OPTION_hdc,
7834 QEMU_OPTION_hdd,
thse4bcb142007-12-02 04:51:10 +00007835 QEMU_OPTION_drive,
bellardcd6f1162004-05-13 22:02:20 +00007836 QEMU_OPTION_cdrom,
balrog3e3d5812007-04-30 02:09:25 +00007837 QEMU_OPTION_mtdblock,
pbrooka1bb27b2007-04-06 16:49:48 +00007838 QEMU_OPTION_sd,
j_mayer86f55662007-04-24 06:52:59 +00007839 QEMU_OPTION_pflash,
bellardcd6f1162004-05-13 22:02:20 +00007840 QEMU_OPTION_boot,
7841 QEMU_OPTION_snapshot,
bellard52ca8d62006-06-14 16:03:05 +00007842#ifdef TARGET_I386
7843 QEMU_OPTION_no_fd_bootchk,
7844#endif
bellardcd6f1162004-05-13 22:02:20 +00007845 QEMU_OPTION_m,
7846 QEMU_OPTION_nographic,
balroga171fe32007-04-30 01:48:07 +00007847 QEMU_OPTION_portrait,
bellard1d14ffa2005-10-30 18:58:22 +00007848#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007849 QEMU_OPTION_audio_help,
7850 QEMU_OPTION_soundhw,
7851#endif
bellardcd6f1162004-05-13 22:02:20 +00007852
bellard7c9d8e02005-11-15 22:16:05 +00007853 QEMU_OPTION_net,
bellardc7f74642004-08-24 21:57:12 +00007854 QEMU_OPTION_tftp,
ths47d5d012007-02-20 00:05:08 +00007855 QEMU_OPTION_bootp,
bellard9d728e82004-09-05 23:09:03 +00007856 QEMU_OPTION_smb,
bellard9bf05442004-08-25 22:12:49 +00007857 QEMU_OPTION_redir,
bellardcd6f1162004-05-13 22:02:20 +00007858
7859 QEMU_OPTION_kernel,
7860 QEMU_OPTION_append,
7861 QEMU_OPTION_initrd,
7862
7863 QEMU_OPTION_S,
7864 QEMU_OPTION_s,
7865 QEMU_OPTION_p,
7866 QEMU_OPTION_d,
7867 QEMU_OPTION_hdachs,
7868 QEMU_OPTION_L,
j_mayer1192dad2007-10-05 13:08:35 +00007869 QEMU_OPTION_bios,
bellard3d11d0e2004-12-12 16:56:30 +00007870 QEMU_OPTION_k,
bellardee22c2f2004-06-03 12:49:50 +00007871 QEMU_OPTION_localtime,
bellard1f042752004-06-05 13:46:47 +00007872 QEMU_OPTION_cirrusvga,
thsd34cab92007-04-02 01:10:46 +00007873 QEMU_OPTION_vmsvga,
bellarde9b137c2004-06-21 16:46:10 +00007874 QEMU_OPTION_g,
bellard1bfe8562004-07-08 21:17:50 +00007875 QEMU_OPTION_std_vga,
ths20d8a3e2007-02-18 17:04:49 +00007876 QEMU_OPTION_echr,
bellard82c643f2004-07-14 17:28:13 +00007877 QEMU_OPTION_monitor,
7878 QEMU_OPTION_serial,
bellard6508fe52005-01-15 12:02:56 +00007879 QEMU_OPTION_parallel,
bellardd63d3072004-10-03 13:29:03 +00007880 QEMU_OPTION_loadvm,
7881 QEMU_OPTION_full_screen,
ths43523e92007-02-18 18:19:32 +00007882 QEMU_OPTION_no_frame,
ths3780e192007-06-21 21:08:02 +00007883 QEMU_OPTION_alt_grab,
ths667acca2006-12-11 02:08:05 +00007884 QEMU_OPTION_no_quit,
bellardf7cce892004-12-08 22:21:25 +00007885 QEMU_OPTION_pidfile,
bellardd993e022005-02-10 22:00:06 +00007886 QEMU_OPTION_no_kqemu,
bellard89bfc102006-02-08 22:46:31 +00007887 QEMU_OPTION_kernel_kqemu,
bellarda09db212005-04-30 16:10:35 +00007888 QEMU_OPTION_win2k_hack,
bellardbb36d472005-11-05 14:22:28 +00007889 QEMU_OPTION_usb,
bellarda594cfb2005-11-06 16:13:29 +00007890 QEMU_OPTION_usbdevice,
bellard6a00d602005-11-21 23:25:50 +00007891 QEMU_OPTION_smp,
bellard24236862006-04-30 21:28:36 +00007892 QEMU_OPTION_vnc,
bellard6515b202006-05-03 22:02:44 +00007893 QEMU_OPTION_no_acpi,
balrog4d3b6f62008-02-10 16:33:14 +00007894 QEMU_OPTION_curses,
bellardd1beab82006-10-02 19:44:22 +00007895 QEMU_OPTION_no_reboot,
aurel32b2f76162008-04-11 21:35:52 +00007896 QEMU_OPTION_no_shutdown,
balrog9467cd42007-05-01 01:34:14 +00007897 QEMU_OPTION_show_cursor,
ths71e3ceb2006-12-22 02:11:31 +00007898 QEMU_OPTION_daemonize,
ths9ae02552007-01-05 17:39:04 +00007899 QEMU_OPTION_option_rom,
thsc35734b2007-03-19 15:17:08 +00007900 QEMU_OPTION_semihosting,
7901 QEMU_OPTION_name,
blueswir166508602007-05-01 14:16:52 +00007902 QEMU_OPTION_prom_env,
balrog2b8f2d42007-07-27 22:08:46 +00007903 QEMU_OPTION_old_param,
thsf3dcfad2007-08-24 01:26:02 +00007904 QEMU_OPTION_clock,
bellard7e0af5d02007-11-07 16:24:33 +00007905 QEMU_OPTION_startdate,
bellard26a5f132008-05-28 12:30:31 +00007906 QEMU_OPTION_tb_size,
pbrook2e70f6e2008-06-29 01:03:05 +00007907 QEMU_OPTION_icount,
bellardcd6f1162004-05-13 22:02:20 +00007908};
7909
7910typedef struct QEMUOption {
7911 const char *name;
7912 int flags;
7913 int index;
7914} QEMUOption;
7915
7916const QEMUOption qemu_options[] = {
7917 { "h", 0, QEMU_OPTION_h },
pbrook64423fb2007-01-27 17:11:41 +00007918 { "help", 0, QEMU_OPTION_h },
bellardcd6f1162004-05-13 22:02:20 +00007919
bellardcc1daa42005-06-05 14:49:17 +00007920 { "M", HAS_ARG, QEMU_OPTION_M },
j_mayer94fc95c2007-03-05 19:44:02 +00007921 { "cpu", HAS_ARG, QEMU_OPTION_cpu },
bellardcd6f1162004-05-13 22:02:20 +00007922 { "fda", HAS_ARG, QEMU_OPTION_fda },
7923 { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7924 { "hda", HAS_ARG, QEMU_OPTION_hda },
7925 { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7926 { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7927 { "hdd", HAS_ARG, QEMU_OPTION_hdd },
thse4bcb142007-12-02 04:51:10 +00007928 { "drive", HAS_ARG, QEMU_OPTION_drive },
bellardcd6f1162004-05-13 22:02:20 +00007929 { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
balrog3e3d5812007-04-30 02:09:25 +00007930 { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
pbrooka1bb27b2007-04-06 16:49:48 +00007931 { "sd", HAS_ARG, QEMU_OPTION_sd },
j_mayer86f55662007-04-24 06:52:59 +00007932 { "pflash", HAS_ARG, QEMU_OPTION_pflash },
bellardcd6f1162004-05-13 22:02:20 +00007933 { "boot", HAS_ARG, QEMU_OPTION_boot },
7934 { "snapshot", 0, QEMU_OPTION_snapshot },
bellard52ca8d62006-06-14 16:03:05 +00007935#ifdef TARGET_I386
7936 { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7937#endif
bellardcd6f1162004-05-13 22:02:20 +00007938 { "m", HAS_ARG, QEMU_OPTION_m },
7939 { "nographic", 0, QEMU_OPTION_nographic },
balroga171fe32007-04-30 01:48:07 +00007940 { "portrait", 0, QEMU_OPTION_portrait },
bellard3d11d0e2004-12-12 16:56:30 +00007941 { "k", HAS_ARG, QEMU_OPTION_k },
bellard1d14ffa2005-10-30 18:58:22 +00007942#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007943 { "audio-help", 0, QEMU_OPTION_audio_help },
7944 { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7945#endif
bellardcd6f1162004-05-13 22:02:20 +00007946
bellard7c9d8e02005-11-15 22:16:05 +00007947 { "net", HAS_ARG, QEMU_OPTION_net},
bellard158156d2004-05-17 21:13:42 +00007948#ifdef CONFIG_SLIRP
bellardc7f74642004-08-24 21:57:12 +00007949 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
ths47d5d012007-02-20 00:05:08 +00007950 { "bootp", HAS_ARG, QEMU_OPTION_bootp },
bellardc94c8d62004-09-13 21:37:34 +00007951#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00007952 { "smb", HAS_ARG, QEMU_OPTION_smb },
bellardc94c8d62004-09-13 21:37:34 +00007953#endif
bellard9bf05442004-08-25 22:12:49 +00007954 { "redir", HAS_ARG, QEMU_OPTION_redir },
bellard158156d2004-05-17 21:13:42 +00007955#endif
bellardcd6f1162004-05-13 22:02:20 +00007956
7957 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7958 { "append", HAS_ARG, QEMU_OPTION_append },
7959 { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7960
7961 { "S", 0, QEMU_OPTION_S },
7962 { "s", 0, QEMU_OPTION_s },
7963 { "p", HAS_ARG, QEMU_OPTION_p },
7964 { "d", HAS_ARG, QEMU_OPTION_d },
7965 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7966 { "L", HAS_ARG, QEMU_OPTION_L },
j_mayer1192dad2007-10-05 13:08:35 +00007967 { "bios", HAS_ARG, QEMU_OPTION_bios },
bellardd993e022005-02-10 22:00:06 +00007968#ifdef USE_KQEMU
7969 { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
bellard89bfc102006-02-08 22:46:31 +00007970 { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
bellardd993e022005-02-10 22:00:06 +00007971#endif
bellard6f7e9ae2005-03-13 09:43:36 +00007972#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00007973 { "g", 1, QEMU_OPTION_g },
bellard77d4bc32004-05-26 22:13:53 +00007974#endif
bellardee22c2f2004-06-03 12:49:50 +00007975 { "localtime", 0, QEMU_OPTION_localtime },
bellard1bfe8562004-07-08 21:17:50 +00007976 { "std-vga", 0, QEMU_OPTION_std_vga },
balrog8b6e0722007-06-22 08:23:44 +00007977 { "echr", HAS_ARG, QEMU_OPTION_echr },
7978 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7979 { "serial", HAS_ARG, QEMU_OPTION_serial },
7980 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
bellardd63d3072004-10-03 13:29:03 +00007981 { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7982 { "full-screen", 0, QEMU_OPTION_full_screen },
ths667acca2006-12-11 02:08:05 +00007983#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007984 { "no-frame", 0, QEMU_OPTION_no_frame },
ths3780e192007-06-21 21:08:02 +00007985 { "alt-grab", 0, QEMU_OPTION_alt_grab },
ths667acca2006-12-11 02:08:05 +00007986 { "no-quit", 0, QEMU_OPTION_no_quit },
7987#endif
bellardf7cce892004-12-08 22:21:25 +00007988 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
bellarda09db212005-04-30 16:10:35 +00007989 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
bellarda594cfb2005-11-06 16:13:29 +00007990 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
bellard6a00d602005-11-21 23:25:50 +00007991 { "smp", HAS_ARG, QEMU_OPTION_smp },
bellard24236862006-04-30 21:28:36 +00007992 { "vnc", HAS_ARG, QEMU_OPTION_vnc },
balrog4d3b6f62008-02-10 16:33:14 +00007993#ifdef CONFIG_CURSES
7994 { "curses", 0, QEMU_OPTION_curses },
7995#endif
ths96d30e42007-01-07 20:42:14 +00007996
bellard1f042752004-06-05 13:46:47 +00007997 /* temporary options */
bellarda594cfb2005-11-06 16:13:29 +00007998 { "usb", 0, QEMU_OPTION_usb },
bellard1f042752004-06-05 13:46:47 +00007999 { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
thsd34cab92007-04-02 01:10:46 +00008000 { "vmwarevga", 0, QEMU_OPTION_vmsvga },
bellard6515b202006-05-03 22:02:44 +00008001 { "no-acpi", 0, QEMU_OPTION_no_acpi },
bellardd1beab82006-10-02 19:44:22 +00008002 { "no-reboot", 0, QEMU_OPTION_no_reboot },
aurel32b2f76162008-04-11 21:35:52 +00008003 { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
balrog9467cd42007-05-01 01:34:14 +00008004 { "show-cursor", 0, QEMU_OPTION_show_cursor },
ths71e3ceb2006-12-22 02:11:31 +00008005 { "daemonize", 0, QEMU_OPTION_daemonize },
ths9ae02552007-01-05 17:39:04 +00008006 { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
pbrooka87295e2007-05-26 15:09:38 +00008007#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00008008 { "semihosting", 0, QEMU_OPTION_semihosting },
8009#endif
thsc35734b2007-03-19 15:17:08 +00008010 { "name", HAS_ARG, QEMU_OPTION_name },
blueswir166508602007-05-01 14:16:52 +00008011#if defined(TARGET_SPARC)
8012 { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
8013#endif
balrog2b8f2d42007-07-27 22:08:46 +00008014#if defined(TARGET_ARM)
8015 { "old-param", 0, QEMU_OPTION_old_param },
8016#endif
thsf3dcfad2007-08-24 01:26:02 +00008017 { "clock", HAS_ARG, QEMU_OPTION_clock },
bellard7e0af5d02007-11-07 16:24:33 +00008018 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
bellard26a5f132008-05-28 12:30:31 +00008019 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
pbrook2e70f6e2008-06-29 01:03:05 +00008020 { "icount", HAS_ARG, QEMU_OPTION_icount },
bellardcd6f1162004-05-13 22:02:20 +00008021 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00008022};
8023
bellard5905b2e2004-08-01 21:53:26 +00008024/* password input */
8025
balrog2bac6012007-04-30 01:34:31 +00008026int qemu_key_check(BlockDriverState *bs, const char *name)
8027{
8028 char password[256];
8029 int i;
8030
8031 if (!bdrv_is_encrypted(bs))
8032 return 0;
8033
8034 term_printf("%s is encrypted.\n", name);
8035 for(i = 0; i < 3; i++) {
8036 monitor_readline("Password: ", 1, password, sizeof(password));
8037 if (bdrv_set_key(bs, password) == 0)
8038 return 0;
8039 term_printf("invalid password\n");
8040 }
8041 return -EPERM;
8042}
8043
aliguori83ab7952008-08-19 14:44:22 +00008044static BlockDriverState *get_bdrv(int index)
8045{
8046 if (index > nb_drives)
8047 return NULL;
8048 return drives_table[index].bdrv;
8049}
8050
bellard5905b2e2004-08-01 21:53:26 +00008051static void read_passwords(void)
8052{
8053 BlockDriverState *bs;
balrog2bac6012007-04-30 01:34:31 +00008054 int i;
bellard5905b2e2004-08-01 21:53:26 +00008055
aliguori83ab7952008-08-19 14:44:22 +00008056 for(i = 0; i < 6; i++) {
8057 bs = get_bdrv(i);
8058 if (bs)
8059 qemu_key_check(bs, bdrv_get_device_name(bs));
bellard5905b2e2004-08-01 21:53:26 +00008060 }
8061}
8062
bellard1d14ffa2005-10-30 18:58:22 +00008063#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00008064struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00008065#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00008066#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00008067 {
8068 "pcspk",
8069 "PC speaker",
8070 0,
8071 1,
8072 { .init_isa = pcspk_audio_init }
8073 },
8074#endif
bellard6a36d842005-12-18 20:34:32 +00008075 {
8076 "sb16",
8077 "Creative Sound Blaster 16",
8078 0,
8079 1,
8080 { .init_isa = SB16_init }
8081 },
8082
malccc53d262008-06-13 10:48:22 +00008083#ifdef CONFIG_CS4231A
8084 {
8085 "cs4231a",
8086 "CS4231A",
8087 0,
8088 1,
8089 { .init_isa = cs4231a_init }
8090 },
8091#endif
8092
bellard6a36d842005-12-18 20:34:32 +00008093#ifdef CONFIG_ADLIB
8094 {
8095 "adlib",
8096#ifdef HAS_YMF262
8097 "Yamaha YMF262 (OPL3)",
8098#else
8099 "Yamaha YM3812 (OPL2)",
8100#endif
8101 0,
8102 1,
8103 { .init_isa = Adlib_init }
8104 },
8105#endif
8106
8107#ifdef CONFIG_GUS
8108 {
8109 "gus",
8110 "Gravis Ultrasound GF1",
8111 0,
8112 1,
8113 { .init_isa = GUS_init }
8114 },
8115#endif
8116
balroge5c9a132008-01-14 04:27:55 +00008117#ifdef CONFIG_AC97
8118 {
8119 "ac97",
8120 "Intel 82801AA AC97 Audio",
8121 0,
8122 0,
8123 { .init_pci = ac97_init }
8124 },
8125#endif
8126
bellard6a36d842005-12-18 20:34:32 +00008127 {
8128 "es1370",
8129 "ENSONIQ AudioPCI ES1370",
8130 0,
8131 0,
8132 { .init_pci = es1370_init }
8133 },
balrogb00052e2007-04-30 02:22:06 +00008134#endif
bellard6a36d842005-12-18 20:34:32 +00008135
8136 { NULL, NULL, 0, 0, { NULL } }
8137};
8138
bellard1d14ffa2005-10-30 18:58:22 +00008139static void select_soundhw (const char *optarg)
8140{
bellard6a36d842005-12-18 20:34:32 +00008141 struct soundhw *c;
8142
bellard1d14ffa2005-10-30 18:58:22 +00008143 if (*optarg == '?') {
8144 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00008145
bellard1d14ffa2005-10-30 18:58:22 +00008146 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00008147 for (c = soundhw; c->name; ++c) {
8148 printf ("%-11s %s\n", c->name, c->descr);
8149 }
8150 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00008151 exit (*optarg != '?');
8152 }
8153 else {
bellard6a36d842005-12-18 20:34:32 +00008154 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00008155 const char *p;
8156 char *e;
8157 int bad_card = 0;
8158
bellard6a36d842005-12-18 20:34:32 +00008159 if (!strcmp (optarg, "all")) {
8160 for (c = soundhw; c->name; ++c) {
8161 c->enabled = 1;
8162 }
8163 return;
8164 }
bellard1d14ffa2005-10-30 18:58:22 +00008165
bellard6a36d842005-12-18 20:34:32 +00008166 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00008167 while (*p) {
8168 e = strchr (p, ',');
8169 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00008170
8171 for (c = soundhw; c->name; ++c) {
8172 if (!strncmp (c->name, p, l)) {
8173 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00008174 break;
8175 }
8176 }
bellard6a36d842005-12-18 20:34:32 +00008177
8178 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00008179 if (l > 80) {
8180 fprintf (stderr,
8181 "Unknown sound card name (too big to show)\n");
8182 }
8183 else {
8184 fprintf (stderr, "Unknown sound card name `%.*s'\n",
8185 (int) l, p);
8186 }
8187 bad_card = 1;
8188 }
8189 p += l + (e != NULL);
8190 }
8191
8192 if (bad_card)
8193 goto show_valid_cards;
8194 }
8195}
8196#endif
8197
bellard3587d7e2006-06-26 20:03:44 +00008198#ifdef _WIN32
8199static BOOL WINAPI qemu_ctrl_handler(DWORD type)
8200{
8201 exit(STATUS_CONTROL_C_EXIT);
8202 return TRUE;
8203}
8204#endif
8205
bellard7c9d8e02005-11-15 22:16:05 +00008206#define MAX_NET_CLIENTS 32
bellardc20709a2004-04-21 23:27:19 +00008207
aliguori5b08fc12008-08-21 20:08:03 +00008208#ifndef _WIN32
8209
8210static void termsig_handler(int signal)
8211{
8212 qemu_system_shutdown_request();
8213}
8214
blueswir16f9e3802008-09-09 18:56:59 +00008215static void termsig_setup(void)
aliguori5b08fc12008-08-21 20:08:03 +00008216{
8217 struct sigaction act;
8218
8219 memset(&act, 0, sizeof(act));
8220 act.sa_handler = termsig_handler;
8221 sigaction(SIGINT, &act, NULL);
8222 sigaction(SIGHUP, &act, NULL);
8223 sigaction(SIGTERM, &act, NULL);
8224}
8225
8226#endif
8227
bellard0824d6f2003-06-24 13:42:40 +00008228int main(int argc, char **argv)
8229{
bellard67b915a2004-03-31 23:37:16 +00008230#ifdef CONFIG_GDBSTUB
pbrookcfc34752007-02-22 01:48:01 +00008231 int use_gdbstub;
8232 const char *gdbstub_port;
bellard67b915a2004-03-31 23:37:16 +00008233#endif
j_mayer28c5af52007-11-11 01:50:45 +00008234 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00008235 int i;
j_mayer28c5af52007-11-11 01:50:45 +00008236 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00008237 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00008238 const char *kernel_filename, *kernel_cmdline;
j_mayer28c5af52007-11-11 01:50:45 +00008239 const char *boot_devices = "";
bellard313aa562003-08-10 21:52:11 +00008240 DisplayState *ds = &display_state;
bellard46d47672004-11-16 01:45:27 +00008241 int cyls, heads, secs, translation;
pbrookfd5f3932008-03-26 20:55:43 +00008242 const char *net_clients[MAX_NET_CLIENTS];
bellard7c9d8e02005-11-15 22:16:05 +00008243 int nb_net_clients;
thse4bcb142007-12-02 04:51:10 +00008244 int hda_index;
bellardcd6f1162004-05-13 22:02:20 +00008245 int optind;
8246 const char *r, *optarg;
bellard82c643f2004-07-14 17:28:13 +00008247 CharDriverState *monitor_hd;
pbrookfd5f3932008-03-26 20:55:43 +00008248 const char *monitor_device;
8249 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00008250 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00008251 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00008252 int parallel_device_index;
bellardd63d3072004-10-03 13:29:03 +00008253 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00008254 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00008255 const char *cpu_model;
pbrookfd5f3932008-03-26 20:55:43 +00008256 const char *usb_devices[MAX_USB_CMDLINE];
bellarda594cfb2005-11-06 16:13:29 +00008257 int usb_devices_index;
ths71e3ceb2006-12-22 02:11:31 +00008258 int fds[2];
bellard26a5f132008-05-28 12:30:31 +00008259 int tb_size;
ths93815bc2007-03-19 15:58:31 +00008260 const char *pid_file = NULL;
blueswir1833c7172007-05-27 19:36:43 +00008261 VLANState *vlan;
bellard0bd48852005-11-11 00:00:47 +00008262
8263 LIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00008264#ifndef _WIN32
8265 {
8266 struct sigaction act;
8267 sigfillset(&act.sa_mask);
8268 act.sa_flags = 0;
8269 act.sa_handler = SIG_IGN;
8270 sigaction(SIGPIPE, &act, NULL);
8271 }
bellard3587d7e2006-06-26 20:03:44 +00008272#else
8273 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00008274 /* Note: cpu_interrupt() is currently not SMP safe, so we force
8275 QEMU to run on a single CPU */
8276 {
8277 HANDLE h;
8278 DWORD mask, smask;
8279 int i;
8280 h = GetCurrentProcess();
8281 if (GetProcessAffinityMask(h, &mask, &smask)) {
8282 for(i = 0; i < 32; i++) {
8283 if (mask & (1 << i))
8284 break;
8285 }
8286 if (i != 32) {
8287 mask = 1 << i;
8288 SetProcessAffinityMask(h, mask);
8289 }
8290 }
8291 }
bellard67b915a2004-03-31 23:37:16 +00008292#endif
bellardbe995c22006-06-25 16:25:21 +00008293
bellardcc1daa42005-06-05 14:49:17 +00008294 register_machines();
8295 machine = first_machine;
j_mayer94fc95c2007-03-05 19:44:02 +00008296 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00008297 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00008298 ram_size = 0;
bellard313aa562003-08-10 21:52:11 +00008299 vga_ram_size = VGA_RAM_SIZE;
bellard67b915a2004-03-31 23:37:16 +00008300#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00008301 use_gdbstub = 0;
bellardc636bb62007-02-05 20:46:05 +00008302 gdbstub_port = DEFAULT_GDBSTUB_PORT;
bellard67b915a2004-03-31 23:37:16 +00008303#endif
bellard33e39632003-07-06 17:15:21 +00008304 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00008305 nographic = 0;
balrog4d3b6f62008-02-10 16:33:14 +00008306 curses = 0;
bellarda20dd502003-09-30 21:07:02 +00008307 kernel_filename = NULL;
8308 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00008309 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00008310 translation = BIOS_ATA_TRANSLATION_AUTO;
pbrookc60e08d2008-07-01 16:24:38 +00008311 monitor_device = "vc";
bellardc4b1fcc2004-03-14 21:44:30 +00008312
aurel32c75a8232008-05-04 00:50:34 +00008313 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00008314 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00008315 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00008316 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00008317
aurel32c75a8232008-05-04 00:50:34 +00008318 parallel_devices[0] = "vc:640x480";
bellard6508fe52005-01-15 12:02:56 +00008319 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00008320 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00008321 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00008322
bellarda594cfb2005-11-06 16:13:29 +00008323 usb_devices_index = 0;
ths3b46e622007-09-17 08:09:54 +00008324
bellard7c9d8e02005-11-15 22:16:05 +00008325 nb_net_clients = 0;
thse4bcb142007-12-02 04:51:10 +00008326 nb_drives = 0;
8327 nb_drives_opt = 0;
8328 hda_index = -1;
bellard7c9d8e02005-11-15 22:16:05 +00008329
8330 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00008331
bellard26a5f132008-05-28 12:30:31 +00008332 tb_size = 0;
8333
bellardcd6f1162004-05-13 22:02:20 +00008334 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00008335 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00008336 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00008337 break;
bellardcd6f1162004-05-13 22:02:20 +00008338 r = argv[optind];
8339 if (r[0] != '-') {
balrog609497a2008-01-14 02:56:53 +00008340 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00008341 } else {
8342 const QEMUOption *popt;
8343
8344 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00008345 /* Treat --foo the same as -foo. */
8346 if (r[1] == '-')
8347 r++;
bellardcd6f1162004-05-13 22:02:20 +00008348 popt = qemu_options;
8349 for(;;) {
8350 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00008351 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00008352 argv[0], r);
8353 exit(1);
8354 }
8355 if (!strcmp(popt->name, r + 1))
8356 break;
8357 popt++;
8358 }
8359 if (popt->flags & HAS_ARG) {
8360 if (optind >= argc) {
8361 fprintf(stderr, "%s: option '%s' requires an argument\n",
8362 argv[0], r);
8363 exit(1);
8364 }
8365 optarg = argv[optind++];
8366 } else {
8367 optarg = NULL;
8368 }
8369
8370 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00008371 case QEMU_OPTION_M:
8372 machine = find_machine(optarg);
8373 if (!machine) {
8374 QEMUMachine *m;
8375 printf("Supported machines are:\n");
8376 for(m = first_machine; m != NULL; m = m->next) {
8377 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00008378 m->name, m->desc,
bellardcc1daa42005-06-05 14:49:17 +00008379 m == first_machine ? " (default)" : "");
8380 }
ths15f82202007-06-29 23:26:08 +00008381 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00008382 }
8383 break;
j_mayer94fc95c2007-03-05 19:44:02 +00008384 case QEMU_OPTION_cpu:
8385 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00008386 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00008387/* XXX: implement xxx_cpu_list for targets that still miss it */
8388#if defined(cpu_list)
8389 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00008390#endif
ths15f82202007-06-29 23:26:08 +00008391 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00008392 } else {
8393 cpu_model = optarg;
8394 }
8395 break;
bellardcd6f1162004-05-13 22:02:20 +00008396 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00008397 initrd_filename = optarg;
8398 break;
bellardcd6f1162004-05-13 22:02:20 +00008399 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00008400 if (cyls == 0)
balrog609497a2008-01-14 02:56:53 +00008401 hda_index = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00008402 else
balrog609497a2008-01-14 02:56:53 +00008403 hda_index = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00008404 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00008405 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008406 translation == BIOS_ATA_TRANSLATION_LBA ?
8407 ",trans=lba" :
8408 translation == BIOS_ATA_TRANSLATION_NONE ?
8409 ",trans=none" : "");
8410 break;
bellardcd6f1162004-05-13 22:02:20 +00008411 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00008412 case QEMU_OPTION_hdc:
8413 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00008414 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00008415 break;
thse4bcb142007-12-02 04:51:10 +00008416 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00008417 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00008418 break;
balrog3e3d5812007-04-30 02:09:25 +00008419 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00008420 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00008421 break;
pbrooka1bb27b2007-04-06 16:49:48 +00008422 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00008423 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00008424 break;
j_mayer86f55662007-04-24 06:52:59 +00008425 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00008426 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00008427 break;
bellardcd6f1162004-05-13 22:02:20 +00008428 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00008429 snapshot = 1;
8430 break;
bellardcd6f1162004-05-13 22:02:20 +00008431 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00008432 {
bellard330d0412003-07-26 18:11:40 +00008433 const char *p;
8434 p = optarg;
8435 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008436 if (cyls < 1 || cyls > 16383)
8437 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008438 if (*p != ',')
8439 goto chs_fail;
8440 p++;
8441 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008442 if (heads < 1 || heads > 16)
8443 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008444 if (*p != ',')
8445 goto chs_fail;
8446 p++;
8447 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008448 if (secs < 1 || secs > 63)
8449 goto chs_fail;
8450 if (*p == ',') {
8451 p++;
8452 if (!strcmp(p, "none"))
8453 translation = BIOS_ATA_TRANSLATION_NONE;
8454 else if (!strcmp(p, "lba"))
8455 translation = BIOS_ATA_TRANSLATION_LBA;
8456 else if (!strcmp(p, "auto"))
8457 translation = BIOS_ATA_TRANSLATION_AUTO;
8458 else
8459 goto chs_fail;
8460 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00008461 chs_fail:
bellard46d47672004-11-16 01:45:27 +00008462 fprintf(stderr, "qemu: invalid physical CHS format\n");
8463 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00008464 }
thse4bcb142007-12-02 04:51:10 +00008465 if (hda_index != -1)
balrog609497a2008-01-14 02:56:53 +00008466 snprintf(drives_opt[hda_index].opt,
8467 sizeof(drives_opt[hda_index].opt),
8468 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
8469 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008470 translation == BIOS_ATA_TRANSLATION_LBA ?
8471 ",trans=lba" :
8472 translation == BIOS_ATA_TRANSLATION_NONE ?
8473 ",trans=none" : "");
bellard330d0412003-07-26 18:11:40 +00008474 }
8475 break;
bellardcd6f1162004-05-13 22:02:20 +00008476 case QEMU_OPTION_nographic:
bellarda20dd502003-09-30 21:07:02 +00008477 nographic = 1;
8478 break;
balrog4d3b6f62008-02-10 16:33:14 +00008479#ifdef CONFIG_CURSES
8480 case QEMU_OPTION_curses:
8481 curses = 1;
8482 break;
8483#endif
balroga171fe32007-04-30 01:48:07 +00008484 case QEMU_OPTION_portrait:
8485 graphic_rotate = 1;
8486 break;
bellardcd6f1162004-05-13 22:02:20 +00008487 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00008488 kernel_filename = optarg;
8489 break;
bellardcd6f1162004-05-13 22:02:20 +00008490 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00008491 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00008492 break;
bellardcd6f1162004-05-13 22:02:20 +00008493 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00008494 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00008495 break;
bellardcd6f1162004-05-13 22:02:20 +00008496 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00008497 boot_devices = optarg;
8498 /* We just do some generic consistency checks */
8499 {
8500 /* Could easily be extended to 64 devices if needed */
ths60fe76f2007-12-16 03:02:09 +00008501 const char *p;
j_mayer28c5af52007-11-11 01:50:45 +00008502
8503 boot_devices_bitmap = 0;
8504 for (p = boot_devices; *p != '\0'; p++) {
8505 /* Allowed boot devices are:
8506 * a b : floppy disk drives
8507 * c ... f : IDE disk drives
8508 * g ... m : machine implementation dependant drives
8509 * n ... p : network devices
8510 * It's up to each machine implementation to check
8511 * if the given boot devices match the actual hardware
8512 * implementation and firmware features.
8513 */
8514 if (*p < 'a' || *p > 'q') {
8515 fprintf(stderr, "Invalid boot device '%c'\n", *p);
8516 exit(1);
8517 }
8518 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
8519 fprintf(stderr,
8520 "Boot device '%c' was given twice\n",*p);
8521 exit(1);
8522 }
8523 boot_devices_bitmap |= 1 << (*p - 'a');
8524 }
bellard36b486b2003-11-11 13:36:08 +00008525 }
8526 break;
bellardcd6f1162004-05-13 22:02:20 +00008527 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00008528 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00008529 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00008530 break;
bellard52ca8d62006-06-14 16:03:05 +00008531#ifdef TARGET_I386
8532 case QEMU_OPTION_no_fd_bootchk:
8533 fd_bootchk = 0;
8534 break;
8535#endif
bellard7c9d8e02005-11-15 22:16:05 +00008536 case QEMU_OPTION_net:
8537 if (nb_net_clients >= MAX_NET_CLIENTS) {
8538 fprintf(stderr, "qemu: too many network clients\n");
bellardc4b1fcc2004-03-14 21:44:30 +00008539 exit(1);
8540 }
pbrookfd5f3932008-03-26 20:55:43 +00008541 net_clients[nb_net_clients] = optarg;
bellard7c9d8e02005-11-15 22:16:05 +00008542 nb_net_clients++;
bellard702c6512004-04-02 21:21:32 +00008543 break;
bellardc7f74642004-08-24 21:57:12 +00008544#ifdef CONFIG_SLIRP
8545 case QEMU_OPTION_tftp:
bellardc7f74642004-08-24 21:57:12 +00008546 tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00008547 break;
ths47d5d012007-02-20 00:05:08 +00008548 case QEMU_OPTION_bootp:
8549 bootp_filename = optarg;
8550 break;
bellardc94c8d62004-09-13 21:37:34 +00008551#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00008552 case QEMU_OPTION_smb:
8553 net_slirp_smb(optarg);
8554 break;
bellardc94c8d62004-09-13 21:37:34 +00008555#endif
bellard9bf05442004-08-25 22:12:49 +00008556 case QEMU_OPTION_redir:
ths3b46e622007-09-17 08:09:54 +00008557 net_slirp_redir(optarg);
bellard9bf05442004-08-25 22:12:49 +00008558 break;
bellardc7f74642004-08-24 21:57:12 +00008559#endif
bellard1d14ffa2005-10-30 18:58:22 +00008560#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00008561 case QEMU_OPTION_audio_help:
8562 AUD_help ();
8563 exit (0);
8564 break;
8565 case QEMU_OPTION_soundhw:
8566 select_soundhw (optarg);
8567 break;
8568#endif
bellardcd6f1162004-05-13 22:02:20 +00008569 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00008570 help(0);
bellardcd6f1162004-05-13 22:02:20 +00008571 break;
aurel3200f82b82008-04-27 21:12:55 +00008572 case QEMU_OPTION_m: {
8573 uint64_t value;
8574 char *ptr;
8575
8576 value = strtoul(optarg, &ptr, 10);
8577 switch (*ptr) {
8578 case 0: case 'M': case 'm':
8579 value <<= 20;
8580 break;
8581 case 'G': case 'g':
8582 value <<= 30;
8583 break;
8584 default:
8585 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00008586 exit(1);
8587 }
aurel3200f82b82008-04-27 21:12:55 +00008588
8589 /* On 32-bit hosts, QEMU is limited by virtual address space */
8590 if (value > (2047 << 20)
8591#ifndef USE_KQEMU
8592 && HOST_LONG_BITS == 32
8593#endif
8594 ) {
8595 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
8596 exit(1);
8597 }
8598 if (value != (uint64_t)(ram_addr_t)value) {
8599 fprintf(stderr, "qemu: ram size too large\n");
8600 exit(1);
8601 }
8602 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00008603 break;
aurel3200f82b82008-04-27 21:12:55 +00008604 }
bellardcd6f1162004-05-13 22:02:20 +00008605 case QEMU_OPTION_d:
8606 {
8607 int mask;
8608 CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00008609
bellardcd6f1162004-05-13 22:02:20 +00008610 mask = cpu_str_to_log_mask(optarg);
8611 if (!mask) {
8612 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00008613 for(item = cpu_log_items; item->mask != 0; item++) {
8614 printf("%-10s %s\n", item->name, item->help);
8615 }
8616 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00008617 }
8618 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00008619 }
bellardcd6f1162004-05-13 22:02:20 +00008620 break;
bellard67b915a2004-03-31 23:37:16 +00008621#ifdef CONFIG_GDBSTUB
bellardcd6f1162004-05-13 22:02:20 +00008622 case QEMU_OPTION_s:
8623 use_gdbstub = 1;
8624 break;
8625 case QEMU_OPTION_p:
pbrookcfc34752007-02-22 01:48:01 +00008626 gdbstub_port = optarg;
bellardcd6f1162004-05-13 22:02:20 +00008627 break;
bellard67b915a2004-03-31 23:37:16 +00008628#endif
bellardcd6f1162004-05-13 22:02:20 +00008629 case QEMU_OPTION_L:
8630 bios_dir = optarg;
8631 break;
j_mayer1192dad2007-10-05 13:08:35 +00008632 case QEMU_OPTION_bios:
8633 bios_name = optarg;
8634 break;
bellardcd6f1162004-05-13 22:02:20 +00008635 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00008636 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00008637 break;
bellard3d11d0e2004-12-12 16:56:30 +00008638 case QEMU_OPTION_k:
8639 keyboard_layout = optarg;
8640 break;
bellardee22c2f2004-06-03 12:49:50 +00008641 case QEMU_OPTION_localtime:
8642 rtc_utc = 0;
8643 break;
bellard1f042752004-06-05 13:46:47 +00008644 case QEMU_OPTION_cirrusvga:
8645 cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +00008646 vmsvga_enabled = 0;
8647 break;
8648 case QEMU_OPTION_vmsvga:
8649 cirrus_vga_enabled = 0;
8650 vmsvga_enabled = 1;
bellard1f042752004-06-05 13:46:47 +00008651 break;
bellard1bfe8562004-07-08 21:17:50 +00008652 case QEMU_OPTION_std_vga:
8653 cirrus_vga_enabled = 0;
thsd34cab92007-04-02 01:10:46 +00008654 vmsvga_enabled = 0;
bellard1bfe8562004-07-08 21:17:50 +00008655 break;
bellarde9b137c2004-06-21 16:46:10 +00008656 case QEMU_OPTION_g:
8657 {
8658 const char *p;
8659 int w, h, depth;
8660 p = optarg;
8661 w = strtol(p, (char **)&p, 10);
8662 if (w <= 0) {
8663 graphic_error:
8664 fprintf(stderr, "qemu: invalid resolution or depth\n");
8665 exit(1);
8666 }
8667 if (*p != 'x')
8668 goto graphic_error;
8669 p++;
8670 h = strtol(p, (char **)&p, 10);
8671 if (h <= 0)
8672 goto graphic_error;
8673 if (*p == 'x') {
8674 p++;
8675 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00008676 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00008677 depth != 24 && depth != 32)
8678 goto graphic_error;
8679 } else if (*p == '\0') {
8680 depth = graphic_depth;
8681 } else {
8682 goto graphic_error;
8683 }
ths3b46e622007-09-17 08:09:54 +00008684
bellarde9b137c2004-06-21 16:46:10 +00008685 graphic_width = w;
8686 graphic_height = h;
8687 graphic_depth = depth;
8688 }
8689 break;
ths20d8a3e2007-02-18 17:04:49 +00008690 case QEMU_OPTION_echr:
8691 {
8692 char *r;
8693 term_escape_char = strtol(optarg, &r, 0);
8694 if (r == optarg)
8695 printf("Bad argument to echr\n");
8696 break;
8697 }
bellard82c643f2004-07-14 17:28:13 +00008698 case QEMU_OPTION_monitor:
pbrookfd5f3932008-03-26 20:55:43 +00008699 monitor_device = optarg;
bellard82c643f2004-07-14 17:28:13 +00008700 break;
8701 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00008702 if (serial_device_index >= MAX_SERIAL_PORTS) {
8703 fprintf(stderr, "qemu: too many serial ports\n");
8704 exit(1);
8705 }
pbrookfd5f3932008-03-26 20:55:43 +00008706 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00008707 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00008708 break;
bellard6508fe52005-01-15 12:02:56 +00008709 case QEMU_OPTION_parallel:
8710 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
8711 fprintf(stderr, "qemu: too many parallel ports\n");
8712 exit(1);
8713 }
pbrookfd5f3932008-03-26 20:55:43 +00008714 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00008715 parallel_device_index++;
8716 break;
bellardd63d3072004-10-03 13:29:03 +00008717 case QEMU_OPTION_loadvm:
8718 loadvm = optarg;
8719 break;
8720 case QEMU_OPTION_full_screen:
8721 full_screen = 1;
8722 break;
ths667acca2006-12-11 02:08:05 +00008723#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00008724 case QEMU_OPTION_no_frame:
8725 no_frame = 1;
8726 break;
ths3780e192007-06-21 21:08:02 +00008727 case QEMU_OPTION_alt_grab:
8728 alt_grab = 1;
8729 break;
ths667acca2006-12-11 02:08:05 +00008730 case QEMU_OPTION_no_quit:
8731 no_quit = 1;
8732 break;
8733#endif
bellardf7cce892004-12-08 22:21:25 +00008734 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00008735 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00008736 break;
bellarda09db212005-04-30 16:10:35 +00008737#ifdef TARGET_I386
8738 case QEMU_OPTION_win2k_hack:
8739 win2k_install_hack = 1;
8740 break;
8741#endif
bellardd993e022005-02-10 22:00:06 +00008742#ifdef USE_KQEMU
8743 case QEMU_OPTION_no_kqemu:
8744 kqemu_allowed = 0;
8745 break;
bellard89bfc102006-02-08 22:46:31 +00008746 case QEMU_OPTION_kernel_kqemu:
8747 kqemu_allowed = 2;
8748 break;
bellardd993e022005-02-10 22:00:06 +00008749#endif
bellardbb36d472005-11-05 14:22:28 +00008750 case QEMU_OPTION_usb:
8751 usb_enabled = 1;
8752 break;
bellarda594cfb2005-11-06 16:13:29 +00008753 case QEMU_OPTION_usbdevice:
8754 usb_enabled = 1;
pbrook0d92ed32006-05-21 16:30:15 +00008755 if (usb_devices_index >= MAX_USB_CMDLINE) {
bellarda594cfb2005-11-06 16:13:29 +00008756 fprintf(stderr, "Too many USB devices\n");
8757 exit(1);
8758 }
pbrookfd5f3932008-03-26 20:55:43 +00008759 usb_devices[usb_devices_index] = optarg;
bellarda594cfb2005-11-06 16:13:29 +00008760 usb_devices_index++;
8761 break;
bellard6a00d602005-11-21 23:25:50 +00008762 case QEMU_OPTION_smp:
8763 smp_cpus = atoi(optarg);
bellardba3c64f2005-12-05 20:31:52 +00008764 if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
bellard6a00d602005-11-21 23:25:50 +00008765 fprintf(stderr, "Invalid number of CPUs\n");
8766 exit(1);
8767 }
8768 break;
bellard24236862006-04-30 21:28:36 +00008769 case QEMU_OPTION_vnc:
ths73fc9742006-12-22 02:09:07 +00008770 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00008771 break;
bellard6515b202006-05-03 22:02:44 +00008772 case QEMU_OPTION_no_acpi:
8773 acpi_enabled = 0;
8774 break;
bellardd1beab82006-10-02 19:44:22 +00008775 case QEMU_OPTION_no_reboot:
8776 no_reboot = 1;
8777 break;
aurel32b2f76162008-04-11 21:35:52 +00008778 case QEMU_OPTION_no_shutdown:
8779 no_shutdown = 1;
8780 break;
balrog9467cd42007-05-01 01:34:14 +00008781 case QEMU_OPTION_show_cursor:
8782 cursor_hide = 0;
8783 break;
ths71e3ceb2006-12-22 02:11:31 +00008784 case QEMU_OPTION_daemonize:
8785 daemonize = 1;
8786 break;
ths9ae02552007-01-05 17:39:04 +00008787 case QEMU_OPTION_option_rom:
8788 if (nb_option_roms >= MAX_OPTION_ROMS) {
8789 fprintf(stderr, "Too many option ROMs\n");
8790 exit(1);
8791 }
8792 option_rom[nb_option_roms] = optarg;
8793 nb_option_roms++;
8794 break;
pbrook8e716212007-01-20 17:12:09 +00008795 case QEMU_OPTION_semihosting:
8796 semihosting_enabled = 1;
8797 break;
thsc35734b2007-03-19 15:17:08 +00008798 case QEMU_OPTION_name:
8799 qemu_name = optarg;
8800 break;
blueswir166508602007-05-01 14:16:52 +00008801#ifdef TARGET_SPARC
8802 case QEMU_OPTION_prom_env:
8803 if (nb_prom_envs >= MAX_PROM_ENVS) {
8804 fprintf(stderr, "Too many prom variables\n");
8805 exit(1);
8806 }
8807 prom_envs[nb_prom_envs] = optarg;
8808 nb_prom_envs++;
8809 break;
8810#endif
balrog2b8f2d42007-07-27 22:08:46 +00008811#ifdef TARGET_ARM
8812 case QEMU_OPTION_old_param:
8813 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00008814 break;
balrog2b8f2d42007-07-27 22:08:46 +00008815#endif
thsf3dcfad2007-08-24 01:26:02 +00008816 case QEMU_OPTION_clock:
8817 configure_alarms(optarg);
8818 break;
bellard7e0af5d02007-11-07 16:24:33 +00008819 case QEMU_OPTION_startdate:
8820 {
8821 struct tm tm;
balrogf6503052008-02-17 11:42:19 +00008822 time_t rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008823 if (!strcmp(optarg, "now")) {
balrogf6503052008-02-17 11:42:19 +00008824 rtc_date_offset = -1;
bellard7e0af5d02007-11-07 16:24:33 +00008825 } else {
8826 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8827 &tm.tm_year,
8828 &tm.tm_mon,
8829 &tm.tm_mday,
8830 &tm.tm_hour,
8831 &tm.tm_min,
8832 &tm.tm_sec) == 6) {
8833 /* OK */
8834 } else if (sscanf(optarg, "%d-%d-%d",
8835 &tm.tm_year,
8836 &tm.tm_mon,
8837 &tm.tm_mday) == 3) {
8838 tm.tm_hour = 0;
8839 tm.tm_min = 0;
8840 tm.tm_sec = 0;
8841 } else {
8842 goto date_fail;
8843 }
8844 tm.tm_year -= 1900;
8845 tm.tm_mon--;
bellard3c6b2082007-11-10 19:36:39 +00008846 rtc_start_date = mktimegm(&tm);
bellard7e0af5d02007-11-07 16:24:33 +00008847 if (rtc_start_date == -1) {
8848 date_fail:
8849 fprintf(stderr, "Invalid date format. Valid format are:\n"
8850 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8851 exit(1);
8852 }
balrogf6503052008-02-17 11:42:19 +00008853 rtc_date_offset = time(NULL) - rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008854 }
8855 }
8856 break;
bellard26a5f132008-05-28 12:30:31 +00008857 case QEMU_OPTION_tb_size:
8858 tb_size = strtol(optarg, NULL, 0);
8859 if (tb_size < 0)
8860 tb_size = 0;
8861 break;
pbrook2e70f6e2008-06-29 01:03:05 +00008862 case QEMU_OPTION_icount:
8863 use_icount = 1;
8864 if (strcmp(optarg, "auto") == 0) {
8865 icount_time_shift = -1;
8866 } else {
8867 icount_time_shift = strtol(optarg, NULL, 0);
8868 }
8869 break;
bellardcd6f1162004-05-13 22:02:20 +00008870 }
bellard0824d6f2003-06-24 13:42:40 +00008871 }
8872 }
bellard330d0412003-07-26 18:11:40 +00008873
aliguoribc0129d2008-08-01 15:12:34 +00008874 if (nographic) {
8875 if (serial_device_index == 0)
8876 serial_devices[0] = "stdio";
8877 if (parallel_device_index == 0)
8878 parallel_devices[0] = "null";
8879 if (strncmp(monitor_device, "vc", 2) == 0)
8880 monitor_device = "stdio";
8881 }
8882
ths71e3ceb2006-12-22 02:11:31 +00008883#ifndef _WIN32
ths71e3ceb2006-12-22 02:11:31 +00008884 if (daemonize) {
8885 pid_t pid;
8886
8887 if (pipe(fds) == -1)
8888 exit(1);
8889
8890 pid = fork();
8891 if (pid > 0) {
8892 uint8_t status;
8893 ssize_t len;
8894
8895 close(fds[1]);
8896
8897 again:
ths93815bc2007-03-19 15:58:31 +00008898 len = read(fds[0], &status, 1);
8899 if (len == -1 && (errno == EINTR))
8900 goto again;
8901
8902 if (len != 1)
8903 exit(1);
8904 else if (status == 1) {
8905 fprintf(stderr, "Could not acquire pidfile\n");
8906 exit(1);
8907 } else
8908 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00008909 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00008910 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00008911
8912 setsid();
8913
8914 pid = fork();
8915 if (pid > 0)
8916 exit(0);
8917 else if (pid < 0)
8918 exit(1);
8919
8920 umask(027);
ths71e3ceb2006-12-22 02:11:31 +00008921
8922 signal(SIGTSTP, SIG_IGN);
8923 signal(SIGTTOU, SIG_IGN);
8924 signal(SIGTTIN, SIG_IGN);
8925 }
8926#endif
8927
thsaa26bb22007-03-25 21:33:06 +00008928 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00008929 if (daemonize) {
8930 uint8_t status = 1;
8931 write(fds[1], &status, 1);
8932 } else
8933 fprintf(stderr, "Could not acquire pid file\n");
8934 exit(1);
8935 }
8936
bellardff3fbb32006-01-08 10:53:14 +00008937#ifdef USE_KQEMU
8938 if (smp_cpus > 1)
8939 kqemu_allowed = 0;
8940#endif
bellarda20dd502003-09-30 21:07:02 +00008941 linux_boot = (kernel_filename != NULL);
balrog7317b8c2007-11-18 02:09:36 +00008942 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
balrog6c41b272007-11-17 12:12:29 +00008943
j_mayer28c5af52007-11-11 01:50:45 +00008944 if (!linux_boot && net_boot == 0 &&
blueswir1f88e4b92008-08-12 15:58:35 +00008945 !machine->nodisk_ok && nb_drives_opt == 0)
ths15f82202007-06-29 23:26:08 +00008946 help(1);
bellard0824d6f2003-06-24 13:42:40 +00008947
thsf8d39c02008-07-03 10:01:15 +00008948 if (!linux_boot && *kernel_cmdline != '\0') {
8949 fprintf(stderr, "-append only allowed with -kernel option\n");
8950 exit(1);
8951 }
8952
8953 if (!linux_boot && initrd_filename != NULL) {
8954 fprintf(stderr, "-initrd only allowed with -kernel option\n");
8955 exit(1);
8956 }
8957
ths96d30e42007-01-07 20:42:14 +00008958 /* boot to floppy or the default cd if no hard disk defined yet */
j_mayer28c5af52007-11-11 01:50:45 +00008959 if (!boot_devices[0]) {
thse4bcb142007-12-02 04:51:10 +00008960 boot_devices = "cad";
ths96d30e42007-01-07 20:42:14 +00008961 }
bellardb118d612003-06-30 23:36:21 +00008962 setvbuf(stdout, NULL, _IOLBF, 0);
ths3b46e622007-09-17 08:09:54 +00008963
pbrook634fce92006-07-15 17:40:09 +00008964 init_timers();
8965 init_timer_alarm();
bellard83f64092006-08-01 16:21:11 +00008966 qemu_aio_init();
pbrook2e70f6e2008-06-29 01:03:05 +00008967 if (use_icount && icount_time_shift < 0) {
8968 use_icount = 2;
8969 /* 125MIPS seems a reasonable initial guess at the guest speed.
8970 It will be corrected fairly quickly anyway. */
8971 icount_time_shift = 3;
8972 init_icount_adjust();
8973 }
pbrook634fce92006-07-15 17:40:09 +00008974
bellardfd1dff42006-02-01 21:29:26 +00008975#ifdef _WIN32
8976 socket_init();
8977#endif
8978
bellard7c9d8e02005-11-15 22:16:05 +00008979 /* init network clients */
8980 if (nb_net_clients == 0) {
8981 /* if no clients, we use a default config */
aliguorif441b282008-08-28 20:05:14 +00008982 net_clients[nb_net_clients++] = "nic";
8983#ifdef CONFIG_SLIRP
8984 net_clients[nb_net_clients++] = "user";
8985#endif
bellardc20709a2004-04-21 23:27:19 +00008986 }
8987
bellard7c9d8e02005-11-15 22:16:05 +00008988 for(i = 0;i < nb_net_clients; i++) {
balrog9ad97e62008-07-29 13:16:31 +00008989 if (net_client_parse(net_clients[i]) < 0)
bellard7c9d8e02005-11-15 22:16:05 +00008990 exit(1);
bellard702c6512004-04-02 21:21:32 +00008991 }
blueswir1833c7172007-05-27 19:36:43 +00008992 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8993 if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8994 continue;
balrog9ad97e62008-07-29 13:16:31 +00008995 if (vlan->nb_guest_devs == 0)
8996 fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id);
blueswir1833c7172007-05-27 19:36:43 +00008997 if (vlan->nb_host_devs == 0)
8998 fprintf(stderr,
8999 "Warning: vlan %d is not connected to host network\n",
9000 vlan->id);
9001 }
bellardf1510b22003-06-25 00:07:40 +00009002
thseec85c22007-01-05 17:41:07 +00009003#ifdef TARGET_I386
balroged494d82007-12-11 23:23:52 +00009004 /* XXX: this should be moved in the PC machine instantiation code */
j_mayer28c5af52007-11-11 01:50:45 +00009005 if (net_boot != 0) {
9006 int netroms = 0;
9007 for (i = 0; i < nb_nics && i < 4; i++) {
thseec85c22007-01-05 17:41:07 +00009008 const char *model = nd_table[i].model;
9009 char buf[1024];
j_mayer28c5af52007-11-11 01:50:45 +00009010 if (net_boot & (1 << i)) {
9011 if (model == NULL)
9012 model = "ne2k_pci";
9013 snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
9014 if (get_image_size(buf) > 0) {
9015 if (nb_option_roms >= MAX_OPTION_ROMS) {
9016 fprintf(stderr, "Too many option ROMs\n");
9017 exit(1);
9018 }
9019 option_rom[nb_option_roms] = strdup(buf);
9020 nb_option_roms++;
9021 netroms++;
9022 }
9023 }
thseec85c22007-01-05 17:41:07 +00009024 }
j_mayer28c5af52007-11-11 01:50:45 +00009025 if (netroms == 0) {
thseec85c22007-01-05 17:41:07 +00009026 fprintf(stderr, "No valid PXE rom found for network device\n");
9027 exit(1);
9028 }
thseec85c22007-01-05 17:41:07 +00009029 }
9030#endif
9031
bellard0824d6f2003-06-24 13:42:40 +00009032 /* init the memory */
balrog7fb4fdc2008-04-24 17:59:27 +00009033 phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
9034
9035 if (machine->ram_require & RAMSIZE_FIXED) {
9036 if (ram_size > 0) {
9037 if (ram_size < phys_ram_size) {
aurel32cd940062008-04-28 20:26:54 +00009038 fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
9039 machine->name, (unsigned long long) phys_ram_size);
balrog7fb4fdc2008-04-24 17:59:27 +00009040 exit(-1);
9041 }
9042
9043 phys_ram_size = ram_size;
9044 } else
9045 ram_size = phys_ram_size;
9046 } else {
aurel324fc5d072008-04-27 21:39:40 +00009047 if (ram_size == 0)
balrog7fb4fdc2008-04-24 17:59:27 +00009048 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
9049
9050 phys_ram_size += ram_size;
9051 }
ths9ae02552007-01-05 17:39:04 +00009052
bellardd993e022005-02-10 22:00:06 +00009053 phys_ram_base = qemu_vmalloc(phys_ram_size);
bellard7f7f9872003-10-30 01:11:23 +00009054 if (!phys_ram_base) {
9055 fprintf(stderr, "Could not allocate physical memory\n");
bellard0824d6f2003-06-24 13:42:40 +00009056 exit(1);
9057 }
9058
bellard26a5f132008-05-28 12:30:31 +00009059 /* init the dynamic translator */
9060 cpu_exec_init_all(tb_size * 1024 * 1024);
9061
bellard5905b2e2004-08-01 21:53:26 +00009062 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00009063
9064 /* we always create the cdrom drive, even if no disk is there */
9065
9066 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009067 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00009068
balrog9d413d12007-12-04 00:10:34 +00009069 /* we always create at least one floppy */
thse4bcb142007-12-02 04:51:10 +00009070
9071 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009072 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00009073
balrog9d413d12007-12-04 00:10:34 +00009074 /* we always create one sd slot, even if no card is in it */
9075
9076 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00009077 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00009078
ths96d30e42007-01-07 20:42:14 +00009079 /* open the virtual block devices */
bellardc4b1fcc2004-03-14 21:44:30 +00009080
thse4bcb142007-12-02 04:51:10 +00009081 for(i = 0; i < nb_drives_opt; i++)
balrog609497a2008-01-14 02:56:53 +00009082 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
thse4bcb142007-12-02 04:51:10 +00009083 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00009084
bellardc88676f2006-08-06 13:36:11 +00009085 register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
9086 register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00009087
bellard313aa562003-08-10 21:52:11 +00009088 /* terminal init */
ths740733b2007-06-08 01:57:56 +00009089 memset(&display_state, 0, sizeof(display_state));
bellarda20dd502003-09-30 21:07:02 +00009090 if (nographic) {
balrog4d3b6f62008-02-10 16:33:14 +00009091 if (curses) {
9092 fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
9093 exit(1);
9094 }
ths2ff89792007-06-21 23:34:19 +00009095 /* nearly nothing to do */
9096 dumb_display_init(ds);
ths73fc9742006-12-22 02:09:07 +00009097 } else if (vnc_display != NULL) {
ths71cab5c2007-08-25 01:35:38 +00009098 vnc_display_init(ds);
9099 if (vnc_display_open(ds, vnc_display) < 0)
9100 exit(1);
balrog4d3b6f62008-02-10 16:33:14 +00009101 } else
9102#if defined(CONFIG_CURSES)
9103 if (curses) {
9104 curses_display_init(ds, full_screen);
9105 } else
9106#endif
9107 {
bellard5b0753e2005-03-01 21:37:28 +00009108#if defined(CONFIG_SDL)
ths43523e92007-02-18 18:19:32 +00009109 sdl_display_init(ds, full_screen, no_frame);
bellard5b0753e2005-03-01 21:37:28 +00009110#elif defined(CONFIG_COCOA)
9111 cocoa_display_init(ds, full_screen);
pbrook67276f52007-11-15 19:04:08 +00009112#else
9113 dumb_display_init(ds);
bellard313aa562003-08-10 21:52:11 +00009114#endif
9115 }
bellard0824d6f2003-06-24 13:42:40 +00009116
aliguori5b08fc12008-08-21 20:08:03 +00009117#ifndef _WIN32
9118 /* must be after terminal init, SDL library changes signal handlers */
9119 termsig_setup();
9120#endif
9121
ths20d8a3e2007-02-18 17:04:49 +00009122 /* Maintain compatibility with multiple stdio monitors */
9123 if (!strcmp(monitor_device,"stdio")) {
9124 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
pbrookfd5f3932008-03-26 20:55:43 +00009125 const char *devname = serial_devices[i];
9126 if (devname && !strcmp(devname,"mon:stdio")) {
9127 monitor_device = NULL;
ths20d8a3e2007-02-18 17:04:49 +00009128 break;
pbrookfd5f3932008-03-26 20:55:43 +00009129 } else if (devname && !strcmp(devname,"stdio")) {
9130 monitor_device = NULL;
9131 serial_devices[i] = "mon:stdio";
ths20d8a3e2007-02-18 17:04:49 +00009132 break;
9133 }
9134 }
bellard82c643f2004-07-14 17:28:13 +00009135 }
pbrookfd5f3932008-03-26 20:55:43 +00009136 if (monitor_device) {
ths20d8a3e2007-02-18 17:04:49 +00009137 monitor_hd = qemu_chr_open(monitor_device);
9138 if (!monitor_hd) {
9139 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
9140 exit(1);
9141 }
9142 monitor_init(monitor_hd, !nographic);
9143 }
bellard82c643f2004-07-14 17:28:13 +00009144
bellard8d11df92004-08-24 21:13:40 +00009145 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00009146 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00009147 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00009148 serial_hds[i] = qemu_chr_open(devname);
bellard8d11df92004-08-24 21:13:40 +00009149 if (!serial_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00009150 fprintf(stderr, "qemu: could not open serial device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00009151 devname);
bellard8d11df92004-08-24 21:13:40 +00009152 exit(1);
9153 }
thsaf3a9032007-07-11 23:14:59 +00009154 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00009155 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00009156 }
bellard82c643f2004-07-14 17:28:13 +00009157 }
bellard82c643f2004-07-14 17:28:13 +00009158
bellard6508fe52005-01-15 12:02:56 +00009159 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00009160 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00009161 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00009162 parallel_hds[i] = qemu_chr_open(devname);
bellard6508fe52005-01-15 12:02:56 +00009163 if (!parallel_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00009164 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00009165 devname);
bellard6508fe52005-01-15 12:02:56 +00009166 exit(1);
9167 }
thsaf3a9032007-07-11 23:14:59 +00009168 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00009169 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00009170 }
9171 }
9172
blueswir1b881c2c2007-11-18 08:46:58 +00009173 machine->init(ram_size, vga_ram_size, boot_devices, ds,
j_mayer94fc95c2007-03-05 19:44:02 +00009174 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
bellard73332e52004-04-04 20:22:28 +00009175
pbrook0d92ed32006-05-21 16:30:15 +00009176 /* init USB devices */
9177 if (usb_enabled) {
9178 for(i = 0; i < usb_devices_index; i++) {
9179 if (usb_device_add(usb_devices[i]) < 0) {
9180 fprintf(stderr, "Warning: could not add USB device %s\n",
9181 usb_devices[i]);
9182 }
9183 }
9184 }
9185
ths740733b2007-06-08 01:57:56 +00009186 if (display_state.dpy_refresh) {
9187 display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
9188 qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
9189 }
bellard7f7f9872003-10-30 01:11:23 +00009190
bellard67b915a2004-03-31 23:37:16 +00009191#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00009192 if (use_gdbstub) {
bellardc636bb62007-02-05 20:46:05 +00009193 /* XXX: use standard host:port notation and modify options
9194 accordingly. */
pbrookcfc34752007-02-22 01:48:01 +00009195 if (gdbserver_start(gdbstub_port) < 0) {
9196 fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
bellardc636bb62007-02-05 20:46:05 +00009197 gdbstub_port);
bellard8a7ddc32004-03-31 19:00:16 +00009198 exit(1);
bellard8a7ddc32004-03-31 19:00:16 +00009199 }
balrog45669e02007-07-02 13:20:17 +00009200 }
bellard67b915a2004-03-31 23:37:16 +00009201#endif
balrog45669e02007-07-02 13:20:17 +00009202
bellardd63d3072004-10-03 13:29:03 +00009203 if (loadvm)
bellardfaea38e2006-08-05 21:31:00 +00009204 do_loadvm(loadvm);
bellardd63d3072004-10-03 13:29:03 +00009205
bellard67b915a2004-03-31 23:37:16 +00009206 {
bellard5905b2e2004-08-01 21:53:26 +00009207 /* XXX: simplify init */
aliguori83ab7952008-08-19 14:44:22 +00009208 read_passwords();
pbrook3c07f8e2007-01-21 16:47:01 +00009209 if (autostart) {
bellard5905b2e2004-08-01 21:53:26 +00009210 vm_start();
9211 }
bellard0824d6f2003-06-24 13:42:40 +00009212 }
thsffd843b2006-12-21 19:46:43 +00009213
ths71e3ceb2006-12-22 02:11:31 +00009214 if (daemonize) {
9215 uint8_t status = 0;
9216 ssize_t len;
9217 int fd;
9218
9219 again1:
9220 len = write(fds[1], &status, 1);
9221 if (len == -1 && (errno == EINTR))
9222 goto again1;
9223
9224 if (len != 1)
9225 exit(1);
9226
aliguoribd54b862008-07-23 00:58:33 +00009227 chdir("/");
balrogaeb30be2007-07-02 15:03:13 +00009228 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00009229 if (fd == -1)
9230 exit(1);
9231
9232 dup2(fd, 0);
9233 dup2(fd, 1);
9234 dup2(fd, 2);
9235
9236 close(fd);
9237 }
9238
bellard8a7ddc32004-03-31 19:00:16 +00009239 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00009240 quit_timers();
thsb46a8902007-10-21 23:20:45 +00009241
ths7d294b62007-10-26 17:21:58 +00009242#if !defined(_WIN32)
thsb46a8902007-10-21 23:20:45 +00009243 /* close network clients */
9244 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
9245 VLANClientState *vc;
9246
ths7d294b62007-10-26 17:21:58 +00009247 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
thsb46a8902007-10-21 23:20:45 +00009248 if (vc->fd_read == tap_receive) {
9249 char ifname[64];
9250 TAPState *s = vc->opaque;
9251
9252 if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
9253 s->down_script[0])
9254 launch_script(s->down_script, ifname, s->fd);
9255 }
ths8a16d272008-07-19 09:56:24 +00009256#if defined(CONFIG_VDE)
9257 if (vc->fd_read == vde_from_qemu) {
9258 VDEState *s = vc->opaque;
9259 vde_close(s->vde);
9260 }
9261#endif
ths4fddf622007-12-17 04:42:29 +00009262 }
ths7d294b62007-10-26 17:21:58 +00009263 }
9264#endif
bellard0824d6f2003-06-24 13:42:40 +00009265 return 0;
9266}