blob: c8db57983b146ffb138896e554fd4771b569899a [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>
bellard83fb7ad2004-07-05 21:25:26 +000064#ifndef __APPLE__
bellard7d3505c2004-05-12 19:32:15 +000065#include <libutil.h>
bellard83fb7ad2004-07-05 21:25:26 +000066#endif
ths5c40d2b2007-06-23 16:03:36 +000067#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
68#include <freebsd/stdlib.h>
bellard7d3505c2004-05-12 19:32:15 +000069#else
bellardec530c82006-04-25 22:36:06 +000070#ifndef __sun__
bellardf1510b22003-06-25 00:07:40 +000071#include <linux/if.h>
72#include <linux/if_tun.h>
bellard7d3505c2004-05-12 19:32:15 +000073#include <pty.h>
74#include <malloc.h>
bellardfd872592004-05-12 19:11:15 +000075#include <linux/rtc.h>
thsbd494f42007-09-16 20:03:23 +000076
77/* For the benefit of older linux systems which don't supply it,
78 we use a local copy of hpet.h. */
79/* #include <linux/hpet.h> */
80#include "hpet.h"
81
bellarde57a8c02005-11-10 23:58:52 +000082#include <linux/ppdev.h>
ths5867c882007-02-17 23:44:43 +000083#include <linux/parport.h>
thsd5d10bc2007-02-17 22:54:49 +000084#else
85#include <sys/stat.h>
86#include <sys/ethernet.h>
87#include <sys/sockio.h>
thsd5d10bc2007-02-17 22:54:49 +000088#include <netinet/arp.h>
89#include <netinet/in.h>
90#include <netinet/in_systm.h>
91#include <netinet/ip.h>
92#include <netinet/ip_icmp.h> // must come after ip.h
93#include <netinet/udp.h>
94#include <netinet/tcp.h>
95#include <net/if.h>
96#include <syslog.h>
97#include <stropts.h>
bellard67b915a2004-03-31 23:37:16 +000098#endif
bellard7d3505c2004-05-12 19:32:15 +000099#endif
thscb4b9762007-09-13 12:39:35 +0000100#else
101#include <winsock2.h>
102int inet_aton(const char *cp, struct in_addr *ia);
bellardec530c82006-04-25 22:36:06 +0000103#endif
bellard67b915a2004-03-31 23:37:16 +0000104
bellardc20709a2004-04-21 23:27:19 +0000105#if defined(CONFIG_SLIRP)
106#include "libslirp.h"
107#endif
108
bellard67b915a2004-03-31 23:37:16 +0000109#ifdef _WIN32
bellard7d3505c2004-05-12 19:32:15 +0000110#include <malloc.h>
bellard67b915a2004-03-31 23:37:16 +0000111#include <sys/timeb.h>
ths4fddf622007-12-17 04:42:29 +0000112#include <mmsystem.h>
bellard67b915a2004-03-31 23:37:16 +0000113#define getopt_long_only getopt_long
114#define memalign(align, size) malloc(size)
115#endif
116
bellard6ca957f2006-04-30 22:53:25 +0000117#include "qemu_socket.h"
118
bellard73332e52004-04-04 20:22:28 +0000119#ifdef CONFIG_SDL
bellard96bcd4f2004-07-10 16:26:15 +0000120#ifdef __APPLE__
bellard83fb7ad2004-07-05 21:25:26 +0000121#include <SDL/SDL.h>
bellard96bcd4f2004-07-10 16:26:15 +0000122#endif
bellard73332e52004-04-04 20:22:28 +0000123#endif /* CONFIG_SDL */
bellard0824d6f2003-06-24 13:42:40 +0000124
bellard5b0753e2005-03-01 21:37:28 +0000125#ifdef CONFIG_COCOA
126#undef main
127#define main qemu_main
128#endif /* CONFIG_COCOA */
129
bellard0824d6f2003-06-24 13:42:40 +0000130#include "disas.h"
bellardfc01f7e2003-06-30 10:03:06 +0000131
bellard8a7ddc32004-03-31 19:00:16 +0000132#include "exec-all.h"
bellard0824d6f2003-06-24 13:42:40 +0000133
bellard5a671352003-10-01 00:13:48 +0000134#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
thsb46a8902007-10-21 23:20:45 +0000135#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
pbrooka14d6c82006-12-23 15:37:33 +0000136#ifdef __sun__
137#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
138#else
139#define SMBD_COMMAND "/usr/sbin/smbd"
140#endif
bellardf1510b22003-06-25 00:07:40 +0000141
bellard0824d6f2003-06-24 13:42:40 +0000142//#define DEBUG_UNUSED_IOPORT
bellardfd872592004-05-12 19:11:15 +0000143//#define DEBUG_IOPORT
bellard330d0412003-07-26 18:11:40 +0000144
bellard77d4bc32004-05-26 22:13:53 +0000145#ifdef TARGET_PPC
146#define DEFAULT_RAM_SIZE 144
147#else
bellard1bfe8562004-07-08 21:17:50 +0000148#define DEFAULT_RAM_SIZE 128
bellard77d4bc32004-05-26 22:13:53 +0000149#endif
bellard8a7ddc32004-03-31 19:00:16 +0000150/* in ms */
151#define GUI_REFRESH_INTERVAL 30
bellard313aa562003-08-10 21:52:11 +0000152
pbrook0d92ed32006-05-21 16:30:15 +0000153/* Max number of USB devices that can be specified on the commandline. */
154#define MAX_USB_CMDLINE 8
155
bellard7dea1da2003-11-16 15:59:30 +0000156/* XXX: use a two level table to limit memory usage */
157#define MAX_IOPORTS 65536
bellard0824d6f2003-06-24 13:42:40 +0000158
bellard80cabfa2004-03-14 12:20:30 +0000159const char *bios_dir = CONFIG_QEMU_SHAREDIR;
j_mayer1192dad2007-10-05 13:08:35 +0000160const char *bios_name = NULL;
bellardc4b1fcc2004-03-14 21:44:30 +0000161void *ioport_opaque[MAX_IOPORTS];
bellardfc01f7e2003-06-30 10:03:06 +0000162IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
163IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
thse4bcb142007-12-02 04:51:10 +0000164/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
bellardfaea38e2006-08-05 21:31:00 +0000165 to store the VM snapshots */
thse4bcb142007-12-02 04:51:10 +0000166DriveInfo drives_table[MAX_DRIVES+1];
167int nb_drives;
bellardfaea38e2006-08-05 21:31:00 +0000168/* point to the block driver where the snapshots are managed */
169BlockDriverState *bs_snapshots;
bellard313aa562003-08-10 21:52:11 +0000170int vga_ram_size;
171static DisplayState display_state;
bellarda20dd502003-09-30 21:07:02 +0000172int nographic;
balrog4d3b6f62008-02-10 16:33:14 +0000173int curses;
bellard3d11d0e2004-12-12 16:56:30 +0000174const char* keyboard_layout = NULL;
bellard313aa562003-08-10 21:52:11 +0000175int64_t ticks_per_sec;
aurel3200f82b82008-04-27 21:12:55 +0000176ram_addr_t ram_size;
bellard80cabfa2004-03-14 12:20:30 +0000177int pit_min_timer_count = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000178int nb_nics;
bellard7c9d8e02005-11-15 22:16:05 +0000179NICInfo nd_table[MAX_NICS];
bellard8a7ddc32004-03-31 19:00:16 +0000180int vm_running;
balrogf6503052008-02-17 11:42:19 +0000181static int rtc_utc = 1;
182static int rtc_date_offset = -1; /* -1 means no change */
bellard1bfe8562004-07-08 21:17:50 +0000183int cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +0000184int vmsvga_enabled = 0;
bellardd8272202005-04-06 20:32:23 +0000185#ifdef TARGET_SPARC
186int graphic_width = 1024;
187int graphic_height = 768;
blueswir1eee0b832007-04-21 19:45:49 +0000188int graphic_depth = 8;
bellardd8272202005-04-06 20:32:23 +0000189#else
bellard1bfe8562004-07-08 21:17:50 +0000190int graphic_width = 800;
191int graphic_height = 600;
bellarde9b137c2004-06-21 16:46:10 +0000192int graphic_depth = 15;
blueswir1eee0b832007-04-21 19:45:49 +0000193#endif
bellardd63d3072004-10-03 13:29:03 +0000194int full_screen = 0;
ths43523e92007-02-18 18:19:32 +0000195int no_frame = 0;
ths667acca2006-12-11 02:08:05 +0000196int no_quit = 0;
bellard8d11df92004-08-24 21:13:40 +0000197CharDriverState *serial_hds[MAX_SERIAL_PORTS];
bellard6508fe52005-01-15 12:02:56 +0000198CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
bellarda09db212005-04-30 16:10:35 +0000199#ifdef TARGET_I386
200int win2k_install_hack = 0;
201#endif
bellardbb36d472005-11-05 14:22:28 +0000202int usb_enabled = 0;
bellard7c9d8e02005-11-15 22:16:05 +0000203static VLANState *first_vlan;
bellard6a00d602005-11-21 23:25:50 +0000204int smp_cpus = 1;
ths73fc9742006-12-22 02:09:07 +0000205const char *vnc_display;
bellardd3e9db92005-12-17 01:27:28 +0000206#if defined(TARGET_SPARC)
bellardba3c64f2005-12-05 20:31:52 +0000207#define MAX_CPUS 16
bellardd3e9db92005-12-17 01:27:28 +0000208#elif defined(TARGET_I386)
209#define MAX_CPUS 255
bellardba3c64f2005-12-05 20:31:52 +0000210#else
bellardd3e9db92005-12-17 01:27:28 +0000211#define MAX_CPUS 1
bellardba3c64f2005-12-05 20:31:52 +0000212#endif
bellard6515b202006-05-03 22:02:44 +0000213int acpi_enabled = 1;
bellard52ca8d62006-06-14 16:03:05 +0000214int fd_bootchk = 1;
bellardd1beab82006-10-02 19:44:22 +0000215int no_reboot = 0;
aurel32b2f76162008-04-11 21:35:52 +0000216int no_shutdown = 0;
balrog9467cd42007-05-01 01:34:14 +0000217int cursor_hide = 1;
balroga171fe32007-04-30 01:48:07 +0000218int graphic_rotate = 0;
ths71e3ceb2006-12-22 02:11:31 +0000219int daemonize = 0;
ths9ae02552007-01-05 17:39:04 +0000220const char *option_rom[MAX_OPTION_ROMS];
221int nb_option_roms;
pbrook8e716212007-01-20 17:12:09 +0000222int semihosting_enabled = 0;
pbrook3c07f8e2007-01-21 16:47:01 +0000223int autostart = 1;
balrog2b8f2d42007-07-27 22:08:46 +0000224#ifdef TARGET_ARM
225int old_param = 0;
226#endif
thsc35734b2007-03-19 15:17:08 +0000227const char *qemu_name;
ths3780e192007-06-21 21:08:02 +0000228int alt_grab = 0;
blueswir166508602007-05-01 14:16:52 +0000229#ifdef TARGET_SPARC
230unsigned int nb_prom_envs = 0;
231const char *prom_envs[MAX_PROM_ENVS];
232#endif
thse4bcb142007-12-02 04:51:10 +0000233int nb_drives_opt;
balrog609497a2008-01-14 02:56:53 +0000234struct drive_opt {
235 const char *file;
236 char opt[1024];
237} drives_opt[MAX_DRIVES];
bellard0824d6f2003-06-24 13:42:40 +0000238
balrogee5605e2007-12-03 03:01:40 +0000239static CPUState *cur_cpu;
240static CPUState *next_cpu;
balrog76ea08f2007-12-16 11:48:54 +0000241static int event_pending = 1;
thsbf20dc02008-06-30 17:22:19 +0000242/* Conversion factor from emulated instructions to virtual clock ticks. */
pbrook2e70f6e2008-06-29 01:03:05 +0000243static int icount_time_shift;
thsbf20dc02008-06-30 17:22:19 +0000244/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
pbrook2e70f6e2008-06-29 01:03:05 +0000245#define MAX_ICOUNT_SHIFT 10
246/* Compensate for varying guest execution speed. */
247static int64_t qemu_icount_bias;
248QEMUTimer *icount_rt_timer;
249QEMUTimer *icount_vm_timer;
balrogee5605e2007-12-03 03:01:40 +0000250
balrogaeb30be2007-07-02 15:03:13 +0000251#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
252
bellard0824d6f2003-06-24 13:42:40 +0000253/***********************************************************/
bellard26aa7d72004-04-28 22:26:05 +0000254/* x86 ISA bus support */
255
256target_phys_addr_t isa_mem_base = 0;
bellard3de388f2005-07-02 18:11:44 +0000257PicState2 *isa_pic;
bellard0824d6f2003-06-24 13:42:40 +0000258
pbrook9596ebb2007-11-18 01:44:38 +0000259static uint32_t default_ioport_readb(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000260{
261#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000262 fprintf(stderr, "unused inb: port=0x%04x\n", address);
bellard0824d6f2003-06-24 13:42:40 +0000263#endif
bellardfc01f7e2003-06-30 10:03:06 +0000264 return 0xff;
bellard0824d6f2003-06-24 13:42:40 +0000265}
266
pbrook9596ebb2007-11-18 01:44:38 +0000267static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000268{
269#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000270 fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
bellard0824d6f2003-06-24 13:42:40 +0000271#endif
272}
273
274/* default is to make two byte accesses */
pbrook9596ebb2007-11-18 01:44:38 +0000275static uint32_t default_ioport_readw(void *opaque, uint32_t address)
bellard0824d6f2003-06-24 13:42:40 +0000276{
277 uint32_t data;
bellarddb45c292004-05-12 19:50:26 +0000278 data = ioport_read_table[0][address](ioport_opaque[address], address);
279 address = (address + 1) & (MAX_IOPORTS - 1);
280 data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
bellard0824d6f2003-06-24 13:42:40 +0000281 return data;
282}
283
pbrook9596ebb2007-11-18 01:44:38 +0000284static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
bellard0824d6f2003-06-24 13:42:40 +0000285{
bellarddb45c292004-05-12 19:50:26 +0000286 ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
287 address = (address + 1) & (MAX_IOPORTS - 1);
288 ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
bellardfc01f7e2003-06-30 10:03:06 +0000289}
290
pbrook9596ebb2007-11-18 01:44:38 +0000291static uint32_t default_ioport_readl(void *opaque, uint32_t address)
bellardfc01f7e2003-06-30 10:03:06 +0000292{
293#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000294 fprintf(stderr, "unused inl: port=0x%04x\n", address);
bellardfc01f7e2003-06-30 10:03:06 +0000295#endif
296 return 0xffffffff;
297}
298
pbrook9596ebb2007-11-18 01:44:38 +0000299static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
bellardfc01f7e2003-06-30 10:03:06 +0000300{
301#ifdef DEBUG_UNUSED_IOPORT
ths1196be32007-03-17 15:17:58 +0000302 fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
bellardfc01f7e2003-06-30 10:03:06 +0000303#endif
bellard0824d6f2003-06-24 13:42:40 +0000304}
305
pbrook9596ebb2007-11-18 01:44:38 +0000306static void init_ioports(void)
bellard0824d6f2003-06-24 13:42:40 +0000307{
308 int i;
309
310 for(i = 0; i < MAX_IOPORTS; i++) {
bellardfc01f7e2003-06-30 10:03:06 +0000311 ioport_read_table[0][i] = default_ioport_readb;
312 ioport_write_table[0][i] = default_ioport_writeb;
313 ioport_read_table[1][i] = default_ioport_readw;
314 ioport_write_table[1][i] = default_ioport_writew;
315 ioport_read_table[2][i] = default_ioport_readl;
316 ioport_write_table[2][i] = default_ioport_writel;
bellard0824d6f2003-06-24 13:42:40 +0000317 }
318}
319
bellardfc01f7e2003-06-30 10:03:06 +0000320/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000321int register_ioport_read(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000322 IOPortReadFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000323{
bellardfc01f7e2003-06-30 10:03:06 +0000324 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000325
bellardc4b1fcc2004-03-14 21:44:30 +0000326 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000327 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000328 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000329 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000330 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000331 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000332 } else {
balrog88fdf562008-04-26 21:11:22 +0000333 hw_error("register_ioport_read: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000334 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000335 }
336 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000337 ioport_read_table[bsize][i] = func;
bellardc4b1fcc2004-03-14 21:44:30 +0000338 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
balrog88fdf562008-04-26 21:11:22 +0000339 hw_error("register_ioport_read: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000340 ioport_opaque[i] = opaque;
341 }
bellard0824d6f2003-06-24 13:42:40 +0000342 return 0;
343}
344
bellardfc01f7e2003-06-30 10:03:06 +0000345/* size is the word size in byte */
ths5fafdf22007-09-16 21:08:06 +0000346int register_ioport_write(int start, int length, int size,
bellardc4b1fcc2004-03-14 21:44:30 +0000347 IOPortWriteFunc *func, void *opaque)
bellard0824d6f2003-06-24 13:42:40 +0000348{
bellardfc01f7e2003-06-30 10:03:06 +0000349 int i, bsize;
bellard0824d6f2003-06-24 13:42:40 +0000350
bellardc4b1fcc2004-03-14 21:44:30 +0000351 if (size == 1) {
bellardfc01f7e2003-06-30 10:03:06 +0000352 bsize = 0;
bellardc4b1fcc2004-03-14 21:44:30 +0000353 } else if (size == 2) {
bellardfc01f7e2003-06-30 10:03:06 +0000354 bsize = 1;
bellardc4b1fcc2004-03-14 21:44:30 +0000355 } else if (size == 4) {
bellardfc01f7e2003-06-30 10:03:06 +0000356 bsize = 2;
bellardc4b1fcc2004-03-14 21:44:30 +0000357 } else {
balrog88fdf562008-04-26 21:11:22 +0000358 hw_error("register_ioport_write: invalid size");
bellardfc01f7e2003-06-30 10:03:06 +0000359 return -1;
bellardc4b1fcc2004-03-14 21:44:30 +0000360 }
361 for(i = start; i < start + length; i += size) {
bellardfc01f7e2003-06-30 10:03:06 +0000362 ioport_write_table[bsize][i] = func;
balrog88fdf562008-04-26 21:11:22 +0000363 if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
364 hw_error("register_ioport_write: invalid opaque");
bellardc4b1fcc2004-03-14 21:44:30 +0000365 ioport_opaque[i] = opaque;
366 }
bellardf1510b22003-06-25 00:07:40 +0000367 return 0;
368}
369
bellard69b91032004-05-18 23:05:28 +0000370void isa_unassign_ioport(int start, int length)
371{
372 int i;
373
374 for(i = start; i < start + length; i++) {
375 ioport_read_table[0][i] = default_ioport_readb;
376 ioport_read_table[1][i] = default_ioport_readw;
377 ioport_read_table[2][i] = default_ioport_readl;
378
379 ioport_write_table[0][i] = default_ioport_writeb;
380 ioport_write_table[1][i] = default_ioport_writew;
381 ioport_write_table[2][i] = default_ioport_writel;
382 }
383}
384
bellard20f32282005-01-03 23:36:21 +0000385/***********************************************************/
386
bellardc45886d2004-01-05 00:02:06 +0000387void cpu_outb(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000388{
bellardfd872592004-05-12 19:11:15 +0000389#ifdef DEBUG_IOPORT
390 if (loglevel & CPU_LOG_IOPORT)
391 fprintf(logfile, "outb: %04x %02x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000392#endif
bellardc4b1fcc2004-03-14 21:44:30 +0000393 ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
bellard89bfc102006-02-08 22:46:31 +0000394#ifdef USE_KQEMU
395 if (env)
396 env->last_io_time = cpu_get_time_fast();
397#endif
bellard0824d6f2003-06-24 13:42:40 +0000398}
399
bellardc45886d2004-01-05 00:02:06 +0000400void cpu_outw(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000401{
bellardfd872592004-05-12 19:11:15 +0000402#ifdef DEBUG_IOPORT
403 if (loglevel & CPU_LOG_IOPORT)
404 fprintf(logfile, "outw: %04x %04x\n", addr, val);
ths3b46e622007-09-17 08:09:54 +0000405#endif
bellardc4b1fcc2004-03-14 21:44:30 +0000406 ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
bellard89bfc102006-02-08 22:46:31 +0000407#ifdef USE_KQEMU
408 if (env)
409 env->last_io_time = cpu_get_time_fast();
410#endif
bellard0824d6f2003-06-24 13:42:40 +0000411}
412
bellardc45886d2004-01-05 00:02:06 +0000413void cpu_outl(CPUState *env, int addr, int val)
bellard0824d6f2003-06-24 13:42:40 +0000414{
bellardfd872592004-05-12 19:11:15 +0000415#ifdef DEBUG_IOPORT
416 if (loglevel & CPU_LOG_IOPORT)
417 fprintf(logfile, "outl: %04x %08x\n", addr, val);
418#endif
bellardc4b1fcc2004-03-14 21:44:30 +0000419 ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
bellard89bfc102006-02-08 22:46:31 +0000420#ifdef USE_KQEMU
421 if (env)
422 env->last_io_time = cpu_get_time_fast();
423#endif
bellard0824d6f2003-06-24 13:42:40 +0000424}
425
bellardc45886d2004-01-05 00:02:06 +0000426int cpu_inb(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000427{
bellardfd872592004-05-12 19:11:15 +0000428 int val;
bellardfd872592004-05-12 19:11:15 +0000429 val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
430#ifdef DEBUG_IOPORT
431 if (loglevel & CPU_LOG_IOPORT)
432 fprintf(logfile, "inb : %04x %02x\n", addr, val);
433#endif
bellard89bfc102006-02-08 22:46:31 +0000434#ifdef USE_KQEMU
435 if (env)
436 env->last_io_time = cpu_get_time_fast();
437#endif
bellardfd872592004-05-12 19:11:15 +0000438 return val;
bellard0824d6f2003-06-24 13:42:40 +0000439}
440
bellardc45886d2004-01-05 00:02:06 +0000441int cpu_inw(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000442{
bellardfd872592004-05-12 19:11:15 +0000443 int val;
bellardfd872592004-05-12 19:11:15 +0000444 val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
445#ifdef DEBUG_IOPORT
446 if (loglevel & CPU_LOG_IOPORT)
447 fprintf(logfile, "inw : %04x %04x\n", addr, val);
448#endif
bellard89bfc102006-02-08 22:46:31 +0000449#ifdef USE_KQEMU
450 if (env)
451 env->last_io_time = cpu_get_time_fast();
452#endif
bellardfd872592004-05-12 19:11:15 +0000453 return val;
bellard0824d6f2003-06-24 13:42:40 +0000454}
455
bellardc45886d2004-01-05 00:02:06 +0000456int cpu_inl(CPUState *env, int addr)
bellard0824d6f2003-06-24 13:42:40 +0000457{
bellardfd872592004-05-12 19:11:15 +0000458 int val;
bellardfd872592004-05-12 19:11:15 +0000459 val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
460#ifdef DEBUG_IOPORT
461 if (loglevel & CPU_LOG_IOPORT)
462 fprintf(logfile, "inl : %04x %08x\n", addr, val);
463#endif
bellard89bfc102006-02-08 22:46:31 +0000464#ifdef USE_KQEMU
465 if (env)
466 env->last_io_time = cpu_get_time_fast();
467#endif
bellardfd872592004-05-12 19:11:15 +0000468 return val;
bellard0824d6f2003-06-24 13:42:40 +0000469}
470
471/***********************************************************/
bellard0824d6f2003-06-24 13:42:40 +0000472void hw_error(const char *fmt, ...)
473{
474 va_list ap;
bellard6a00d602005-11-21 23:25:50 +0000475 CPUState *env;
bellard0824d6f2003-06-24 13:42:40 +0000476
477 va_start(ap, fmt);
478 fprintf(stderr, "qemu: hardware error: ");
479 vfprintf(stderr, fmt, ap);
480 fprintf(stderr, "\n");
bellard6a00d602005-11-21 23:25:50 +0000481 for(env = first_cpu; env != NULL; env = env->next_cpu) {
482 fprintf(stderr, "CPU #%d:\n", env->cpu_index);
bellard0824d6f2003-06-24 13:42:40 +0000483#ifdef TARGET_I386
bellard6a00d602005-11-21 23:25:50 +0000484 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
bellardc45886d2004-01-05 00:02:06 +0000485#else
bellard6a00d602005-11-21 23:25:50 +0000486 cpu_dump_state(env, stderr, fprintf, 0);
bellard0824d6f2003-06-24 13:42:40 +0000487#endif
bellard6a00d602005-11-21 23:25:50 +0000488 }
bellard0824d6f2003-06-24 13:42:40 +0000489 va_end(ap);
490 abort();
491}
492
bellard8a7ddc32004-03-31 19:00:16 +0000493/***********************************************************/
bellard63066f42004-06-03 18:45:02 +0000494/* keyboard/mouse */
495
496static QEMUPutKBDEvent *qemu_put_kbd_event;
497static void *qemu_put_kbd_event_opaque;
ths455204e2007-01-05 16:42:13 +0000498static QEMUPutMouseEntry *qemu_put_mouse_event_head;
499static QEMUPutMouseEntry *qemu_put_mouse_event_current;
bellard63066f42004-06-03 18:45:02 +0000500
501void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
502{
503 qemu_put_kbd_event_opaque = opaque;
504 qemu_put_kbd_event = func;
505}
506
ths455204e2007-01-05 16:42:13 +0000507QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
508 void *opaque, int absolute,
509 const char *name)
bellard63066f42004-06-03 18:45:02 +0000510{
ths455204e2007-01-05 16:42:13 +0000511 QEMUPutMouseEntry *s, *cursor;
512
513 s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
514 if (!s)
515 return NULL;
516
517 s->qemu_put_mouse_event = func;
518 s->qemu_put_mouse_event_opaque = opaque;
519 s->qemu_put_mouse_event_absolute = absolute;
520 s->qemu_put_mouse_event_name = qemu_strdup(name);
521 s->next = NULL;
522
523 if (!qemu_put_mouse_event_head) {
524 qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
525 return s;
526 }
527
528 cursor = qemu_put_mouse_event_head;
529 while (cursor->next != NULL)
530 cursor = cursor->next;
531
532 cursor->next = s;
533 qemu_put_mouse_event_current = s;
534
535 return s;
536}
537
538void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
539{
540 QEMUPutMouseEntry *prev = NULL, *cursor;
541
542 if (!qemu_put_mouse_event_head || entry == NULL)
543 return;
544
545 cursor = qemu_put_mouse_event_head;
546 while (cursor != NULL && cursor != entry) {
547 prev = cursor;
548 cursor = cursor->next;
549 }
550
551 if (cursor == NULL) // does not exist or list empty
552 return;
553 else if (prev == NULL) { // entry is head
554 qemu_put_mouse_event_head = cursor->next;
555 if (qemu_put_mouse_event_current == entry)
556 qemu_put_mouse_event_current = cursor->next;
557 qemu_free(entry->qemu_put_mouse_event_name);
558 qemu_free(entry);
559 return;
560 }
561
562 prev->next = entry->next;
563
564 if (qemu_put_mouse_event_current == entry)
565 qemu_put_mouse_event_current = prev;
566
567 qemu_free(entry->qemu_put_mouse_event_name);
568 qemu_free(entry);
bellard63066f42004-06-03 18:45:02 +0000569}
570
571void kbd_put_keycode(int keycode)
572{
573 if (qemu_put_kbd_event) {
574 qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
575 }
576}
577
578void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
579{
ths455204e2007-01-05 16:42:13 +0000580 QEMUPutMouseEvent *mouse_event;
581 void *mouse_event_opaque;
balroga171fe32007-04-30 01:48:07 +0000582 int width;
ths455204e2007-01-05 16:42:13 +0000583
584 if (!qemu_put_mouse_event_current) {
585 return;
586 }
587
588 mouse_event =
589 qemu_put_mouse_event_current->qemu_put_mouse_event;
590 mouse_event_opaque =
591 qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
592
593 if (mouse_event) {
balroga171fe32007-04-30 01:48:07 +0000594 if (graphic_rotate) {
595 if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
596 width = 0x7fff;
597 else
aurel32b94ed572008-03-10 19:34:27 +0000598 width = graphic_width - 1;
balroga171fe32007-04-30 01:48:07 +0000599 mouse_event(mouse_event_opaque,
600 width - dy, dx, dz, buttons_state);
601 } else
602 mouse_event(mouse_event_opaque,
603 dx, dy, dz, buttons_state);
bellard63066f42004-06-03 18:45:02 +0000604 }
605}
606
bellard09b26c52006-04-12 21:09:08 +0000607int kbd_mouse_is_absolute(void)
608{
ths455204e2007-01-05 16:42:13 +0000609 if (!qemu_put_mouse_event_current)
610 return 0;
611
612 return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
613}
614
615void do_info_mice(void)
616{
617 QEMUPutMouseEntry *cursor;
618 int index = 0;
619
620 if (!qemu_put_mouse_event_head) {
621 term_printf("No mouse devices connected\n");
622 return;
623 }
624
625 term_printf("Mouse devices available:\n");
626 cursor = qemu_put_mouse_event_head;
627 while (cursor != NULL) {
628 term_printf("%c Mouse #%d: %s\n",
629 (cursor == qemu_put_mouse_event_current ? '*' : ' '),
630 index, cursor->qemu_put_mouse_event_name);
631 index++;
632 cursor = cursor->next;
633 }
634}
635
636void do_mouse_set(int index)
637{
638 QEMUPutMouseEntry *cursor;
639 int i = 0;
640
641 if (!qemu_put_mouse_event_head) {
642 term_printf("No mouse devices connected\n");
643 return;
644 }
645
646 cursor = qemu_put_mouse_event_head;
647 while (cursor != NULL && index != i) {
648 i++;
649 cursor = cursor->next;
650 }
651
652 if (cursor != NULL)
653 qemu_put_mouse_event_current = cursor;
654 else
655 term_printf("Mouse at given index not found\n");
bellard09b26c52006-04-12 21:09:08 +0000656}
657
bellard87858c82003-06-27 12:01:39 +0000658/* compute with 96 bit intermediate result: (a*b)/c */
bellard80cabfa2004-03-14 12:20:30 +0000659uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
bellard87858c82003-06-27 12:01:39 +0000660{
661 union {
662 uint64_t ll;
663 struct {
664#ifdef WORDS_BIGENDIAN
665 uint32_t high, low;
666#else
667 uint32_t low, high;
ths3b46e622007-09-17 08:09:54 +0000668#endif
bellard87858c82003-06-27 12:01:39 +0000669 } l;
670 } u, res;
671 uint64_t rl, rh;
672
673 u.ll = a;
674 rl = (uint64_t)u.l.low * (uint64_t)b;
675 rh = (uint64_t)u.l.high * (uint64_t)b;
676 rh += (rl >> 32);
677 res.l.high = rh / c;
678 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
679 return res.ll;
680}
681
bellard1dce7c32006-07-13 23:20:22 +0000682/***********************************************************/
683/* real time host monotonic timer */
684
685#define QEMU_TIMER_BASE 1000000000LL
686
687#ifdef WIN32
688
689static int64_t clock_freq;
690
691static void init_get_clock(void)
692{
bellarda8e5ac32006-07-14 09:36:13 +0000693 LARGE_INTEGER freq;
694 int ret;
bellard1dce7c32006-07-13 23:20:22 +0000695 ret = QueryPerformanceFrequency(&freq);
696 if (ret == 0) {
697 fprintf(stderr, "Could not calibrate ticks\n");
698 exit(1);
699 }
700 clock_freq = freq.QuadPart;
701}
702
703static int64_t get_clock(void)
704{
705 LARGE_INTEGER ti;
706 QueryPerformanceCounter(&ti);
707 return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
708}
709
710#else
711
712static int use_rt_clock;
713
714static void init_get_clock(void)
715{
716 use_rt_clock = 0;
717#if defined(__linux__)
718 {
719 struct timespec ts;
720 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
721 use_rt_clock = 1;
722 }
723 }
724#endif
725}
726
727static int64_t get_clock(void)
728{
729#if defined(__linux__)
730 if (use_rt_clock) {
731 struct timespec ts;
732 clock_gettime(CLOCK_MONOTONIC, &ts);
733 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
ths5fafdf22007-09-16 21:08:06 +0000734 } else
bellard1dce7c32006-07-13 23:20:22 +0000735#endif
736 {
737 /* XXX: using gettimeofday leads to problems if the date
738 changes, so it should be avoided. */
739 struct timeval tv;
740 gettimeofday(&tv, NULL);
741 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
742 }
743}
bellard1dce7c32006-07-13 23:20:22 +0000744#endif
745
pbrook2e70f6e2008-06-29 01:03:05 +0000746/* Return the virtual CPU time, based on the instruction counter. */
747static int64_t cpu_get_icount(void)
748{
749 int64_t icount;
750 CPUState *env = cpu_single_env;;
751 icount = qemu_icount;
752 if (env) {
753 if (!can_do_io(env))
754 fprintf(stderr, "Bad clock read\n");
755 icount -= (env->icount_decr.u16.low + env->icount_extra);
756 }
757 return qemu_icount_bias + (icount << icount_time_shift);
758}
759
bellard1dce7c32006-07-13 23:20:22 +0000760/***********************************************************/
761/* guest cycle counter */
762
763static int64_t cpu_ticks_prev;
764static int64_t cpu_ticks_offset;
765static int64_t cpu_clock_offset;
766static int cpu_ticks_enabled;
767
768/* return the host CPU cycle counter and handle stop/restart */
769int64_t cpu_get_ticks(void)
770{
pbrook2e70f6e2008-06-29 01:03:05 +0000771 if (use_icount) {
772 return cpu_get_icount();
773 }
bellard1dce7c32006-07-13 23:20:22 +0000774 if (!cpu_ticks_enabled) {
775 return cpu_ticks_offset;
776 } else {
777 int64_t ticks;
778 ticks = cpu_get_real_ticks();
779 if (cpu_ticks_prev > ticks) {
780 /* Note: non increasing ticks may happen if the host uses
781 software suspend */
782 cpu_ticks_offset += cpu_ticks_prev - ticks;
783 }
784 cpu_ticks_prev = ticks;
785 return ticks + cpu_ticks_offset;
786 }
787}
788
789/* return the host CPU monotonic timer and handle stop/restart */
790static int64_t cpu_get_clock(void)
791{
792 int64_t ti;
793 if (!cpu_ticks_enabled) {
794 return cpu_clock_offset;
795 } else {
796 ti = get_clock();
797 return ti + cpu_clock_offset;
798 }
799}
800
801/* enable cpu_get_ticks() */
802void cpu_enable_ticks(void)
803{
804 if (!cpu_ticks_enabled) {
805 cpu_ticks_offset -= cpu_get_real_ticks();
806 cpu_clock_offset -= get_clock();
807 cpu_ticks_enabled = 1;
808 }
809}
810
811/* disable cpu_get_ticks() : the clock is stopped. You must not call
812 cpu_get_ticks() after that. */
813void cpu_disable_ticks(void)
814{
815 if (cpu_ticks_enabled) {
816 cpu_ticks_offset = cpu_get_ticks();
817 cpu_clock_offset = cpu_get_clock();
818 cpu_ticks_enabled = 0;
819 }
820}
821
822/***********************************************************/
823/* timers */
ths5fafdf22007-09-16 21:08:06 +0000824
bellard8a7ddc32004-03-31 19:00:16 +0000825#define QEMU_TIMER_REALTIME 0
826#define QEMU_TIMER_VIRTUAL 1
827
828struct QEMUClock {
829 int type;
830 /* XXX: add frequency */
831};
832
833struct QEMUTimer {
834 QEMUClock *clock;
835 int64_t expire_time;
836 QEMUTimerCB *cb;
837 void *opaque;
838 struct QEMUTimer *next;
839};
840
thsc8994012007-08-19 21:56:03 +0000841struct qemu_alarm_timer {
842 char const *name;
thsefe75412007-08-24 01:36:32 +0000843 unsigned int flags;
thsc8994012007-08-19 21:56:03 +0000844
845 int (*start)(struct qemu_alarm_timer *t);
846 void (*stop)(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000847 void (*rearm)(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000848 void *priv;
849};
850
thsefe75412007-08-24 01:36:32 +0000851#define ALARM_FLAG_DYNTICKS 0x1
balrogd5d08332008-01-05 19:41:47 +0000852#define ALARM_FLAG_EXPIRED 0x2
thsefe75412007-08-24 01:36:32 +0000853
854static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
855{
856 return t->flags & ALARM_FLAG_DYNTICKS;
857}
858
859static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
860{
861 if (!alarm_has_dynticks(t))
862 return;
863
864 t->rearm(t);
865}
866
867/* TODO: MIN_TIMER_REARM_US should be optimized */
868#define MIN_TIMER_REARM_US 250
869
thsc8994012007-08-19 21:56:03 +0000870static struct qemu_alarm_timer *alarm_timer;
871
872#ifdef _WIN32
873
874struct qemu_alarm_win32 {
875 MMRESULT timerId;
876 HANDLE host_alarm;
877 unsigned int period;
878} alarm_win32_data = {0, NULL, -1};
879
880static int win32_start_timer(struct qemu_alarm_timer *t);
881static void win32_stop_timer(struct qemu_alarm_timer *t);
thsefe75412007-08-24 01:36:32 +0000882static void win32_rearm_timer(struct qemu_alarm_timer *t);
thsc8994012007-08-19 21:56:03 +0000883
884#else
885
886static int unix_start_timer(struct qemu_alarm_timer *t);
887static void unix_stop_timer(struct qemu_alarm_timer *t);
888
ths231c6582007-08-26 17:29:15 +0000889#ifdef __linux__
890
thsefe75412007-08-24 01:36:32 +0000891static int dynticks_start_timer(struct qemu_alarm_timer *t);
892static void dynticks_stop_timer(struct qemu_alarm_timer *t);
893static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
894
thsc40ec5a2007-08-19 22:09:40 +0000895static int hpet_start_timer(struct qemu_alarm_timer *t);
896static void hpet_stop_timer(struct qemu_alarm_timer *t);
897
thsc8994012007-08-19 21:56:03 +0000898static int rtc_start_timer(struct qemu_alarm_timer *t);
899static void rtc_stop_timer(struct qemu_alarm_timer *t);
900
thsefe75412007-08-24 01:36:32 +0000901#endif /* __linux__ */
thsc8994012007-08-19 21:56:03 +0000902
903#endif /* _WIN32 */
904
pbrook2e70f6e2008-06-29 01:03:05 +0000905/* Correlation between real and virtual time is always going to be
thsbf20dc02008-06-30 17:22:19 +0000906 fairly approximate, so ignore small variation.
pbrook2e70f6e2008-06-29 01:03:05 +0000907 When the guest is idle real and virtual time will be aligned in
908 the IO wait loop. */
909#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
910
911static void icount_adjust(void)
912{
913 int64_t cur_time;
914 int64_t cur_icount;
915 int64_t delta;
916 static int64_t last_delta;
917 /* If the VM is not running, then do nothing. */
918 if (!vm_running)
919 return;
920
921 cur_time = cpu_get_clock();
922 cur_icount = qemu_get_clock(vm_clock);
923 delta = cur_icount - cur_time;
924 /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
925 if (delta > 0
926 && last_delta + ICOUNT_WOBBLE < delta * 2
927 && icount_time_shift > 0) {
928 /* The guest is getting too far ahead. Slow time down. */
929 icount_time_shift--;
930 }
931 if (delta < 0
932 && last_delta - ICOUNT_WOBBLE > delta * 2
933 && icount_time_shift < MAX_ICOUNT_SHIFT) {
934 /* The guest is getting too far behind. Speed time up. */
935 icount_time_shift++;
936 }
937 last_delta = delta;
938 qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift);
939}
940
941static void icount_adjust_rt(void * opaque)
942{
943 qemu_mod_timer(icount_rt_timer,
944 qemu_get_clock(rt_clock) + 1000);
945 icount_adjust();
946}
947
948static void icount_adjust_vm(void * opaque)
949{
950 qemu_mod_timer(icount_vm_timer,
951 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
952 icount_adjust();
953}
954
955static void init_icount_adjust(void)
956{
957 /* Have both realtime and virtual time triggers for speed adjustment.
958 The realtime trigger catches emulated time passing too slowly,
959 the virtual time trigger catches emulated time passing too fast.
960 Realtime triggers occur even when idle, so use them less frequently
961 than VM triggers. */
962 icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);
963 qemu_mod_timer(icount_rt_timer,
964 qemu_get_clock(rt_clock) + 1000);
965 icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
966 qemu_mod_timer(icount_vm_timer,
967 qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
968}
969
thsc8994012007-08-19 21:56:03 +0000970static struct qemu_alarm_timer alarm_timers[] = {
thsefe75412007-08-24 01:36:32 +0000971#ifndef _WIN32
ths231c6582007-08-26 17:29:15 +0000972#ifdef __linux__
thsefe75412007-08-24 01:36:32 +0000973 {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
974 dynticks_stop_timer, dynticks_rearm_timer, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000975 /* HPET - if available - is preferred */
thsefe75412007-08-24 01:36:32 +0000976 {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
thsc40ec5a2007-08-19 22:09:40 +0000977 /* ...otherwise try RTC */
thsefe75412007-08-24 01:36:32 +0000978 {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000979#endif
thsefe75412007-08-24 01:36:32 +0000980 {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
thsc8994012007-08-19 21:56:03 +0000981#else
thsefe75412007-08-24 01:36:32 +0000982 {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
983 win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
984 {"win32", 0, win32_start_timer,
985 win32_stop_timer, NULL, &alarm_win32_data},
thsc8994012007-08-19 21:56:03 +0000986#endif
987 {NULL, }
988};
989
blueswir13f47aa82008-03-09 06:59:01 +0000990static void show_available_alarms(void)
thsf3dcfad2007-08-24 01:26:02 +0000991{
992 int i;
993
994 printf("Available alarm timers, in order of precedence:\n");
995 for (i = 0; alarm_timers[i].name; i++)
996 printf("%s\n", alarm_timers[i].name);
997}
998
999static void configure_alarms(char const *opt)
1000{
1001 int i;
1002 int cur = 0;
1003 int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
1004 char *arg;
1005 char *name;
pbrook2e70f6e2008-06-29 01:03:05 +00001006 struct qemu_alarm_timer tmp;
thsf3dcfad2007-08-24 01:26:02 +00001007
aurel323adda042008-03-09 23:43:49 +00001008 if (!strcmp(opt, "?")) {
thsf3dcfad2007-08-24 01:26:02 +00001009 show_available_alarms();
1010 exit(0);
1011 }
1012
1013 arg = strdup(opt);
1014
1015 /* Reorder the array */
1016 name = strtok(arg, ",");
1017 while (name) {
balroge2b577e2007-09-17 21:25:20 +00001018 for (i = 0; i < count && alarm_timers[i].name; i++) {
thsf3dcfad2007-08-24 01:26:02 +00001019 if (!strcmp(alarm_timers[i].name, name))
1020 break;
1021 }
1022
1023 if (i == count) {
1024 fprintf(stderr, "Unknown clock %s\n", name);
1025 goto next;
1026 }
1027
1028 if (i < cur)
1029 /* Ignore */
1030 goto next;
1031
1032 /* Swap */
1033 tmp = alarm_timers[i];
1034 alarm_timers[i] = alarm_timers[cur];
1035 alarm_timers[cur] = tmp;
1036
1037 cur++;
1038next:
1039 name = strtok(NULL, ",");
1040 }
1041
1042 free(arg);
1043
1044 if (cur) {
pbrook2e70f6e2008-06-29 01:03:05 +00001045 /* Disable remaining timers */
thsf3dcfad2007-08-24 01:26:02 +00001046 for (i = cur; i < count; i++)
1047 alarm_timers[i].name = NULL;
aurel323adda042008-03-09 23:43:49 +00001048 } else {
1049 show_available_alarms();
1050 exit(1);
thsf3dcfad2007-08-24 01:26:02 +00001051 }
thsf3dcfad2007-08-24 01:26:02 +00001052}
1053
bellard8a7ddc32004-03-31 19:00:16 +00001054QEMUClock *rt_clock;
1055QEMUClock *vm_clock;
1056
1057static QEMUTimer *active_timers[2];
bellard8a7ddc32004-03-31 19:00:16 +00001058
pbrook9596ebb2007-11-18 01:44:38 +00001059static QEMUClock *qemu_new_clock(int type)
bellard8a7ddc32004-03-31 19:00:16 +00001060{
1061 QEMUClock *clock;
1062 clock = qemu_mallocz(sizeof(QEMUClock));
1063 if (!clock)
1064 return NULL;
1065 clock->type = type;
1066 return clock;
1067}
1068
1069QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
1070{
1071 QEMUTimer *ts;
1072
1073 ts = qemu_mallocz(sizeof(QEMUTimer));
1074 ts->clock = clock;
1075 ts->cb = cb;
1076 ts->opaque = opaque;
1077 return ts;
1078}
1079
1080void qemu_free_timer(QEMUTimer *ts)
1081{
1082 qemu_free(ts);
1083}
1084
1085/* stop a timer, but do not dealloc it */
1086void qemu_del_timer(QEMUTimer *ts)
1087{
1088 QEMUTimer **pt, *t;
1089
1090 /* NOTE: this code must be signal safe because
1091 qemu_timer_expired() can be called from a signal. */
1092 pt = &active_timers[ts->clock->type];
1093 for(;;) {
1094 t = *pt;
1095 if (!t)
1096 break;
1097 if (t == ts) {
1098 *pt = t->next;
1099 break;
1100 }
1101 pt = &t->next;
1102 }
1103}
1104
1105/* modify the current timer so that it will be fired when current_time
1106 >= expire_time. The corresponding callback will be called. */
1107void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1108{
1109 QEMUTimer **pt, *t;
1110
1111 qemu_del_timer(ts);
1112
1113 /* add the timer in the sorted list */
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;
ths5fafdf22007-09-16 21:08:06 +00001121 if (t->expire_time > expire_time)
bellard8a7ddc32004-03-31 19:00:16 +00001122 break;
1123 pt = &t->next;
1124 }
1125 ts->expire_time = expire_time;
1126 ts->next = *pt;
1127 *pt = ts;
balrogd5d08332008-01-05 19:41:47 +00001128
1129 /* Rearm if necessary */
pbrook2e70f6e2008-06-29 01:03:05 +00001130 if (pt == &active_timers[ts->clock->type]) {
1131 if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {
1132 qemu_rearm_alarm_timer(alarm_timer);
1133 }
1134 /* Interrupt execution to force deadline recalculation. */
1135 if (use_icount && cpu_single_env) {
1136 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
1137 }
1138 }
bellard8a7ddc32004-03-31 19:00:16 +00001139}
1140
1141int qemu_timer_pending(QEMUTimer *ts)
1142{
1143 QEMUTimer *t;
1144 for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1145 if (t == ts)
1146 return 1;
1147 }
1148 return 0;
1149}
1150
1151static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1152{
1153 if (!timer_head)
1154 return 0;
1155 return (timer_head->expire_time <= current_time);
1156}
1157
1158static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1159{
1160 QEMUTimer *ts;
ths3b46e622007-09-17 08:09:54 +00001161
bellard8a7ddc32004-03-31 19:00:16 +00001162 for(;;) {
1163 ts = *ptimer_head;
bellarde95c8d52004-09-30 22:22:08 +00001164 if (!ts || ts->expire_time > current_time)
bellard8a7ddc32004-03-31 19:00:16 +00001165 break;
1166 /* remove timer from the list before calling the callback */
1167 *ptimer_head = ts->next;
1168 ts->next = NULL;
ths3b46e622007-09-17 08:09:54 +00001169
bellard8a7ddc32004-03-31 19:00:16 +00001170 /* run the callback (the timer list can be modified) */
1171 ts->cb(ts->opaque);
1172 }
1173}
1174
1175int64_t qemu_get_clock(QEMUClock *clock)
1176{
1177 switch(clock->type) {
1178 case QEMU_TIMER_REALTIME:
bellard1dce7c32006-07-13 23:20:22 +00001179 return get_clock() / 1000000;
bellard8a7ddc32004-03-31 19:00:16 +00001180 default:
1181 case QEMU_TIMER_VIRTUAL:
pbrook2e70f6e2008-06-29 01:03:05 +00001182 if (use_icount) {
1183 return cpu_get_icount();
1184 } else {
1185 return cpu_get_clock();
1186 }
bellard8a7ddc32004-03-31 19:00:16 +00001187 }
1188}
1189
bellard1dce7c32006-07-13 23:20:22 +00001190static void init_timers(void)
1191{
1192 init_get_clock();
1193 ticks_per_sec = QEMU_TIMER_BASE;
1194 rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1195 vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1196}
1197
bellard8a7ddc32004-03-31 19:00:16 +00001198/* save a timer */
1199void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1200{
1201 uint64_t expire_time;
1202
1203 if (qemu_timer_pending(ts)) {
1204 expire_time = ts->expire_time;
1205 } else {
1206 expire_time = -1;
1207 }
1208 qemu_put_be64(f, expire_time);
1209}
1210
1211void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1212{
1213 uint64_t expire_time;
1214
1215 expire_time = qemu_get_be64(f);
1216 if (expire_time != -1) {
1217 qemu_mod_timer(ts, expire_time);
1218 } else {
1219 qemu_del_timer(ts);
1220 }
1221}
1222
1223static void timer_save(QEMUFile *f, void *opaque)
1224{
1225 if (cpu_ticks_enabled) {
1226 hw_error("cannot save state if virtual timers are running");
1227 }
thsbee8d682007-12-16 23:41:11 +00001228 qemu_put_be64(f, cpu_ticks_offset);
1229 qemu_put_be64(f, ticks_per_sec);
1230 qemu_put_be64(f, cpu_clock_offset);
bellard8a7ddc32004-03-31 19:00:16 +00001231}
1232
1233static int timer_load(QEMUFile *f, void *opaque, int version_id)
1234{
bellardc88676f2006-08-06 13:36:11 +00001235 if (version_id != 1 && version_id != 2)
bellard8a7ddc32004-03-31 19:00:16 +00001236 return -EINVAL;
1237 if (cpu_ticks_enabled) {
1238 return -EINVAL;
1239 }
thsbee8d682007-12-16 23:41:11 +00001240 cpu_ticks_offset=qemu_get_be64(f);
1241 ticks_per_sec=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001242 if (version_id == 2) {
thsbee8d682007-12-16 23:41:11 +00001243 cpu_clock_offset=qemu_get_be64(f);
bellardc88676f2006-08-06 13:36:11 +00001244 }
bellard8a7ddc32004-03-31 19:00:16 +00001245 return 0;
1246}
1247
bellard67b915a2004-03-31 23:37:16 +00001248#ifdef _WIN32
ths5fafdf22007-09-16 21:08:06 +00001249void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
bellard67b915a2004-03-31 23:37:16 +00001250 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1251#else
bellard8a7ddc32004-03-31 19:00:16 +00001252static void host_alarm_handler(int host_signum)
bellard67b915a2004-03-31 23:37:16 +00001253#endif
bellard8a7ddc32004-03-31 19:00:16 +00001254{
bellard02ba45c2004-06-25 14:46:23 +00001255#if 0
1256#define DISP_FREQ 1000
1257 {
1258 static int64_t delta_min = INT64_MAX;
1259 static int64_t delta_max, delta_cum, last_clock, delta, ti;
1260 static int count;
1261 ti = qemu_get_clock(vm_clock);
1262 if (last_clock != 0) {
1263 delta = ti - last_clock;
1264 if (delta < delta_min)
1265 delta_min = delta;
1266 if (delta > delta_max)
1267 delta_max = delta;
1268 delta_cum += delta;
1269 if (++count == DISP_FREQ) {
bellard26a76462006-06-25 18:15:32 +00001270 printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
bellard02ba45c2004-06-25 14:46:23 +00001271 muldiv64(delta_min, 1000000, ticks_per_sec),
1272 muldiv64(delta_max, 1000000, ticks_per_sec),
1273 muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1274 (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1275 count = 0;
1276 delta_min = INT64_MAX;
1277 delta_max = 0;
1278 delta_cum = 0;
1279 }
1280 }
1281 last_clock = ti;
1282 }
1283#endif
thsefe75412007-08-24 01:36:32 +00001284 if (alarm_has_dynticks(alarm_timer) ||
pbrook2e70f6e2008-06-29 01:03:05 +00001285 (!use_icount &&
1286 qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1287 qemu_get_clock(vm_clock))) ||
bellard8a7ddc32004-03-31 19:00:16 +00001288 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1289 qemu_get_clock(rt_clock))) {
bellard06d9f2f2006-05-01 13:23:04 +00001290#ifdef _WIN32
thsc8994012007-08-19 21:56:03 +00001291 struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1292 SetEvent(data->host_alarm);
bellard06d9f2f2006-05-01 13:23:04 +00001293#endif
balrogee5605e2007-12-03 03:01:40 +00001294 CPUState *env = next_cpu;
1295
balrogd5d08332008-01-05 19:41:47 +00001296 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1297
balrog4f8eb8d2007-12-16 12:39:38 +00001298 if (env) {
1299 /* stop the currently executing cpu because a timer occured */
1300 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
bellarda332e112005-09-03 17:55:47 +00001301#ifdef USE_KQEMU
balrog4f8eb8d2007-12-16 12:39:38 +00001302 if (env->kqemu_enabled) {
1303 kqemu_cpu_interrupt(env);
1304 }
balrogee5605e2007-12-03 03:01:40 +00001305#endif
balrog4f8eb8d2007-12-16 12:39:38 +00001306 }
balrogee5605e2007-12-03 03:01:40 +00001307 event_pending = 1;
bellard8a7ddc32004-03-31 19:00:16 +00001308 }
1309}
1310
pbrook2e70f6e2008-06-29 01:03:05 +00001311static int64_t qemu_next_deadline(void)
thsefe75412007-08-24 01:36:32 +00001312{
pbrook2e70f6e2008-06-29 01:03:05 +00001313 int64_t delta;
thsefe75412007-08-24 01:36:32 +00001314
1315 if (active_timers[QEMU_TIMER_VIRTUAL]) {
pbrook2e70f6e2008-06-29 01:03:05 +00001316 delta = active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1317 qemu_get_clock(vm_clock);
1318 } else {
1319 /* To avoid problems with overflow limit this to 2^32. */
1320 delta = INT32_MAX;
thsefe75412007-08-24 01:36:32 +00001321 }
1322
pbrook2e70f6e2008-06-29 01:03:05 +00001323 if (delta < 0)
1324 delta = 0;
thsefe75412007-08-24 01:36:32 +00001325
pbrook2e70f6e2008-06-29 01:03:05 +00001326 return delta;
1327}
1328
1329static uint64_t qemu_next_deadline_dyntick(void)
1330{
1331 int64_t delta;
1332 int64_t rtdelta;
1333
1334 if (use_icount)
1335 delta = INT32_MAX;
1336 else
1337 delta = (qemu_next_deadline() + 999) / 1000;
1338
1339 if (active_timers[QEMU_TIMER_REALTIME]) {
1340 rtdelta = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
1341 qemu_get_clock(rt_clock))*1000;
1342 if (rtdelta < delta)
1343 delta = rtdelta;
1344 }
1345
1346 if (delta < MIN_TIMER_REARM_US)
1347 delta = MIN_TIMER_REARM_US;
1348
1349 return delta;
thsefe75412007-08-24 01:36:32 +00001350}
1351
bellardfd872592004-05-12 19:11:15 +00001352#ifndef _WIN32
1353
bellard829309c2004-05-20 13:20:12 +00001354#if defined(__linux__)
1355
bellardfd872592004-05-12 19:11:15 +00001356#define RTC_FREQ 1024
1357
thsc8994012007-08-19 21:56:03 +00001358static void enable_sigio_timer(int fd)
bellardfd872592004-05-12 19:11:15 +00001359{
thsc8994012007-08-19 21:56:03 +00001360 struct sigaction act;
1361
1362 /* timer signal */
1363 sigfillset(&act.sa_mask);
1364 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001365 act.sa_handler = host_alarm_handler;
1366
1367 sigaction(SIGIO, &act, NULL);
1368 fcntl(fd, F_SETFL, O_ASYNC);
1369 fcntl(fd, F_SETOWN, getpid());
1370}
1371
thsc40ec5a2007-08-19 22:09:40 +00001372static int hpet_start_timer(struct qemu_alarm_timer *t)
1373{
1374 struct hpet_info info;
1375 int r, fd;
1376
1377 fd = open("/dev/hpet", O_RDONLY);
1378 if (fd < 0)
1379 return -1;
1380
1381 /* Set frequency */
1382 r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1383 if (r < 0) {
1384 fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1385 "error, but for better emulation accuracy type:\n"
1386 "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1387 goto fail;
1388 }
1389
1390 /* Check capabilities */
1391 r = ioctl(fd, HPET_INFO, &info);
1392 if (r < 0)
1393 goto fail;
1394
1395 /* Enable periodic mode */
1396 r = ioctl(fd, HPET_EPI, 0);
1397 if (info.hi_flags && (r < 0))
1398 goto fail;
1399
1400 /* Enable interrupt */
1401 r = ioctl(fd, HPET_IE_ON, 0);
1402 if (r < 0)
1403 goto fail;
1404
1405 enable_sigio_timer(fd);
pbrookfcdc2122007-08-23 20:22:22 +00001406 t->priv = (void *)(long)fd;
thsc40ec5a2007-08-19 22:09:40 +00001407
1408 return 0;
1409fail:
1410 close(fd);
1411 return -1;
1412}
1413
1414static void hpet_stop_timer(struct qemu_alarm_timer *t)
1415{
pbrookfcdc2122007-08-23 20:22:22 +00001416 int fd = (long)t->priv;
thsc40ec5a2007-08-19 22:09:40 +00001417
1418 close(fd);
1419}
1420
thsc8994012007-08-19 21:56:03 +00001421static int rtc_start_timer(struct qemu_alarm_timer *t)
1422{
1423 int rtc_fd;
balrogb5a23ad2008-02-03 03:45:47 +00001424 unsigned long current_rtc_freq = 0;
thsc8994012007-08-19 21:56:03 +00001425
balrogaeb30be2007-07-02 15:03:13 +00001426 TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
bellardfd872592004-05-12 19:11:15 +00001427 if (rtc_fd < 0)
1428 return -1;
balrogb5a23ad2008-02-03 03:45:47 +00001429 ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1430 if (current_rtc_freq != RTC_FREQ &&
1431 ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
bellardfd872592004-05-12 19:11:15 +00001432 fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1433 "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1434 "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1435 goto fail;
1436 }
1437 if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1438 fail:
1439 close(rtc_fd);
1440 return -1;
1441 }
thsc8994012007-08-19 21:56:03 +00001442
1443 enable_sigio_timer(rtc_fd);
1444
pbrookfcdc2122007-08-23 20:22:22 +00001445 t->priv = (void *)(long)rtc_fd;
thsc8994012007-08-19 21:56:03 +00001446
bellardfd872592004-05-12 19:11:15 +00001447 return 0;
1448}
1449
thsc8994012007-08-19 21:56:03 +00001450static void rtc_stop_timer(struct qemu_alarm_timer *t)
bellard829309c2004-05-20 13:20:12 +00001451{
pbrookfcdc2122007-08-23 20:22:22 +00001452 int rtc_fd = (long)t->priv;
thsc8994012007-08-19 21:56:03 +00001453
1454 close(rtc_fd);
bellard829309c2004-05-20 13:20:12 +00001455}
1456
thsefe75412007-08-24 01:36:32 +00001457static int dynticks_start_timer(struct qemu_alarm_timer *t)
1458{
1459 struct sigevent ev;
1460 timer_t host_timer;
1461 struct sigaction act;
1462
1463 sigfillset(&act.sa_mask);
1464 act.sa_flags = 0;
thsefe75412007-08-24 01:36:32 +00001465 act.sa_handler = host_alarm_handler;
1466
1467 sigaction(SIGALRM, &act, NULL);
1468
1469 ev.sigev_value.sival_int = 0;
1470 ev.sigev_notify = SIGEV_SIGNAL;
1471 ev.sigev_signo = SIGALRM;
1472
1473 if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1474 perror("timer_create");
1475
1476 /* disable dynticks */
1477 fprintf(stderr, "Dynamic Ticks disabled\n");
1478
1479 return -1;
1480 }
1481
1482 t->priv = (void *)host_timer;
1483
1484 return 0;
1485}
1486
1487static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1488{
1489 timer_t host_timer = (timer_t)t->priv;
1490
1491 timer_delete(host_timer);
1492}
1493
1494static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1495{
1496 timer_t host_timer = (timer_t)t->priv;
1497 struct itimerspec timeout;
1498 int64_t nearest_delta_us = INT64_MAX;
1499 int64_t current_us;
1500
1501 if (!active_timers[QEMU_TIMER_REALTIME] &&
1502 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001503 return;
thsefe75412007-08-24 01:36:32 +00001504
pbrook2e70f6e2008-06-29 01:03:05 +00001505 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001506
1507 /* check whether a timer is already running */
1508 if (timer_gettime(host_timer, &timeout)) {
1509 perror("gettime");
1510 fprintf(stderr, "Internal timer error: aborting\n");
1511 exit(1);
1512 }
1513 current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1514 if (current_us && current_us <= nearest_delta_us)
1515 return;
1516
1517 timeout.it_interval.tv_sec = 0;
1518 timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1519 timeout.it_value.tv_sec = nearest_delta_us / 1000000;
1520 timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1521 if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1522 perror("settime");
1523 fprintf(stderr, "Internal timer error: aborting\n");
1524 exit(1);
1525 }
1526}
1527
ths70744b32007-08-26 17:31:30 +00001528#endif /* defined(__linux__) */
ths231c6582007-08-26 17:29:15 +00001529
thsc8994012007-08-19 21:56:03 +00001530static int unix_start_timer(struct qemu_alarm_timer *t)
1531{
1532 struct sigaction act;
1533 struct itimerval itv;
1534 int err;
1535
1536 /* timer signal */
1537 sigfillset(&act.sa_mask);
1538 act.sa_flags = 0;
thsc8994012007-08-19 21:56:03 +00001539 act.sa_handler = host_alarm_handler;
1540
1541 sigaction(SIGALRM, &act, NULL);
1542
1543 itv.it_interval.tv_sec = 0;
1544 /* for i386 kernel 2.6 to get 1 ms */
1545 itv.it_interval.tv_usec = 999;
1546 itv.it_value.tv_sec = 0;
1547 itv.it_value.tv_usec = 10 * 1000;
1548
1549 err = setitimer(ITIMER_REAL, &itv, NULL);
1550 if (err)
1551 return -1;
1552
1553 return 0;
1554}
1555
1556static void unix_stop_timer(struct qemu_alarm_timer *t)
1557{
1558 struct itimerval itv;
1559
1560 memset(&itv, 0, sizeof(itv));
1561 setitimer(ITIMER_REAL, &itv, NULL);
1562}
1563
bellard829309c2004-05-20 13:20:12 +00001564#endif /* !defined(_WIN32) */
bellardfd872592004-05-12 19:11:15 +00001565
thsc8994012007-08-19 21:56:03 +00001566#ifdef _WIN32
1567
1568static int win32_start_timer(struct qemu_alarm_timer *t)
1569{
1570 TIMECAPS tc;
1571 struct qemu_alarm_win32 *data = t->priv;
thsefe75412007-08-24 01:36:32 +00001572 UINT flags;
thsc8994012007-08-19 21:56:03 +00001573
1574 data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1575 if (!data->host_alarm) {
1576 perror("Failed CreateEvent");
thsc396a7f2007-08-20 15:42:22 +00001577 return -1;
thsc8994012007-08-19 21:56:03 +00001578 }
1579
1580 memset(&tc, 0, sizeof(tc));
1581 timeGetDevCaps(&tc, sizeof(tc));
1582
1583 if (data->period < tc.wPeriodMin)
1584 data->period = tc.wPeriodMin;
1585
1586 timeBeginPeriod(data->period);
1587
thsefe75412007-08-24 01:36:32 +00001588 flags = TIME_CALLBACK_FUNCTION;
1589 if (alarm_has_dynticks(t))
1590 flags |= TIME_ONESHOT;
1591 else
1592 flags |= TIME_PERIODIC;
1593
thsc8994012007-08-19 21:56:03 +00001594 data->timerId = timeSetEvent(1, // interval (ms)
1595 data->period, // resolution
1596 host_alarm_handler, // function
1597 (DWORD)t, // parameter
thsefe75412007-08-24 01:36:32 +00001598 flags);
thsc8994012007-08-19 21:56:03 +00001599
1600 if (!data->timerId) {
1601 perror("Failed to initialize win32 alarm timer");
1602
1603 timeEndPeriod(data->period);
1604 CloseHandle(data->host_alarm);
1605 return -1;
1606 }
1607
1608 qemu_add_wait_object(data->host_alarm, NULL, NULL);
1609
1610 return 0;
1611}
1612
1613static void win32_stop_timer(struct qemu_alarm_timer *t)
1614{
1615 struct qemu_alarm_win32 *data = t->priv;
1616
1617 timeKillEvent(data->timerId);
1618 timeEndPeriod(data->period);
1619
1620 CloseHandle(data->host_alarm);
1621}
1622
thsefe75412007-08-24 01:36:32 +00001623static void win32_rearm_timer(struct qemu_alarm_timer *t)
1624{
1625 struct qemu_alarm_win32 *data = t->priv;
1626 uint64_t nearest_delta_us;
1627
1628 if (!active_timers[QEMU_TIMER_REALTIME] &&
1629 !active_timers[QEMU_TIMER_VIRTUAL])
balrogd5d08332008-01-05 19:41:47 +00001630 return;
thsefe75412007-08-24 01:36:32 +00001631
pbrook2e70f6e2008-06-29 01:03:05 +00001632 nearest_delta_us = qemu_next_deadline_dyntick();
thsefe75412007-08-24 01:36:32 +00001633 nearest_delta_us /= 1000;
1634
1635 timeKillEvent(data->timerId);
1636
1637 data->timerId = timeSetEvent(1,
1638 data->period,
1639 host_alarm_handler,
1640 (DWORD)t,
1641 TIME_ONESHOT | TIME_PERIODIC);
1642
1643 if (!data->timerId) {
1644 perror("Failed to re-arm win32 alarm timer");
1645
1646 timeEndPeriod(data->period);
1647 CloseHandle(data->host_alarm);
1648 exit(1);
1649 }
1650}
1651
thsc8994012007-08-19 21:56:03 +00001652#endif /* _WIN32 */
1653
bellard1dce7c32006-07-13 23:20:22 +00001654static void init_timer_alarm(void)
bellard8a7ddc32004-03-31 19:00:16 +00001655{
thsc8994012007-08-19 21:56:03 +00001656 struct qemu_alarm_timer *t;
1657 int i, err = -1;
bellard06d9f2f2006-05-01 13:23:04 +00001658
thsc8994012007-08-19 21:56:03 +00001659 for (i = 0; alarm_timers[i].name; i++) {
1660 t = &alarm_timers[i];
1661
thsc8994012007-08-19 21:56:03 +00001662 err = t->start(t);
1663 if (!err)
1664 break;
bellard67b915a2004-03-31 23:37:16 +00001665 }
bellardfd872592004-05-12 19:11:15 +00001666
thsc8994012007-08-19 21:56:03 +00001667 if (err) {
1668 fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1669 fprintf(stderr, "Terminating\n");
1670 exit(1);
bellard67b915a2004-03-31 23:37:16 +00001671 }
thsc8994012007-08-19 21:56:03 +00001672
1673 alarm_timer = t;
bellard8a7ddc32004-03-31 19:00:16 +00001674}
1675
pbrook9596ebb2007-11-18 01:44:38 +00001676static void quit_timers(void)
bellard40c3bac2004-04-04 12:56:28 +00001677{
thsc8994012007-08-19 21:56:03 +00001678 alarm_timer->stop(alarm_timer);
1679 alarm_timer = NULL;
bellard40c3bac2004-04-04 12:56:28 +00001680}
1681
bellardc4b1fcc2004-03-14 21:44:30 +00001682/***********************************************************/
balrogf6503052008-02-17 11:42:19 +00001683/* host time/date access */
1684void qemu_get_timedate(struct tm *tm, int offset)
1685{
1686 time_t ti;
1687 struct tm *ret;
1688
1689 time(&ti);
1690 ti += offset;
1691 if (rtc_date_offset == -1) {
1692 if (rtc_utc)
1693 ret = gmtime(&ti);
1694 else
1695 ret = localtime(&ti);
1696 } else {
1697 ti -= rtc_date_offset;
1698 ret = gmtime(&ti);
1699 }
1700
1701 memcpy(tm, ret, sizeof(struct tm));
1702}
1703
1704int qemu_timedate_diff(struct tm *tm)
1705{
1706 time_t seconds;
1707
1708 if (rtc_date_offset == -1)
1709 if (rtc_utc)
1710 seconds = mktimegm(tm);
1711 else
1712 seconds = mktime(tm);
1713 else
1714 seconds = mktimegm(tm) + rtc_date_offset;
1715
1716 return seconds - time(NULL);
1717}
1718
1719/***********************************************************/
bellard82c643f2004-07-14 17:28:13 +00001720/* character device */
bellardc45886d2004-01-05 00:02:06 +00001721
pbrooke5b0bc42007-01-27 23:46:43 +00001722static void qemu_chr_event(CharDriverState *s, int event)
1723{
1724 if (!s->chr_event)
1725 return;
1726 s->chr_event(s->handler_opaque, event);
1727}
1728
ths86e94de2007-01-05 22:01:59 +00001729static void qemu_chr_reset_bh(void *opaque)
1730{
1731 CharDriverState *s = opaque;
pbrooke5b0bc42007-01-27 23:46:43 +00001732 qemu_chr_event(s, CHR_EVENT_RESET);
ths86e94de2007-01-05 22:01:59 +00001733 qemu_bh_delete(s->bh);
1734 s->bh = NULL;
1735}
1736
1737void qemu_chr_reset(CharDriverState *s)
1738{
1739 if (s->bh == NULL) {
1740 s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1741 qemu_bh_schedule(s->bh);
1742 }
1743}
1744
bellard82c643f2004-07-14 17:28:13 +00001745int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
bellard67b915a2004-03-31 23:37:16 +00001746{
bellard82c643f2004-07-14 17:28:13 +00001747 return s->chr_write(s, buf, len);
bellard67b915a2004-03-31 23:37:16 +00001748}
1749
bellarde57a8c02005-11-10 23:58:52 +00001750int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00001751{
bellarde57a8c02005-11-10 23:58:52 +00001752 if (!s->chr_ioctl)
1753 return -ENOTSUP;
1754 return s->chr_ioctl(s, cmd, arg);
bellardf8d179e2005-11-08 22:30:36 +00001755}
1756
pbrooke5b0bc42007-01-27 23:46:43 +00001757int qemu_chr_can_read(CharDriverState *s)
1758{
1759 if (!s->chr_can_read)
1760 return 0;
1761 return s->chr_can_read(s->handler_opaque);
1762}
1763
1764void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1765{
1766 s->chr_read(s->handler_opaque, buf, len);
1767}
1768
balrogbd9bdce2007-11-25 00:55:06 +00001769void qemu_chr_accept_input(CharDriverState *s)
1770{
1771 if (s->chr_accept_input)
1772 s->chr_accept_input(s);
1773}
pbrooke5b0bc42007-01-27 23:46:43 +00001774
bellard82c643f2004-07-14 17:28:13 +00001775void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
bellard0824d6f2003-06-24 13:42:40 +00001776{
bellard82c643f2004-07-14 17:28:13 +00001777 char buf[4096];
1778 va_list ap;
1779 va_start(ap, fmt);
1780 vsnprintf(buf, sizeof(buf), fmt, ap);
thsffe8ab82007-12-16 03:16:05 +00001781 qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
bellard82c643f2004-07-14 17:28:13 +00001782 va_end(ap);
1783}
1784
bellard5905b2e2004-08-01 21:53:26 +00001785void qemu_chr_send_event(CharDriverState *s, int event)
1786{
1787 if (s->chr_send_event)
1788 s->chr_send_event(s, event);
1789}
1790
ths5fafdf22007-09-16 21:08:06 +00001791void qemu_chr_add_handlers(CharDriverState *s,
1792 IOCanRWHandler *fd_can_read,
pbrooke5b0bc42007-01-27 23:46:43 +00001793 IOReadHandler *fd_read,
1794 IOEventHandler *fd_event,
1795 void *opaque)
bellard82c643f2004-07-14 17:28:13 +00001796{
pbrooke5b0bc42007-01-27 23:46:43 +00001797 s->chr_can_read = fd_can_read;
1798 s->chr_read = fd_read;
1799 s->chr_event = fd_event;
1800 s->handler_opaque = opaque;
1801 if (s->chr_update_read_handler)
1802 s->chr_update_read_handler(s);
bellard82c643f2004-07-14 17:28:13 +00001803}
ths3b46e622007-09-17 08:09:54 +00001804
bellard82c643f2004-07-14 17:28:13 +00001805static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1806{
1807 return len;
1808}
1809
ths52f61fd2006-12-22 21:20:52 +00001810static CharDriverState *qemu_chr_open_null(void)
bellard82c643f2004-07-14 17:28:13 +00001811{
1812 CharDriverState *chr;
1813
1814 chr = qemu_mallocz(sizeof(CharDriverState));
1815 if (!chr)
1816 return NULL;
1817 chr->chr_write = null_chr_write;
bellard82c643f2004-07-14 17:28:13 +00001818 return chr;
1819}
1820
ths20d8a3e2007-02-18 17:04:49 +00001821/* MUX driver for serial I/O splitting */
1822static int term_timestamps;
1823static int64_t term_timestamps_start;
ths9c1de612007-02-21 17:25:30 +00001824#define MAX_MUX 4
balrogbd9bdce2007-11-25 00:55:06 +00001825#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
1826#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
ths20d8a3e2007-02-18 17:04:49 +00001827typedef struct {
1828 IOCanRWHandler *chr_can_read[MAX_MUX];
1829 IOReadHandler *chr_read[MAX_MUX];
1830 IOEventHandler *chr_event[MAX_MUX];
1831 void *ext_opaque[MAX_MUX];
1832 CharDriverState *drv;
balrogbd9bdce2007-11-25 00:55:06 +00001833 unsigned char buffer[MUX_BUFFER_SIZE];
1834 int prod;
1835 int cons;
ths20d8a3e2007-02-18 17:04:49 +00001836 int mux_cnt;
1837 int term_got_escape;
1838 int max_size;
1839} MuxDriver;
1840
1841
1842static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1843{
1844 MuxDriver *d = chr->opaque;
1845 int ret;
1846 if (!term_timestamps) {
1847 ret = d->drv->chr_write(d->drv, buf, len);
1848 } else {
1849 int i;
1850
1851 ret = 0;
1852 for(i = 0; i < len; i++) {
1853 ret += d->drv->chr_write(d->drv, buf+i, 1);
1854 if (buf[i] == '\n') {
1855 char buf1[64];
1856 int64_t ti;
1857 int secs;
1858
1859 ti = get_clock();
1860 if (term_timestamps_start == -1)
1861 term_timestamps_start = ti;
1862 ti -= term_timestamps_start;
1863 secs = ti / 1000000000;
1864 snprintf(buf1, sizeof(buf1),
1865 "[%02d:%02d:%02d.%03d] ",
1866 secs / 3600,
1867 (secs / 60) % 60,
1868 secs % 60,
1869 (int)((ti / 1000000) % 1000));
thsffe8ab82007-12-16 03:16:05 +00001870 d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
ths20d8a3e2007-02-18 17:04:49 +00001871 }
1872 }
1873 }
1874 return ret;
1875}
1876
1877static char *mux_help[] = {
1878 "% h print this help\n\r",
1879 "% x exit emulator\n\r",
1880 "% s save disk data back to file (if -snapshot)\n\r",
1881 "% t toggle console timestamps\n\r"
1882 "% b send break (magic sysrq)\n\r",
1883 "% c switch between console and monitor\n\r",
1884 "% % sends %\n\r",
1885 NULL
1886};
1887
1888static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1889static void mux_print_help(CharDriverState *chr)
1890{
1891 int i, j;
1892 char ebuf[15] = "Escape-Char";
1893 char cbuf[50] = "\n\r";
1894
1895 if (term_escape_char > 0 && term_escape_char < 26) {
1896 sprintf(cbuf,"\n\r");
1897 sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
1898 } else {
thsffe8ab82007-12-16 03:16:05 +00001899 sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
1900 term_escape_char);
ths20d8a3e2007-02-18 17:04:49 +00001901 }
thsffe8ab82007-12-16 03:16:05 +00001902 chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
ths20d8a3e2007-02-18 17:04:49 +00001903 for (i = 0; mux_help[i] != NULL; i++) {
1904 for (j=0; mux_help[i][j] != '\0'; j++) {
1905 if (mux_help[i][j] == '%')
thsffe8ab82007-12-16 03:16:05 +00001906 chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
ths20d8a3e2007-02-18 17:04:49 +00001907 else
thsffe8ab82007-12-16 03:16:05 +00001908 chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
ths20d8a3e2007-02-18 17:04:49 +00001909 }
1910 }
1911}
1912
1913static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1914{
1915 if (d->term_got_escape) {
1916 d->term_got_escape = 0;
1917 if (ch == term_escape_char)
1918 goto send_char;
1919 switch(ch) {
1920 case '?':
1921 case 'h':
1922 mux_print_help(chr);
1923 break;
1924 case 'x':
1925 {
1926 char *term = "QEMU: Terminated\n\r";
thsffe8ab82007-12-16 03:16:05 +00001927 chr->chr_write(chr,(uint8_t *)term,strlen(term));
ths20d8a3e2007-02-18 17:04:49 +00001928 exit(0);
1929 break;
1930 }
1931 case 's':
1932 {
1933 int i;
thse4bcb142007-12-02 04:51:10 +00001934 for (i = 0; i < nb_drives; i++) {
1935 bdrv_commit(drives_table[i].bdrv);
ths20d8a3e2007-02-18 17:04:49 +00001936 }
1937 }
1938 break;
1939 case 'b':
balrog36ddb832007-05-18 17:46:59 +00001940 qemu_chr_event(chr, CHR_EVENT_BREAK);
ths20d8a3e2007-02-18 17:04:49 +00001941 break;
1942 case 'c':
1943 /* Switch to the next registered device */
1944 chr->focus++;
1945 if (chr->focus >= d->mux_cnt)
1946 chr->focus = 0;
1947 break;
1948 case 't':
1949 term_timestamps = !term_timestamps;
1950 term_timestamps_start = -1;
1951 break;
1952 }
1953 } else if (ch == term_escape_char) {
1954 d->term_got_escape = 1;
1955 } else {
1956 send_char:
1957 return 1;
1958 }
1959 return 0;
1960}
1961
balrogbd9bdce2007-11-25 00:55:06 +00001962static void mux_chr_accept_input(CharDriverState *chr)
1963{
1964 int m = chr->focus;
1965 MuxDriver *d = chr->opaque;
1966
1967 while (d->prod != d->cons &&
1968 d->chr_can_read[m] &&
1969 d->chr_can_read[m](d->ext_opaque[m])) {
1970 d->chr_read[m](d->ext_opaque[m],
1971 &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
1972 }
1973}
1974
ths20d8a3e2007-02-18 17:04:49 +00001975static int mux_chr_can_read(void *opaque)
1976{
1977 CharDriverState *chr = opaque;
1978 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00001979
1980 if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
1981 return 1;
ths20d8a3e2007-02-18 17:04:49 +00001982 if (d->chr_can_read[chr->focus])
balrogbd9bdce2007-11-25 00:55:06 +00001983 return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
ths20d8a3e2007-02-18 17:04:49 +00001984 return 0;
1985}
1986
1987static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1988{
1989 CharDriverState *chr = opaque;
1990 MuxDriver *d = chr->opaque;
balrogbd9bdce2007-11-25 00:55:06 +00001991 int m = chr->focus;
ths20d8a3e2007-02-18 17:04:49 +00001992 int i;
balrogbd9bdce2007-11-25 00:55:06 +00001993
1994 mux_chr_accept_input (opaque);
1995
ths20d8a3e2007-02-18 17:04:49 +00001996 for(i = 0; i < size; i++)
balrogbd9bdce2007-11-25 00:55:06 +00001997 if (mux_proc_byte(chr, d, buf[i])) {
1998 if (d->prod == d->cons &&
1999 d->chr_can_read[m] &&
2000 d->chr_can_read[m](d->ext_opaque[m]))
2001 d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
2002 else
2003 d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
2004 }
ths20d8a3e2007-02-18 17:04:49 +00002005}
2006
2007static void mux_chr_event(void *opaque, int event)
2008{
2009 CharDriverState *chr = opaque;
2010 MuxDriver *d = chr->opaque;
2011 int i;
2012
2013 /* Send the event to all registered listeners */
2014 for (i = 0; i < d->mux_cnt; i++)
2015 if (d->chr_event[i])
2016 d->chr_event[i](d->ext_opaque[i], event);
2017}
2018
2019static void mux_chr_update_read_handler(CharDriverState *chr)
2020{
2021 MuxDriver *d = chr->opaque;
2022
2023 if (d->mux_cnt >= MAX_MUX) {
2024 fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
2025 return;
2026 }
2027 d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
2028 d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
2029 d->chr_read[d->mux_cnt] = chr->chr_read;
2030 d->chr_event[d->mux_cnt] = chr->chr_event;
2031 /* Fix up the real driver with mux routines */
2032 if (d->mux_cnt == 0) {
2033 qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
2034 mux_chr_event, chr);
2035 }
2036 chr->focus = d->mux_cnt;
2037 d->mux_cnt++;
2038}
2039
pbrook9596ebb2007-11-18 01:44:38 +00002040static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
ths20d8a3e2007-02-18 17:04:49 +00002041{
2042 CharDriverState *chr;
2043 MuxDriver *d;
2044
2045 chr = qemu_mallocz(sizeof(CharDriverState));
2046 if (!chr)
2047 return NULL;
2048 d = qemu_mallocz(sizeof(MuxDriver));
2049 if (!d) {
2050 free(chr);
2051 return NULL;
2052 }
2053
2054 chr->opaque = d;
2055 d->drv = drv;
2056 chr->focus = -1;
2057 chr->chr_write = mux_chr_write;
2058 chr->chr_update_read_handler = mux_chr_update_read_handler;
balrogbd9bdce2007-11-25 00:55:06 +00002059 chr->chr_accept_input = mux_chr_accept_input;
ths20d8a3e2007-02-18 17:04:49 +00002060 return chr;
2061}
2062
2063
bellardfd1dff42006-02-01 21:29:26 +00002064#ifdef _WIN32
bellard82c643f2004-07-14 17:28:13 +00002065
bellardfd1dff42006-02-01 21:29:26 +00002066static void socket_cleanup(void)
2067{
2068 WSACleanup();
2069}
bellard82c643f2004-07-14 17:28:13 +00002070
bellardfd1dff42006-02-01 21:29:26 +00002071static int socket_init(void)
2072{
2073 WSADATA Data;
2074 int ret, err;
2075
2076 ret = WSAStartup(MAKEWORD(2,2), &Data);
2077 if (ret != 0) {
2078 err = WSAGetLastError();
2079 fprintf(stderr, "WSAStartup: %d\n", err);
2080 return -1;
2081 }
2082 atexit(socket_cleanup);
2083 return 0;
2084}
2085
2086static int send_all(int fd, const uint8_t *buf, int len1)
2087{
2088 int ret, len;
ths3b46e622007-09-17 08:09:54 +00002089
bellardfd1dff42006-02-01 21:29:26 +00002090 len = len1;
2091 while (len > 0) {
2092 ret = send(fd, buf, len, 0);
2093 if (ret < 0) {
2094 int errno;
2095 errno = WSAGetLastError();
2096 if (errno != WSAEWOULDBLOCK) {
2097 return -1;
2098 }
2099 } else if (ret == 0) {
2100 break;
2101 } else {
2102 buf += ret;
2103 len -= ret;
2104 }
2105 }
2106 return len1 - len;
2107}
2108
2109void socket_set_nonblock(int fd)
2110{
2111 unsigned long opt = 1;
2112 ioctlsocket(fd, FIONBIO, &opt);
2113}
2114
2115#else
2116
bellard1d969052004-09-18 19:34:39 +00002117static int unix_write(int fd, const uint8_t *buf, int len1)
2118{
2119 int ret, len;
2120
2121 len = len1;
2122 while (len > 0) {
2123 ret = write(fd, buf, len);
2124 if (ret < 0) {
2125 if (errno != EINTR && errno != EAGAIN)
2126 return -1;
2127 } else if (ret == 0) {
2128 break;
2129 } else {
2130 buf += ret;
2131 len -= ret;
2132 }
2133 }
2134 return len1 - len;
2135}
2136
bellardfd1dff42006-02-01 21:29:26 +00002137static inline int send_all(int fd, const uint8_t *buf, int len1)
2138{
2139 return unix_write(fd, buf, len1);
2140}
2141
2142void socket_set_nonblock(int fd)
2143{
2144 fcntl(fd, F_SETFL, O_NONBLOCK);
2145}
2146#endif /* !_WIN32 */
2147
2148#ifndef _WIN32
2149
2150typedef struct {
2151 int fd_in, fd_out;
bellardfd1dff42006-02-01 21:29:26 +00002152 int max_size;
2153} FDCharDriver;
2154
ths20d8a3e2007-02-18 17:04:49 +00002155#define STDIO_MAX_CLIENTS 1
2156static int stdio_nb_clients = 0;
bellardfd1dff42006-02-01 21:29:26 +00002157
bellard82c643f2004-07-14 17:28:13 +00002158static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2159{
2160 FDCharDriver *s = chr->opaque;
bellard1d969052004-09-18 19:34:39 +00002161 return unix_write(s->fd_out, buf, len);
bellard82c643f2004-07-14 17:28:13 +00002162}
2163
bellard7c9d8e02005-11-15 22:16:05 +00002164static int fd_chr_read_poll(void *opaque)
2165{
2166 CharDriverState *chr = opaque;
2167 FDCharDriver *s = chr->opaque;
2168
pbrooke5b0bc42007-01-27 23:46:43 +00002169 s->max_size = qemu_chr_can_read(chr);
bellard7c9d8e02005-11-15 22:16:05 +00002170 return s->max_size;
2171}
2172
2173static void fd_chr_read(void *opaque)
2174{
2175 CharDriverState *chr = opaque;
2176 FDCharDriver *s = chr->opaque;
2177 int size, len;
2178 uint8_t buf[1024];
ths3b46e622007-09-17 08:09:54 +00002179
bellard7c9d8e02005-11-15 22:16:05 +00002180 len = sizeof(buf);
2181 if (len > s->max_size)
2182 len = s->max_size;
2183 if (len == 0)
2184 return;
2185 size = read(s->fd_in, buf, len);
pbrook188157f2006-11-01 01:44:16 +00002186 if (size == 0) {
2187 /* FD has been closed. Remove it from the active list. */
2188 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2189 return;
2190 }
bellard7c9d8e02005-11-15 22:16:05 +00002191 if (size > 0) {
pbrooke5b0bc42007-01-27 23:46:43 +00002192 qemu_chr_read(chr, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00002193 }
2194}
2195
pbrooke5b0bc42007-01-27 23:46:43 +00002196static void fd_chr_update_read_handler(CharDriverState *chr)
bellard82c643f2004-07-14 17:28:13 +00002197{
2198 FDCharDriver *s = chr->opaque;
2199
bellardf8d179e2005-11-08 22:30:36 +00002200 if (s->fd_in >= 0) {
2201 if (nographic && s->fd_in == 0) {
bellardf8d179e2005-11-08 22:30:36 +00002202 } else {
ths5fafdf22007-09-16 21:08:06 +00002203 qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
bellard7c9d8e02005-11-15 22:16:05 +00002204 fd_chr_read, NULL, chr);
bellardf8d179e2005-11-08 22:30:36 +00002205 }
bellard0824d6f2003-06-24 13:42:40 +00002206 }
2207}
2208
balroga11d0702008-01-19 13:00:43 +00002209static void fd_chr_close(struct CharDriverState *chr)
2210{
2211 FDCharDriver *s = chr->opaque;
2212
2213 if (s->fd_in >= 0) {
2214 if (nographic && s->fd_in == 0) {
2215 } else {
2216 qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2217 }
2218 }
2219
2220 qemu_free(s);
2221}
2222
bellard82c643f2004-07-14 17:28:13 +00002223/* open a character device to a unix fd */
ths52f61fd2006-12-22 21:20:52 +00002224static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
bellard82c643f2004-07-14 17:28:13 +00002225{
2226 CharDriverState *chr;
2227 FDCharDriver *s;
2228
2229 chr = qemu_mallocz(sizeof(CharDriverState));
2230 if (!chr)
2231 return NULL;
2232 s = qemu_mallocz(sizeof(FDCharDriver));
2233 if (!s) {
2234 free(chr);
2235 return NULL;
2236 }
2237 s->fd_in = fd_in;
2238 s->fd_out = fd_out;
2239 chr->opaque = s;
2240 chr->chr_write = fd_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00002241 chr->chr_update_read_handler = fd_chr_update_read_handler;
balroga11d0702008-01-19 13:00:43 +00002242 chr->chr_close = fd_chr_close;
ths86e94de2007-01-05 22:01:59 +00002243
2244 qemu_chr_reset(chr);
2245
bellard82c643f2004-07-14 17:28:13 +00002246 return chr;
2247}
2248
ths52f61fd2006-12-22 21:20:52 +00002249static CharDriverState *qemu_chr_open_file_out(const char *file_out)
bellardf8d179e2005-11-08 22:30:36 +00002250{
2251 int fd_out;
2252
balrogaeb30be2007-07-02 15:03:13 +00002253 TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
bellardf8d179e2005-11-08 22:30:36 +00002254 if (fd_out < 0)
2255 return NULL;
2256 return qemu_chr_open_fd(-1, fd_out);
2257}
2258
ths52f61fd2006-12-22 21:20:52 +00002259static CharDriverState *qemu_chr_open_pipe(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002260{
thsc26c1c42006-12-22 19:25:31 +00002261 int fd_in, fd_out;
2262 char filename_in[256], filename_out[256];
bellardf8d179e2005-11-08 22:30:36 +00002263
thsc26c1c42006-12-22 19:25:31 +00002264 snprintf(filename_in, 256, "%s.in", filename);
2265 snprintf(filename_out, 256, "%s.out", filename);
balrogaeb30be2007-07-02 15:03:13 +00002266 TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2267 TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002268 if (fd_in < 0 || fd_out < 0) {
2269 if (fd_in >= 0)
2270 close(fd_in);
2271 if (fd_out >= 0)
2272 close(fd_out);
balrogaeb30be2007-07-02 15:03:13 +00002273 TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
thsc26c1c42006-12-22 19:25:31 +00002274 if (fd_in < 0)
2275 return NULL;
2276 }
2277 return qemu_chr_open_fd(fd_in, fd_out);
bellardf8d179e2005-11-08 22:30:36 +00002278}
2279
2280
bellard82c643f2004-07-14 17:28:13 +00002281/* for STDIO, we handle the case where several clients use it
2282 (nographic mode) */
2283
bellardaa0bc6b2005-09-03 15:28:58 +00002284#define TERM_FIFO_MAX_SIZE 1
2285
bellardaa0bc6b2005-09-03 15:28:58 +00002286static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
bellard1dce7c32006-07-13 23:20:22 +00002287static int term_fifo_size;
bellard82c643f2004-07-14 17:28:13 +00002288
bellard7c9d8e02005-11-15 22:16:05 +00002289static int stdio_read_poll(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002290{
ths20d8a3e2007-02-18 17:04:49 +00002291 CharDriverState *chr = opaque;
bellardaa0bc6b2005-09-03 15:28:58 +00002292
ths20d8a3e2007-02-18 17:04:49 +00002293 /* try to flush the queue if needed */
2294 if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2295 qemu_chr_read(chr, term_fifo, 1);
2296 term_fifo_size = 0;
bellardaa0bc6b2005-09-03 15:28:58 +00002297 }
ths20d8a3e2007-02-18 17:04:49 +00002298 /* see if we can absorb more chars */
2299 if (term_fifo_size == 0)
2300 return 1;
2301 else
2302 return 0;
bellard82c643f2004-07-14 17:28:13 +00002303}
2304
bellard7c9d8e02005-11-15 22:16:05 +00002305static void stdio_read(void *opaque)
bellard82c643f2004-07-14 17:28:13 +00002306{
bellard7c9d8e02005-11-15 22:16:05 +00002307 int size;
2308 uint8_t buf[1];
ths20d8a3e2007-02-18 17:04:49 +00002309 CharDriverState *chr = opaque;
2310
bellard7c9d8e02005-11-15 22:16:05 +00002311 size = read(0, buf, 1);
pbrook519945d2006-09-10 14:39:54 +00002312 if (size == 0) {
2313 /* stdin has been closed. Remove it from the active list. */
2314 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2315 return;
2316 }
ths20d8a3e2007-02-18 17:04:49 +00002317 if (size > 0) {
2318 if (qemu_chr_can_read(chr) > 0) {
2319 qemu_chr_read(chr, buf, 1);
2320 } else if (term_fifo_size == 0) {
2321 term_fifo[term_fifo_size++] = buf[0];
bellard1dce7c32006-07-13 23:20:22 +00002322 }
bellard1dce7c32006-07-13 23:20:22 +00002323 }
2324}
2325
bellard8d11df92004-08-24 21:13:40 +00002326/* init terminal so that we can grab keys */
2327static struct termios oldtty;
2328static int old_fd0_flags;
balroga11d0702008-01-19 13:00:43 +00002329static int term_atexit_done;
bellard8d11df92004-08-24 21:13:40 +00002330
2331static void term_exit(void)
2332{
2333 tcsetattr (0, TCSANOW, &oldtty);
2334 fcntl(0, F_SETFL, old_fd0_flags);
2335}
2336
2337static void term_init(void)
2338{
2339 struct termios tty;
2340
2341 tcgetattr (0, &tty);
2342 oldtty = tty;
2343 old_fd0_flags = fcntl(0, F_GETFL);
2344
2345 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2346 |INLCR|IGNCR|ICRNL|IXON);
2347 tty.c_oflag |= OPOST;
2348 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2349 /* if graphical mode, we allow Ctrl-C handling */
2350 if (nographic)
2351 tty.c_lflag &= ~ISIG;
2352 tty.c_cflag &= ~(CSIZE|PARENB);
2353 tty.c_cflag |= CS8;
2354 tty.c_cc[VMIN] = 1;
2355 tty.c_cc[VTIME] = 0;
ths3b46e622007-09-17 08:09:54 +00002356
bellard8d11df92004-08-24 21:13:40 +00002357 tcsetattr (0, TCSANOW, &tty);
2358
balroga11d0702008-01-19 13:00:43 +00002359 if (!term_atexit_done++)
2360 atexit(term_exit);
bellard8d11df92004-08-24 21:13:40 +00002361
2362 fcntl(0, F_SETFL, O_NONBLOCK);
2363}
2364
balroga11d0702008-01-19 13:00:43 +00002365static void qemu_chr_close_stdio(struct CharDriverState *chr)
2366{
2367 term_exit();
2368 stdio_nb_clients--;
2369 qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2370 fd_chr_close(chr);
2371}
2372
ths52f61fd2006-12-22 21:20:52 +00002373static CharDriverState *qemu_chr_open_stdio(void)
bellard82c643f2004-07-14 17:28:13 +00002374{
2375 CharDriverState *chr;
2376
ths20d8a3e2007-02-18 17:04:49 +00002377 if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2378 return NULL;
2379 chr = qemu_chr_open_fd(0, 1);
balroga11d0702008-01-19 13:00:43 +00002380 chr->chr_close = qemu_chr_close_stdio;
ths20d8a3e2007-02-18 17:04:49 +00002381 qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2382 stdio_nb_clients++;
2383 term_init();
2384
bellard82c643f2004-07-14 17:28:13 +00002385 return chr;
2386}
2387
aurel3264b7b732008-05-05 10:05:31 +00002388#ifdef __sun__
2389/* Once Solaris has openpty(), this is going to be removed. */
2390int openpty(int *amaster, int *aslave, char *name,
2391 struct termios *termp, struct winsize *winp)
2392{
2393 const char *slave;
2394 int mfd = -1, sfd = -1;
2395
2396 *amaster = *aslave = -1;
2397
2398 mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
2399 if (mfd < 0)
2400 goto err;
2401
2402 if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
2403 goto err;
2404
2405 if ((slave = ptsname(mfd)) == NULL)
2406 goto err;
2407
2408 if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
2409 goto err;
2410
2411 if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
2412 (termp != NULL && tcgetattr(sfd, termp) < 0))
2413 goto err;
2414
2415 if (amaster)
2416 *amaster = mfd;
2417 if (aslave)
2418 *aslave = sfd;
2419 if (winp)
2420 ioctl(sfd, TIOCSWINSZ, winp);
2421
2422 return 0;
2423
2424err:
2425 if (sfd != -1)
2426 close(sfd);
2427 close(mfd);
2428 return -1;
2429}
2430
2431void cfmakeraw (struct termios *termios_p)
2432{
2433 termios_p->c_iflag &=
2434 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2435 termios_p->c_oflag &= ~OPOST;
2436 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2437 termios_p->c_cflag &= ~(CSIZE|PARENB);
2438 termios_p->c_cflag |= CS8;
2439
2440 termios_p->c_cc[VMIN] = 0;
2441 termios_p->c_cc[VTIME] = 0;
2442}
2443#endif
2444
thsaec62502007-06-25 11:48:07 +00002445#if defined(__linux__) || defined(__sun__)
ths52f61fd2006-12-22 21:20:52 +00002446static CharDriverState *qemu_chr_open_pty(void)
bellard82c643f2004-07-14 17:28:13 +00002447{
bellard91fc2112005-12-18 19:09:37 +00002448 struct termios tty;
bellard82c643f2004-07-14 17:28:13 +00002449 int master_fd, slave_fd;
ths3b46e622007-09-17 08:09:54 +00002450
aurel3264b7b732008-05-05 10:05:31 +00002451 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
bellard82c643f2004-07-14 17:28:13 +00002452 return NULL;
2453 }
ths3b46e622007-09-17 08:09:54 +00002454
aurel3264b7b732008-05-05 10:05:31 +00002455 /* Set raw attributes on the pty. */
2456 cfmakeraw(&tty);
2457 tcsetattr(slave_fd, TCSAFLUSH, &tty);
bellard91fc2112005-12-18 19:09:37 +00002458
aurel3264b7b732008-05-05 10:05:31 +00002459 fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
bellard82c643f2004-07-14 17:28:13 +00002460 return qemu_chr_open_fd(master_fd, master_fd);
2461}
bellardf8d179e2005-11-08 22:30:36 +00002462
ths5fafdf22007-09-16 21:08:06 +00002463static void tty_serial_init(int fd, int speed,
bellardf8d179e2005-11-08 22:30:36 +00002464 int parity, int data_bits, int stop_bits)
2465{
2466 struct termios tty;
2467 speed_t spd;
2468
bellarde57a8c02005-11-10 23:58:52 +00002469#if 0
ths5fafdf22007-09-16 21:08:06 +00002470 printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
bellarde57a8c02005-11-10 23:58:52 +00002471 speed, parity, data_bits, stop_bits);
2472#endif
2473 tcgetattr (fd, &tty);
bellardf8d179e2005-11-08 22:30:36 +00002474
balroga7954212008-01-14 03:41:02 +00002475#define MARGIN 1.1
2476 if (speed <= 50 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002477 spd = B50;
balroga7954212008-01-14 03:41:02 +00002478 else if (speed <= 75 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002479 spd = B75;
balroga7954212008-01-14 03:41:02 +00002480 else if (speed <= 300 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002481 spd = B300;
balroga7954212008-01-14 03:41:02 +00002482 else if (speed <= 600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002483 spd = B600;
balroga7954212008-01-14 03:41:02 +00002484 else if (speed <= 1200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002485 spd = B1200;
balroga7954212008-01-14 03:41:02 +00002486 else if (speed <= 2400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002487 spd = B2400;
balroga7954212008-01-14 03:41:02 +00002488 else if (speed <= 4800 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002489 spd = B4800;
balroga7954212008-01-14 03:41:02 +00002490 else if (speed <= 9600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002491 spd = B9600;
balroga7954212008-01-14 03:41:02 +00002492 else if (speed <= 19200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002493 spd = B19200;
balroga7954212008-01-14 03:41:02 +00002494 else if (speed <= 38400 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002495 spd = B38400;
balroga7954212008-01-14 03:41:02 +00002496 else if (speed <= 57600 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002497 spd = B57600;
balroga7954212008-01-14 03:41:02 +00002498 else if (speed <= 115200 * MARGIN)
bellardf8d179e2005-11-08 22:30:36 +00002499 spd = B115200;
balroga7954212008-01-14 03:41:02 +00002500 else
2501 spd = B115200;
bellardf8d179e2005-11-08 22:30:36 +00002502
2503 cfsetispeed(&tty, spd);
2504 cfsetospeed(&tty, spd);
2505
2506 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2507 |INLCR|IGNCR|ICRNL|IXON);
2508 tty.c_oflag |= OPOST;
2509 tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
bellard094eed62006-09-09 11:10:18 +00002510 tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
bellardf8d179e2005-11-08 22:30:36 +00002511 switch(data_bits) {
2512 default:
2513 case 8:
2514 tty.c_cflag |= CS8;
2515 break;
2516 case 7:
2517 tty.c_cflag |= CS7;
2518 break;
2519 case 6:
2520 tty.c_cflag |= CS6;
2521 break;
2522 case 5:
2523 tty.c_cflag |= CS5;
2524 break;
2525 }
2526 switch(parity) {
2527 default:
2528 case 'N':
2529 break;
2530 case 'E':
2531 tty.c_cflag |= PARENB;
2532 break;
2533 case 'O':
2534 tty.c_cflag |= PARENB | PARODD;
2535 break;
2536 }
bellard094eed62006-09-09 11:10:18 +00002537 if (stop_bits == 2)
2538 tty.c_cflag |= CSTOPB;
ths3b46e622007-09-17 08:09:54 +00002539
bellardf8d179e2005-11-08 22:30:36 +00002540 tcsetattr (fd, TCSANOW, &tty);
2541}
2542
bellarde57a8c02005-11-10 23:58:52 +00002543static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
bellardf8d179e2005-11-08 22:30:36 +00002544{
2545 FDCharDriver *s = chr->opaque;
ths3b46e622007-09-17 08:09:54 +00002546
bellarde57a8c02005-11-10 23:58:52 +00002547 switch(cmd) {
2548 case CHR_IOCTL_SERIAL_SET_PARAMS:
2549 {
2550 QEMUSerialSetParams *ssp = arg;
ths5fafdf22007-09-16 21:08:06 +00002551 tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
bellarde57a8c02005-11-10 23:58:52 +00002552 ssp->data_bits, ssp->stop_bits);
2553 }
2554 break;
2555 case CHR_IOCTL_SERIAL_SET_BREAK:
2556 {
2557 int enable = *(int *)arg;
2558 if (enable)
2559 tcsendbreak(s->fd_in, 1);
2560 }
2561 break;
2562 default:
2563 return -ENOTSUP;
2564 }
2565 return 0;
bellardf8d179e2005-11-08 22:30:36 +00002566}
2567
ths52f61fd2006-12-22 21:20:52 +00002568static CharDriverState *qemu_chr_open_tty(const char *filename)
bellardf8d179e2005-11-08 22:30:36 +00002569{
2570 CharDriverState *chr;
2571 int fd;
2572
balrogaeb30be2007-07-02 15:03:13 +00002573 TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
bellardf8d179e2005-11-08 22:30:36 +00002574 fcntl(fd, F_SETFL, O_NONBLOCK);
2575 tty_serial_init(fd, 115200, 'N', 8, 1);
2576 chr = qemu_chr_open_fd(fd, fd);
balrogaeb30be2007-07-02 15:03:13 +00002577 if (!chr) {
2578 close(fd);
bellardf8d179e2005-11-08 22:30:36 +00002579 return NULL;
balrogaeb30be2007-07-02 15:03:13 +00002580 }
bellarde57a8c02005-11-10 23:58:52 +00002581 chr->chr_ioctl = tty_serial_ioctl;
ths86e94de2007-01-05 22:01:59 +00002582 qemu_chr_reset(chr);
bellarde57a8c02005-11-10 23:58:52 +00002583 return chr;
2584}
thsaec62502007-06-25 11:48:07 +00002585#else /* ! __linux__ && ! __sun__ */
2586static CharDriverState *qemu_chr_open_pty(void)
2587{
2588 return NULL;
2589}
2590#endif /* __linux__ || __sun__ */
bellarde57a8c02005-11-10 23:58:52 +00002591
thsaec62502007-06-25 11:48:07 +00002592#if defined(__linux__)
ths5867c882007-02-17 23:44:43 +00002593typedef struct {
2594 int fd;
2595 int mode;
2596} ParallelCharDriver;
2597
2598static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2599{
2600 if (s->mode != mode) {
2601 int m = mode;
2602 if (ioctl(s->fd, PPSETMODE, &m) < 0)
2603 return 0;
2604 s->mode = mode;
2605 }
2606 return 1;
2607}
2608
bellarde57a8c02005-11-10 23:58:52 +00002609static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2610{
ths5867c882007-02-17 23:44:43 +00002611 ParallelCharDriver *drv = chr->opaque;
2612 int fd = drv->fd;
bellarde57a8c02005-11-10 23:58:52 +00002613 uint8_t b;
2614
2615 switch(cmd) {
2616 case CHR_IOCTL_PP_READ_DATA:
2617 if (ioctl(fd, PPRDATA, &b) < 0)
2618 return -ENOTSUP;
2619 *(uint8_t *)arg = b;
2620 break;
2621 case CHR_IOCTL_PP_WRITE_DATA:
2622 b = *(uint8_t *)arg;
2623 if (ioctl(fd, PPWDATA, &b) < 0)
2624 return -ENOTSUP;
2625 break;
2626 case CHR_IOCTL_PP_READ_CONTROL:
2627 if (ioctl(fd, PPRCONTROL, &b) < 0)
2628 return -ENOTSUP;
ths5867c882007-02-17 23:44:43 +00002629 /* Linux gives only the lowest bits, and no way to know data
2630 direction! For better compatibility set the fixed upper
2631 bits. */
2632 *(uint8_t *)arg = b | 0xc0;
bellarde57a8c02005-11-10 23:58:52 +00002633 break;
2634 case CHR_IOCTL_PP_WRITE_CONTROL:
2635 b = *(uint8_t *)arg;
2636 if (ioctl(fd, PPWCONTROL, &b) < 0)
2637 return -ENOTSUP;
2638 break;
2639 case CHR_IOCTL_PP_READ_STATUS:
2640 if (ioctl(fd, PPRSTATUS, &b) < 0)
2641 return -ENOTSUP;
2642 *(uint8_t *)arg = b;
2643 break;
ths5867c882007-02-17 23:44:43 +00002644 case CHR_IOCTL_PP_EPP_READ_ADDR:
2645 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2646 struct ParallelIOArg *parg = arg;
2647 int n = read(fd, parg->buffer, parg->count);
2648 if (n != parg->count) {
2649 return -EIO;
2650 }
2651 }
2652 break;
2653 case CHR_IOCTL_PP_EPP_READ:
2654 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2655 struct ParallelIOArg *parg = arg;
2656 int n = read(fd, parg->buffer, parg->count);
2657 if (n != parg->count) {
2658 return -EIO;
2659 }
2660 }
2661 break;
2662 case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2663 if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2664 struct ParallelIOArg *parg = arg;
2665 int n = write(fd, parg->buffer, parg->count);
2666 if (n != parg->count) {
2667 return -EIO;
2668 }
2669 }
2670 break;
2671 case CHR_IOCTL_PP_EPP_WRITE:
2672 if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2673 struct ParallelIOArg *parg = arg;
2674 int n = write(fd, parg->buffer, parg->count);
2675 if (n != parg->count) {
2676 return -EIO;
2677 }
2678 }
2679 break;
bellarde57a8c02005-11-10 23:58:52 +00002680 default:
2681 return -ENOTSUP;
2682 }
2683 return 0;
2684}
2685
ths5867c882007-02-17 23:44:43 +00002686static void pp_close(CharDriverState *chr)
2687{
2688 ParallelCharDriver *drv = chr->opaque;
2689 int fd = drv->fd;
2690
2691 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2692 ioctl(fd, PPRELEASE);
2693 close(fd);
2694 qemu_free(drv);
2695}
2696
ths52f61fd2006-12-22 21:20:52 +00002697static CharDriverState *qemu_chr_open_pp(const char *filename)
bellarde57a8c02005-11-10 23:58:52 +00002698{
2699 CharDriverState *chr;
ths5867c882007-02-17 23:44:43 +00002700 ParallelCharDriver *drv;
bellarde57a8c02005-11-10 23:58:52 +00002701 int fd;
2702
balrogaeb30be2007-07-02 15:03:13 +00002703 TFR(fd = open(filename, O_RDWR));
bellarde57a8c02005-11-10 23:58:52 +00002704 if (fd < 0)
2705 return NULL;
2706
2707 if (ioctl(fd, PPCLAIM) < 0) {
2708 close(fd);
2709 return NULL;
2710 }
2711
ths5867c882007-02-17 23:44:43 +00002712 drv = qemu_mallocz(sizeof(ParallelCharDriver));
2713 if (!drv) {
bellarde57a8c02005-11-10 23:58:52 +00002714 close(fd);
2715 return NULL;
2716 }
ths5867c882007-02-17 23:44:43 +00002717 drv->fd = fd;
2718 drv->mode = IEEE1284_MODE_COMPAT;
2719
2720 chr = qemu_mallocz(sizeof(CharDriverState));
2721 if (!chr) {
2722 qemu_free(drv);
2723 close(fd);
2724 return NULL;
2725 }
bellarde57a8c02005-11-10 23:58:52 +00002726 chr->chr_write = null_chr_write;
bellarde57a8c02005-11-10 23:58:52 +00002727 chr->chr_ioctl = pp_ioctl;
ths5867c882007-02-17 23:44:43 +00002728 chr->chr_close = pp_close;
2729 chr->opaque = drv;
ths86e94de2007-01-05 22:01:59 +00002730
2731 qemu_chr_reset(chr);
2732
bellardf8d179e2005-11-08 22:30:36 +00002733 return chr;
2734}
thsaec62502007-06-25 11:48:07 +00002735#endif /* __linux__ */
bellardf8d179e2005-11-08 22:30:36 +00002736
thsaec62502007-06-25 11:48:07 +00002737#else /* _WIN32 */
bellard67b915a2004-03-31 23:37:16 +00002738
bellardf3311102006-04-12 20:21:17 +00002739typedef struct {
bellardf3311102006-04-12 20:21:17 +00002740 int max_size;
2741 HANDLE hcom, hrecv, hsend;
2742 OVERLAPPED orecv, osend;
2743 BOOL fpipe;
2744 DWORD len;
2745} WinCharState;
2746
2747#define NSENDBUF 2048
2748#define NRECVBUF 2048
2749#define MAXCONNECT 1
2750#define NTIMEOUT 5000
2751
2752static int win_chr_poll(void *opaque);
2753static int win_chr_pipe_poll(void *opaque);
2754
ths087f4ae2007-02-10 21:50:42 +00002755static void win_chr_close(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002756{
ths087f4ae2007-02-10 21:50:42 +00002757 WinCharState *s = chr->opaque;
2758
bellardf3311102006-04-12 20:21:17 +00002759 if (s->hsend) {
2760 CloseHandle(s->hsend);
2761 s->hsend = NULL;
2762 }
2763 if (s->hrecv) {
2764 CloseHandle(s->hrecv);
2765 s->hrecv = NULL;
2766 }
2767 if (s->hcom) {
2768 CloseHandle(s->hcom);
2769 s->hcom = NULL;
2770 }
2771 if (s->fpipe)
ths087f4ae2007-02-10 21:50:42 +00002772 qemu_del_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002773 else
ths087f4ae2007-02-10 21:50:42 +00002774 qemu_del_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002775}
2776
ths087f4ae2007-02-10 21:50:42 +00002777static int win_chr_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00002778{
2779 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002780 COMMCONFIG comcfg;
2781 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2782 COMSTAT comstat;
2783 DWORD size;
2784 DWORD err;
ths3b46e622007-09-17 08:09:54 +00002785
bellardf3311102006-04-12 20:21:17 +00002786 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2787 if (!s->hsend) {
2788 fprintf(stderr, "Failed CreateEvent\n");
2789 goto fail;
2790 }
2791 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2792 if (!s->hrecv) {
2793 fprintf(stderr, "Failed CreateEvent\n");
2794 goto fail;
2795 }
2796
2797 s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2798 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2799 if (s->hcom == INVALID_HANDLE_VALUE) {
2800 fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2801 s->hcom = NULL;
2802 goto fail;
2803 }
ths3b46e622007-09-17 08:09:54 +00002804
bellardf3311102006-04-12 20:21:17 +00002805 if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
2806 fprintf(stderr, "Failed SetupComm\n");
2807 goto fail;
2808 }
ths3b46e622007-09-17 08:09:54 +00002809
bellardf3311102006-04-12 20:21:17 +00002810 ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2811 size = sizeof(COMMCONFIG);
2812 GetDefaultCommConfig(filename, &comcfg, &size);
2813 comcfg.dcb.DCBlength = sizeof(DCB);
2814 CommConfigDialog(filename, NULL, &comcfg);
2815
2816 if (!SetCommState(s->hcom, &comcfg.dcb)) {
2817 fprintf(stderr, "Failed SetCommState\n");
2818 goto fail;
2819 }
2820
2821 if (!SetCommMask(s->hcom, EV_ERR)) {
2822 fprintf(stderr, "Failed SetCommMask\n");
2823 goto fail;
2824 }
2825
2826 cto.ReadIntervalTimeout = MAXDWORD;
2827 if (!SetCommTimeouts(s->hcom, &cto)) {
2828 fprintf(stderr, "Failed SetCommTimeouts\n");
2829 goto fail;
2830 }
ths3b46e622007-09-17 08:09:54 +00002831
bellardf3311102006-04-12 20:21:17 +00002832 if (!ClearCommError(s->hcom, &err, &comstat)) {
2833 fprintf(stderr, "Failed ClearCommError\n");
2834 goto fail;
2835 }
ths087f4ae2007-02-10 21:50:42 +00002836 qemu_add_polling_cb(win_chr_poll, chr);
bellardf3311102006-04-12 20:21:17 +00002837 return 0;
2838
2839 fail:
ths087f4ae2007-02-10 21:50:42 +00002840 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00002841 return -1;
2842}
2843
2844static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
2845{
2846 WinCharState *s = chr->opaque;
2847 DWORD len, ret, size, err;
2848
2849 len = len1;
2850 ZeroMemory(&s->osend, sizeof(s->osend));
2851 s->osend.hEvent = s->hsend;
2852 while (len > 0) {
2853 if (s->hsend)
2854 ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2855 else
2856 ret = WriteFile(s->hcom, buf, len, &size, NULL);
2857 if (!ret) {
2858 err = GetLastError();
2859 if (err == ERROR_IO_PENDING) {
2860 ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2861 if (ret) {
2862 buf += size;
2863 len -= size;
2864 } else {
2865 break;
2866 }
2867 } else {
2868 break;
2869 }
2870 } else {
2871 buf += size;
2872 len -= size;
2873 }
2874 }
2875 return len1 - len;
2876}
2877
ths087f4ae2007-02-10 21:50:42 +00002878static int win_chr_read_poll(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002879{
ths087f4ae2007-02-10 21:50:42 +00002880 WinCharState *s = chr->opaque;
2881
2882 s->max_size = qemu_chr_can_read(chr);
bellardf3311102006-04-12 20:21:17 +00002883 return s->max_size;
2884}
pbrooke5b0bc42007-01-27 23:46:43 +00002885
ths087f4ae2007-02-10 21:50:42 +00002886static void win_chr_readfile(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002887{
ths087f4ae2007-02-10 21:50:42 +00002888 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002889 int ret, err;
2890 uint8_t buf[1024];
2891 DWORD size;
ths3b46e622007-09-17 08:09:54 +00002892
bellardf3311102006-04-12 20:21:17 +00002893 ZeroMemory(&s->orecv, sizeof(s->orecv));
2894 s->orecv.hEvent = s->hrecv;
2895 ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2896 if (!ret) {
2897 err = GetLastError();
2898 if (err == ERROR_IO_PENDING) {
2899 ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2900 }
2901 }
2902
2903 if (size > 0) {
ths087f4ae2007-02-10 21:50:42 +00002904 qemu_chr_read(chr, buf, size);
bellardf3311102006-04-12 20:21:17 +00002905 }
2906}
2907
ths087f4ae2007-02-10 21:50:42 +00002908static void win_chr_read(CharDriverState *chr)
bellardf3311102006-04-12 20:21:17 +00002909{
ths087f4ae2007-02-10 21:50:42 +00002910 WinCharState *s = chr->opaque;
2911
bellardf3311102006-04-12 20:21:17 +00002912 if (s->len > s->max_size)
2913 s->len = s->max_size;
2914 if (s->len == 0)
2915 return;
ths3b46e622007-09-17 08:09:54 +00002916
ths087f4ae2007-02-10 21:50:42 +00002917 win_chr_readfile(chr);
bellardf3311102006-04-12 20:21:17 +00002918}
2919
2920static int win_chr_poll(void *opaque)
2921{
ths087f4ae2007-02-10 21:50:42 +00002922 CharDriverState *chr = opaque;
2923 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002924 COMSTAT status;
2925 DWORD comerr;
ths3b46e622007-09-17 08:09:54 +00002926
bellardf3311102006-04-12 20:21:17 +00002927 ClearCommError(s->hcom, &comerr, &status);
2928 if (status.cbInQue > 0) {
2929 s->len = status.cbInQue;
ths087f4ae2007-02-10 21:50:42 +00002930 win_chr_read_poll(chr);
2931 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00002932 return 1;
2933 }
2934 return 0;
2935}
2936
ths52f61fd2006-12-22 21:20:52 +00002937static CharDriverState *qemu_chr_open_win(const char *filename)
bellardf3311102006-04-12 20:21:17 +00002938{
2939 CharDriverState *chr;
2940 WinCharState *s;
ths3b46e622007-09-17 08:09:54 +00002941
bellardf3311102006-04-12 20:21:17 +00002942 chr = qemu_mallocz(sizeof(CharDriverState));
2943 if (!chr)
2944 return NULL;
2945 s = qemu_mallocz(sizeof(WinCharState));
2946 if (!s) {
2947 free(chr);
2948 return NULL;
2949 }
2950 chr->opaque = s;
2951 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00002952 chr->chr_close = win_chr_close;
2953
ths087f4ae2007-02-10 21:50:42 +00002954 if (win_chr_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00002955 free(s);
2956 free(chr);
2957 return NULL;
2958 }
ths86e94de2007-01-05 22:01:59 +00002959 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00002960 return chr;
2961}
2962
2963static int win_chr_pipe_poll(void *opaque)
2964{
ths087f4ae2007-02-10 21:50:42 +00002965 CharDriverState *chr = opaque;
2966 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002967 DWORD size;
2968
2969 PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2970 if (size > 0) {
2971 s->len = size;
ths087f4ae2007-02-10 21:50:42 +00002972 win_chr_read_poll(chr);
2973 win_chr_read(chr);
bellardf3311102006-04-12 20:21:17 +00002974 return 1;
2975 }
2976 return 0;
2977}
2978
ths087f4ae2007-02-10 21:50:42 +00002979static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
bellardf3311102006-04-12 20:21:17 +00002980{
ths087f4ae2007-02-10 21:50:42 +00002981 WinCharState *s = chr->opaque;
bellardf3311102006-04-12 20:21:17 +00002982 OVERLAPPED ov;
2983 int ret;
2984 DWORD size;
2985 char openname[256];
ths3b46e622007-09-17 08:09:54 +00002986
bellardf3311102006-04-12 20:21:17 +00002987 s->fpipe = TRUE;
2988
2989 s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2990 if (!s->hsend) {
2991 fprintf(stderr, "Failed CreateEvent\n");
2992 goto fail;
2993 }
2994 s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2995 if (!s->hrecv) {
2996 fprintf(stderr, "Failed CreateEvent\n");
2997 goto fail;
2998 }
ths3b46e622007-09-17 08:09:54 +00002999
bellardf3311102006-04-12 20:21:17 +00003000 snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
3001 s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
3002 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
3003 PIPE_WAIT,
3004 MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
3005 if (s->hcom == INVALID_HANDLE_VALUE) {
3006 fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
3007 s->hcom = NULL;
3008 goto fail;
3009 }
3010
3011 ZeroMemory(&ov, sizeof(ov));
3012 ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
3013 ret = ConnectNamedPipe(s->hcom, &ov);
3014 if (ret) {
3015 fprintf(stderr, "Failed ConnectNamedPipe\n");
3016 goto fail;
3017 }
3018
3019 ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
3020 if (!ret) {
3021 fprintf(stderr, "Failed GetOverlappedResult\n");
3022 if (ov.hEvent) {
3023 CloseHandle(ov.hEvent);
3024 ov.hEvent = NULL;
3025 }
3026 goto fail;
3027 }
3028
3029 if (ov.hEvent) {
3030 CloseHandle(ov.hEvent);
3031 ov.hEvent = NULL;
3032 }
ths087f4ae2007-02-10 21:50:42 +00003033 qemu_add_polling_cb(win_chr_pipe_poll, chr);
bellardf3311102006-04-12 20:21:17 +00003034 return 0;
3035
3036 fail:
ths087f4ae2007-02-10 21:50:42 +00003037 win_chr_close(chr);
bellardf3311102006-04-12 20:21:17 +00003038 return -1;
3039}
3040
3041
ths52f61fd2006-12-22 21:20:52 +00003042static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
bellardf3311102006-04-12 20:21:17 +00003043{
3044 CharDriverState *chr;
3045 WinCharState *s;
3046
3047 chr = qemu_mallocz(sizeof(CharDriverState));
3048 if (!chr)
3049 return NULL;
3050 s = qemu_mallocz(sizeof(WinCharState));
3051 if (!s) {
3052 free(chr);
3053 return NULL;
3054 }
3055 chr->opaque = s;
3056 chr->chr_write = win_chr_write;
bellardf3311102006-04-12 20:21:17 +00003057 chr->chr_close = win_chr_close;
ths3b46e622007-09-17 08:09:54 +00003058
ths087f4ae2007-02-10 21:50:42 +00003059 if (win_chr_pipe_init(chr, filename) < 0) {
bellardf3311102006-04-12 20:21:17 +00003060 free(s);
3061 free(chr);
3062 return NULL;
3063 }
ths86e94de2007-01-05 22:01:59 +00003064 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003065 return chr;
3066}
3067
ths52f61fd2006-12-22 21:20:52 +00003068static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
bellardf3311102006-04-12 20:21:17 +00003069{
3070 CharDriverState *chr;
3071 WinCharState *s;
3072
3073 chr = qemu_mallocz(sizeof(CharDriverState));
3074 if (!chr)
3075 return NULL;
3076 s = qemu_mallocz(sizeof(WinCharState));
3077 if (!s) {
3078 free(chr);
3079 return NULL;
3080 }
3081 s->hcom = fd_out;
3082 chr->opaque = s;
3083 chr->chr_write = win_chr_write;
ths86e94de2007-01-05 22:01:59 +00003084 qemu_chr_reset(chr);
bellardf3311102006-04-12 20:21:17 +00003085 return chr;
3086}
ths72d46472007-05-13 14:54:54 +00003087
3088static CharDriverState *qemu_chr_open_win_con(const char *filename)
3089{
3090 return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
3091}
3092
ths52f61fd2006-12-22 21:20:52 +00003093static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
bellardf3311102006-04-12 20:21:17 +00003094{
3095 HANDLE fd_out;
ths3b46e622007-09-17 08:09:54 +00003096
bellardf3311102006-04-12 20:21:17 +00003097 fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3098 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3099 if (fd_out == INVALID_HANDLE_VALUE)
3100 return NULL;
3101
3102 return qemu_chr_open_win_file(fd_out);
3103}
thsaec62502007-06-25 11:48:07 +00003104#endif /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003105
bellard0bab00f2006-06-25 14:49:44 +00003106/***********************************************************/
3107/* UDP Net console */
3108
3109typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003110 int fd;
3111 struct sockaddr_in daddr;
ths60fe76f2007-12-16 03:02:09 +00003112 uint8_t buf[1024];
bellard0bab00f2006-06-25 14:49:44 +00003113 int bufcnt;
3114 int bufptr;
3115 int max_size;
3116} NetCharDriver;
3117
3118static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3119{
3120 NetCharDriver *s = chr->opaque;
3121
3122 return sendto(s->fd, buf, len, 0,
3123 (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
3124}
3125
3126static int udp_chr_read_poll(void *opaque)
3127{
3128 CharDriverState *chr = opaque;
3129 NetCharDriver *s = chr->opaque;
3130
pbrooke5b0bc42007-01-27 23:46:43 +00003131 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003132
3133 /* If there were any stray characters in the queue process them
3134 * first
3135 */
3136 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003137 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003138 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003139 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003140 }
3141 return s->max_size;
3142}
3143
3144static void udp_chr_read(void *opaque)
3145{
3146 CharDriverState *chr = opaque;
3147 NetCharDriver *s = chr->opaque;
3148
3149 if (s->max_size == 0)
3150 return;
3151 s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
3152 s->bufptr = s->bufcnt;
3153 if (s->bufcnt <= 0)
3154 return;
3155
3156 s->bufptr = 0;
3157 while (s->max_size > 0 && s->bufptr < s->bufcnt) {
pbrooke5b0bc42007-01-27 23:46:43 +00003158 qemu_chr_read(chr, &s->buf[s->bufptr], 1);
bellard0bab00f2006-06-25 14:49:44 +00003159 s->bufptr++;
pbrooke5b0bc42007-01-27 23:46:43 +00003160 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003161 }
3162}
3163
pbrooke5b0bc42007-01-27 23:46:43 +00003164static void udp_chr_update_read_handler(CharDriverState *chr)
bellard0bab00f2006-06-25 14:49:44 +00003165{
3166 NetCharDriver *s = chr->opaque;
3167
3168 if (s->fd >= 0) {
bellard0bab00f2006-06-25 14:49:44 +00003169 qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
3170 udp_chr_read, NULL, chr);
3171 }
3172}
3173
3174int parse_host_port(struct sockaddr_in *saddr, const char *str);
ths52f61fd2006-12-22 21:20:52 +00003175#ifndef _WIN32
3176static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3177#endif
bellard951f1352006-06-27 21:02:43 +00003178int parse_host_src_port(struct sockaddr_in *haddr,
3179 struct sockaddr_in *saddr,
3180 const char *str);
bellard0bab00f2006-06-25 14:49:44 +00003181
ths52f61fd2006-12-22 21:20:52 +00003182static CharDriverState *qemu_chr_open_udp(const char *def)
bellard0bab00f2006-06-25 14:49:44 +00003183{
3184 CharDriverState *chr = NULL;
3185 NetCharDriver *s = NULL;
3186 int fd = -1;
bellard951f1352006-06-27 21:02:43 +00003187 struct sockaddr_in saddr;
bellard0bab00f2006-06-25 14:49:44 +00003188
3189 chr = qemu_mallocz(sizeof(CharDriverState));
3190 if (!chr)
3191 goto return_err;
3192 s = qemu_mallocz(sizeof(NetCharDriver));
3193 if (!s)
3194 goto return_err;
3195
3196 fd = socket(PF_INET, SOCK_DGRAM, 0);
3197 if (fd < 0) {
3198 perror("socket(PF_INET, SOCK_DGRAM)");
3199 goto return_err;
3200 }
3201
bellard951f1352006-06-27 21:02:43 +00003202 if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
3203 printf("Could not parse: %s\n", def);
3204 goto return_err;
bellard0bab00f2006-06-25 14:49:44 +00003205 }
3206
bellard951f1352006-06-27 21:02:43 +00003207 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
bellard0bab00f2006-06-25 14:49:44 +00003208 {
3209 perror("bind");
3210 goto return_err;
3211 }
3212
3213 s->fd = fd;
3214 s->bufcnt = 0;
3215 s->bufptr = 0;
3216 chr->opaque = s;
3217 chr->chr_write = udp_chr_write;
pbrooke5b0bc42007-01-27 23:46:43 +00003218 chr->chr_update_read_handler = udp_chr_update_read_handler;
bellard0bab00f2006-06-25 14:49:44 +00003219 return chr;
3220
3221return_err:
3222 if (chr)
3223 free(chr);
3224 if (s)
3225 free(s);
3226 if (fd >= 0)
3227 closesocket(fd);
3228 return NULL;
3229}
3230
3231/***********************************************************/
3232/* TCP Net console */
3233
3234typedef struct {
bellard0bab00f2006-06-25 14:49:44 +00003235 int fd, listen_fd;
3236 int connected;
3237 int max_size;
bellard951f1352006-06-27 21:02:43 +00003238 int do_telnetopt;
pbrooke5b0bc42007-01-27 23:46:43 +00003239 int do_nodelay;
thsffd843b2006-12-21 19:46:43 +00003240 int is_unix;
bellard0bab00f2006-06-25 14:49:44 +00003241} TCPCharDriver;
3242
3243static void tcp_chr_accept(void *opaque);
3244
3245static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3246{
3247 TCPCharDriver *s = chr->opaque;
3248 if (s->connected) {
3249 return send_all(s->fd, buf, len);
3250 } else {
3251 /* XXX: indicate an error ? */
3252 return len;
3253 }
3254}
3255
3256static int tcp_chr_read_poll(void *opaque)
3257{
3258 CharDriverState *chr = opaque;
3259 TCPCharDriver *s = chr->opaque;
3260 if (!s->connected)
3261 return 0;
pbrooke5b0bc42007-01-27 23:46:43 +00003262 s->max_size = qemu_chr_can_read(chr);
bellard0bab00f2006-06-25 14:49:44 +00003263 return s->max_size;
3264}
3265
bellard951f1352006-06-27 21:02:43 +00003266#define IAC 255
3267#define IAC_BREAK 243
3268static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
3269 TCPCharDriver *s,
ths60fe76f2007-12-16 03:02:09 +00003270 uint8_t *buf, int *size)
bellard951f1352006-06-27 21:02:43 +00003271{
3272 /* Handle any telnet client's basic IAC options to satisfy char by
3273 * char mode with no echo. All IAC options will be removed from
3274 * the buf and the do_telnetopt variable will be used to track the
3275 * state of the width of the IAC information.
3276 *
3277 * IAC commands come in sets of 3 bytes with the exception of the
3278 * "IAC BREAK" command and the double IAC.
3279 */
3280
3281 int i;
3282 int j = 0;
3283
3284 for (i = 0; i < *size; i++) {
3285 if (s->do_telnetopt > 1) {
3286 if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3287 /* Double IAC means send an IAC */
3288 if (j != i)
3289 buf[j] = buf[i];
3290 j++;
3291 s->do_telnetopt = 1;
3292 } else {
3293 if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3294 /* Handle IAC break commands by sending a serial break */
pbrooke5b0bc42007-01-27 23:46:43 +00003295 qemu_chr_event(chr, CHR_EVENT_BREAK);
bellard951f1352006-06-27 21:02:43 +00003296 s->do_telnetopt++;
3297 }
3298 s->do_telnetopt++;
3299 }
3300 if (s->do_telnetopt >= 4) {
3301 s->do_telnetopt = 1;
3302 }
3303 } else {
3304 if ((unsigned char)buf[i] == IAC) {
3305 s->do_telnetopt = 2;
3306 } else {
3307 if (j != i)
3308 buf[j] = buf[i];
3309 j++;
3310 }
3311 }
3312 }
3313 *size = j;
3314}
3315
bellard0bab00f2006-06-25 14:49:44 +00003316static void tcp_chr_read(void *opaque)
3317{
3318 CharDriverState *chr = opaque;
3319 TCPCharDriver *s = chr->opaque;
3320 uint8_t buf[1024];
3321 int len, size;
3322
3323 if (!s->connected || s->max_size <= 0)
3324 return;
3325 len = sizeof(buf);
3326 if (len > s->max_size)
3327 len = s->max_size;
3328 size = recv(s->fd, buf, len, 0);
3329 if (size == 0) {
3330 /* connection closed */
3331 s->connected = 0;
3332 if (s->listen_fd >= 0) {
3333 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3334 }
3335 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3336 closesocket(s->fd);
3337 s->fd = -1;
3338 } else if (size > 0) {
bellard951f1352006-06-27 21:02:43 +00003339 if (s->do_telnetopt)
3340 tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3341 if (size > 0)
pbrooke5b0bc42007-01-27 23:46:43 +00003342 qemu_chr_read(chr, buf, size);
bellard0bab00f2006-06-25 14:49:44 +00003343 }
3344}
3345
bellard0bab00f2006-06-25 14:49:44 +00003346static void tcp_chr_connect(void *opaque)
3347{
3348 CharDriverState *chr = opaque;
3349 TCPCharDriver *s = chr->opaque;
3350
3351 s->connected = 1;
3352 qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3353 tcp_chr_read, NULL, chr);
ths86e94de2007-01-05 22:01:59 +00003354 qemu_chr_reset(chr);
bellard0bab00f2006-06-25 14:49:44 +00003355}
3356
bellard951f1352006-06-27 21:02:43 +00003357#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3358static void tcp_chr_telnet_init(int fd)
3359{
3360 char buf[3];
3361 /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3362 IACSET(buf, 0xff, 0xfb, 0x01); /* IAC WILL ECHO */
3363 send(fd, (char *)buf, 3, 0);
3364 IACSET(buf, 0xff, 0xfb, 0x03); /* IAC WILL Suppress go ahead */
3365 send(fd, (char *)buf, 3, 0);
3366 IACSET(buf, 0xff, 0xfb, 0x00); /* IAC WILL Binary */
3367 send(fd, (char *)buf, 3, 0);
3368 IACSET(buf, 0xff, 0xfd, 0x00); /* IAC DO Binary */
3369 send(fd, (char *)buf, 3, 0);
3370}
3371
pbrookf7499982007-01-28 00:10:01 +00003372static void socket_set_nodelay(int fd)
3373{
3374 int val = 1;
3375 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3376}
3377
bellard0bab00f2006-06-25 14:49:44 +00003378static void tcp_chr_accept(void *opaque)
3379{
3380 CharDriverState *chr = opaque;
3381 TCPCharDriver *s = chr->opaque;
3382 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003383#ifndef _WIN32
3384 struct sockaddr_un uaddr;
3385#endif
3386 struct sockaddr *addr;
bellard0bab00f2006-06-25 14:49:44 +00003387 socklen_t len;
3388 int fd;
3389
3390 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003391#ifndef _WIN32
3392 if (s->is_unix) {
3393 len = sizeof(uaddr);
3394 addr = (struct sockaddr *)&uaddr;
3395 } else
3396#endif
3397 {
3398 len = sizeof(saddr);
3399 addr = (struct sockaddr *)&saddr;
3400 }
3401 fd = accept(s->listen_fd, addr, &len);
bellard0bab00f2006-06-25 14:49:44 +00003402 if (fd < 0 && errno != EINTR) {
3403 return;
3404 } else if (fd >= 0) {
bellard951f1352006-06-27 21:02:43 +00003405 if (s->do_telnetopt)
3406 tcp_chr_telnet_init(fd);
bellard0bab00f2006-06-25 14:49:44 +00003407 break;
3408 }
3409 }
3410 socket_set_nonblock(fd);
pbrookf7499982007-01-28 00:10:01 +00003411 if (s->do_nodelay)
3412 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003413 s->fd = fd;
3414 qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3415 tcp_chr_connect(chr);
3416}
3417
3418static void tcp_chr_close(CharDriverState *chr)
3419{
3420 TCPCharDriver *s = chr->opaque;
3421 if (s->fd >= 0)
3422 closesocket(s->fd);
3423 if (s->listen_fd >= 0)
3424 closesocket(s->listen_fd);
3425 qemu_free(s);
3426}
3427
ths5fafdf22007-09-16 21:08:06 +00003428static CharDriverState *qemu_chr_open_tcp(const char *host_str,
thsffd843b2006-12-21 19:46:43 +00003429 int is_telnet,
3430 int is_unix)
bellard0bab00f2006-06-25 14:49:44 +00003431{
3432 CharDriverState *chr = NULL;
3433 TCPCharDriver *s = NULL;
3434 int fd = -1, ret, err, val;
bellard951f1352006-06-27 21:02:43 +00003435 int is_listen = 0;
3436 int is_waitconnect = 1;
pbrookf7499982007-01-28 00:10:01 +00003437 int do_nodelay = 0;
bellard951f1352006-06-27 21:02:43 +00003438 const char *ptr;
bellard0bab00f2006-06-25 14:49:44 +00003439 struct sockaddr_in saddr;
thsffd843b2006-12-21 19:46:43 +00003440#ifndef _WIN32
3441 struct sockaddr_un uaddr;
3442#endif
3443 struct sockaddr *addr;
3444 socklen_t addrlen;
bellard0bab00f2006-06-25 14:49:44 +00003445
thsffd843b2006-12-21 19:46:43 +00003446#ifndef _WIN32
3447 if (is_unix) {
3448 addr = (struct sockaddr *)&uaddr;
3449 addrlen = sizeof(uaddr);
3450 if (parse_unix_path(&uaddr, host_str) < 0)
3451 goto fail;
3452 } else
3453#endif
3454 {
3455 addr = (struct sockaddr *)&saddr;
3456 addrlen = sizeof(saddr);
3457 if (parse_host_port(&saddr, host_str) < 0)
3458 goto fail;
3459 }
bellard0bab00f2006-06-25 14:49:44 +00003460
bellard951f1352006-06-27 21:02:43 +00003461 ptr = host_str;
3462 while((ptr = strchr(ptr,','))) {
3463 ptr++;
3464 if (!strncmp(ptr,"server",6)) {
3465 is_listen = 1;
3466 } else if (!strncmp(ptr,"nowait",6)) {
3467 is_waitconnect = 0;
pbrookf7499982007-01-28 00:10:01 +00003468 } else if (!strncmp(ptr,"nodelay",6)) {
3469 do_nodelay = 1;
bellard951f1352006-06-27 21:02:43 +00003470 } else {
3471 printf("Unknown option: %s\n", ptr);
3472 goto fail;
3473 }
3474 }
3475 if (!is_listen)
3476 is_waitconnect = 0;
3477
bellard0bab00f2006-06-25 14:49:44 +00003478 chr = qemu_mallocz(sizeof(CharDriverState));
3479 if (!chr)
3480 goto fail;
3481 s = qemu_mallocz(sizeof(TCPCharDriver));
3482 if (!s)
3483 goto fail;
thsffd843b2006-12-21 19:46:43 +00003484
3485#ifndef _WIN32
3486 if (is_unix)
3487 fd = socket(PF_UNIX, SOCK_STREAM, 0);
3488 else
3489#endif
3490 fd = socket(PF_INET, SOCK_STREAM, 0);
ths5fafdf22007-09-16 21:08:06 +00003491
3492 if (fd < 0)
bellard0bab00f2006-06-25 14:49:44 +00003493 goto fail;
bellard951f1352006-06-27 21:02:43 +00003494
3495 if (!is_waitconnect)
3496 socket_set_nonblock(fd);
bellard0bab00f2006-06-25 14:49:44 +00003497
3498 s->connected = 0;
3499 s->fd = -1;
3500 s->listen_fd = -1;
thsffd843b2006-12-21 19:46:43 +00003501 s->is_unix = is_unix;
pbrookf7499982007-01-28 00:10:01 +00003502 s->do_nodelay = do_nodelay && !is_unix;
thsffd843b2006-12-21 19:46:43 +00003503
3504 chr->opaque = s;
3505 chr->chr_write = tcp_chr_write;
thsffd843b2006-12-21 19:46:43 +00003506 chr->chr_close = tcp_chr_close;
3507
bellard0bab00f2006-06-25 14:49:44 +00003508 if (is_listen) {
3509 /* allow fast reuse */
thsffd843b2006-12-21 19:46:43 +00003510#ifndef _WIN32
3511 if (is_unix) {
3512 char path[109];
bellardae45d362008-06-11 09:44:44 +00003513 pstrcpy(path, sizeof(path), uaddr.sun_path);
thsffd843b2006-12-21 19:46:43 +00003514 unlink(path);
3515 } else
3516#endif
3517 {
3518 val = 1;
3519 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3520 }
ths3b46e622007-09-17 08:09:54 +00003521
thsffd843b2006-12-21 19:46:43 +00003522 ret = bind(fd, addr, addrlen);
3523 if (ret < 0)
bellard0bab00f2006-06-25 14:49:44 +00003524 goto fail;
thsffd843b2006-12-21 19:46:43 +00003525
bellard0bab00f2006-06-25 14:49:44 +00003526 ret = listen(fd, 0);
3527 if (ret < 0)
3528 goto fail;
thsffd843b2006-12-21 19:46:43 +00003529
bellard0bab00f2006-06-25 14:49:44 +00003530 s->listen_fd = fd;
3531 qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
bellard951f1352006-06-27 21:02:43 +00003532 if (is_telnet)
3533 s->do_telnetopt = 1;
bellard0bab00f2006-06-25 14:49:44 +00003534 } else {
3535 for(;;) {
thsffd843b2006-12-21 19:46:43 +00003536 ret = connect(fd, addr, addrlen);
bellard0bab00f2006-06-25 14:49:44 +00003537 if (ret < 0) {
3538 err = socket_error();
3539 if (err == EINTR || err == EWOULDBLOCK) {
3540 } else if (err == EINPROGRESS) {
3541 break;
thsf5b12262007-03-25 15:58:03 +00003542#ifdef _WIN32
3543 } else if (err == WSAEALREADY) {
3544 break;
3545#endif
bellard0bab00f2006-06-25 14:49:44 +00003546 } else {
3547 goto fail;
3548 }
3549 } else {
3550 s->connected = 1;
3551 break;
3552 }
3553 }
3554 s->fd = fd;
pbrookf7499982007-01-28 00:10:01 +00003555 socket_set_nodelay(fd);
bellard0bab00f2006-06-25 14:49:44 +00003556 if (s->connected)
3557 tcp_chr_connect(chr);
3558 else
3559 qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3560 }
ths3b46e622007-09-17 08:09:54 +00003561
bellard951f1352006-06-27 21:02:43 +00003562 if (is_listen && is_waitconnect) {
3563 printf("QEMU waiting for connection on: %s\n", host_str);
3564 tcp_chr_accept(chr);
3565 socket_set_nonblock(s->listen_fd);
3566 }
3567
bellard0bab00f2006-06-25 14:49:44 +00003568 return chr;
3569 fail:
3570 if (fd >= 0)
3571 closesocket(fd);
3572 qemu_free(s);
3573 qemu_free(chr);
3574 return NULL;
3575}
3576
bellard82c643f2004-07-14 17:28:13 +00003577CharDriverState *qemu_chr_open(const char *filename)
3578{
bellardf8d179e2005-11-08 22:30:36 +00003579 const char *p;
bellardfd1dff42006-02-01 21:29:26 +00003580
bellard82c643f2004-07-14 17:28:13 +00003581 if (!strcmp(filename, "vc")) {
thsaf3a9032007-07-11 23:14:59 +00003582 return text_console_init(&display_state, 0);
3583 } else if (strstart(filename, "vc:", &p)) {
3584 return text_console_init(&display_state, p);
bellard82c643f2004-07-14 17:28:13 +00003585 } else if (!strcmp(filename, "null")) {
3586 return qemu_chr_open_null();
ths5fafdf22007-09-16 21:08:06 +00003587 } else
bellard0bab00f2006-06-25 14:49:44 +00003588 if (strstart(filename, "tcp:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003589 return qemu_chr_open_tcp(p, 0, 0);
bellard0bab00f2006-06-25 14:49:44 +00003590 } else
bellard951f1352006-06-27 21:02:43 +00003591 if (strstart(filename, "telnet:", &p)) {
thsffd843b2006-12-21 19:46:43 +00003592 return qemu_chr_open_tcp(p, 1, 0);
bellard0bab00f2006-06-25 14:49:44 +00003593 } else
3594 if (strstart(filename, "udp:", &p)) {
3595 return qemu_chr_open_udp(p);
3596 } else
ths20d8a3e2007-02-18 17:04:49 +00003597 if (strstart(filename, "mon:", &p)) {
3598 CharDriverState *drv = qemu_chr_open(p);
3599 if (drv) {
3600 drv = qemu_chr_open_mux(drv);
3601 monitor_init(drv, !nographic);
3602 return drv;
3603 }
3604 printf("Unable to open driver: %s\n", p);
3605 return 0;
3606 } else
bellard76647282005-11-27 19:10:42 +00003607#ifndef _WIN32
thsffd843b2006-12-21 19:46:43 +00003608 if (strstart(filename, "unix:", &p)) {
3609 return qemu_chr_open_tcp(p, 0, 1);
3610 } else if (strstart(filename, "file:", &p)) {
bellardf8d179e2005-11-08 22:30:36 +00003611 return qemu_chr_open_file_out(p);
3612 } else if (strstart(filename, "pipe:", &p)) {
3613 return qemu_chr_open_pipe(p);
bellard76647282005-11-27 19:10:42 +00003614 } else if (!strcmp(filename, "pty")) {
bellard82c643f2004-07-14 17:28:13 +00003615 return qemu_chr_open_pty();
3616 } else if (!strcmp(filename, "stdio")) {
3617 return qemu_chr_open_stdio();
ths5fafdf22007-09-16 21:08:06 +00003618 } else
bellardf8d179e2005-11-08 22:30:36 +00003619#if defined(__linux__)
bellarde57a8c02005-11-10 23:58:52 +00003620 if (strstart(filename, "/dev/parport", NULL)) {
3621 return qemu_chr_open_pp(filename);
ths5fafdf22007-09-16 21:08:06 +00003622 } else
thsaec62502007-06-25 11:48:07 +00003623#endif
ths3fda3882007-06-28 15:14:49 +00003624#if defined(__linux__) || defined(__sun__)
bellardf8d179e2005-11-08 22:30:36 +00003625 if (strstart(filename, "/dev/", NULL)) {
3626 return qemu_chr_open_tty(filename);
ths3fda3882007-06-28 15:14:49 +00003627 } else
3628#endif
thsaec62502007-06-25 11:48:07 +00003629#else /* !_WIN32 */
bellardf3311102006-04-12 20:21:17 +00003630 if (strstart(filename, "COM", NULL)) {
3631 return qemu_chr_open_win(filename);
3632 } else
3633 if (strstart(filename, "pipe:", &p)) {
3634 return qemu_chr_open_win_pipe(p);
3635 } else
ths72d46472007-05-13 14:54:54 +00003636 if (strstart(filename, "con:", NULL)) {
3637 return qemu_chr_open_win_con(filename);
3638 } else
bellardf3311102006-04-12 20:21:17 +00003639 if (strstart(filename, "file:", &p)) {
3640 return qemu_chr_open_win_file_out(p);
aurel322e4d9fb2008-04-08 06:01:02 +00003641 } else
3642#endif
3643#ifdef CONFIG_BRLAPI
3644 if (!strcmp(filename, "braille")) {
3645 return chr_baum_init();
3646 } else
bellardf3311102006-04-12 20:21:17 +00003647#endif
bellard82c643f2004-07-14 17:28:13 +00003648 {
3649 return NULL;
3650 }
3651}
3652
bellardf3311102006-04-12 20:21:17 +00003653void qemu_chr_close(CharDriverState *chr)
3654{
3655 if (chr->chr_close)
3656 chr->chr_close(chr);
balroga11d0702008-01-19 13:00:43 +00003657 qemu_free(chr);
bellardf3311102006-04-12 20:21:17 +00003658}
3659
bellardf1510b22003-06-25 00:07:40 +00003660/***********************************************************/
bellard7c9d8e02005-11-15 22:16:05 +00003661/* network device redirectors */
bellardf1510b22003-06-25 00:07:40 +00003662
j_mayer3f4afa12007-11-19 01:05:22 +00003663__attribute__ (( unused ))
pbrook9596ebb2007-11-18 01:44:38 +00003664static void hex_dump(FILE *f, const uint8_t *buf, int size)
bellard67b915a2004-03-31 23:37:16 +00003665{
bellardc20709a2004-04-21 23:27:19 +00003666 int len, i, j, c;
3667
3668 for(i=0;i<size;i+=16) {
3669 len = size - i;
3670 if (len > 16)
3671 len = 16;
3672 fprintf(f, "%08x ", i);
3673 for(j=0;j<16;j++) {
3674 if (j < len)
3675 fprintf(f, " %02x", buf[i+j]);
3676 else
3677 fprintf(f, " ");
3678 }
3679 fprintf(f, " ");
3680 for(j=0;j<len;j++) {
3681 c = buf[i+j];
3682 if (c < ' ' || c > '~')
3683 c = '.';
3684 fprintf(f, "%c", c);
3685 }
3686 fprintf(f, "\n");
3687 }
3688}
3689
bellard7c9d8e02005-11-15 22:16:05 +00003690static int parse_macaddr(uint8_t *macaddr, const char *p)
bellardc20709a2004-04-21 23:27:19 +00003691{
bellard7c9d8e02005-11-15 22:16:05 +00003692 int i;
balrog76ea08f2007-12-16 11:48:54 +00003693 char *last_char;
3694 long int offset;
3695
3696 errno = 0;
3697 offset = strtol(p, &last_char, 0);
3698 if (0 == errno && '\0' == *last_char &&
3699 offset >= 0 && offset <= 0xFFFFFF) {
3700 macaddr[3] = (offset & 0xFF0000) >> 16;
3701 macaddr[4] = (offset & 0xFF00) >> 8;
3702 macaddr[5] = offset & 0xFF;
3703 return 0;
3704 } else {
3705 for(i = 0; i < 6; i++) {
3706 macaddr[i] = strtol(p, (char **)&p, 16);
3707 if (i == 5) {
3708 if (*p != '\0')
3709 return -1;
3710 } else {
3711 if (*p != ':' && *p != '-')
3712 return -1;
3713 p++;
3714 }
bellard7c9d8e02005-11-15 22:16:05 +00003715 }
balrog76ea08f2007-12-16 11:48:54 +00003716 return 0;
bellardc20709a2004-04-21 23:27:19 +00003717 }
balrog76ea08f2007-12-16 11:48:54 +00003718
3719 return -1;
bellardc20709a2004-04-21 23:27:19 +00003720}
3721
bellard9bf05442004-08-25 22:12:49 +00003722static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3723{
3724 const char *p, *p1;
3725 int len;
3726 p = *pp;
3727 p1 = strchr(p, sep);
3728 if (!p1)
3729 return -1;
3730 len = p1 - p;
3731 p1++;
3732 if (buf_size > 0) {
3733 if (len > buf_size - 1)
3734 len = buf_size - 1;
3735 memcpy(buf, p, len);
3736 buf[len] = '\0';
3737 }
3738 *pp = p1;
3739 return 0;
3740}
3741
bellard951f1352006-06-27 21:02:43 +00003742int parse_host_src_port(struct sockaddr_in *haddr,
3743 struct sockaddr_in *saddr,
3744 const char *input_str)
3745{
3746 char *str = strdup(input_str);
3747 char *host_str = str;
3748 char *src_str;
3749 char *ptr;
3750
3751 /*
3752 * Chop off any extra arguments at the end of the string which
3753 * would start with a comma, then fill in the src port information
3754 * if it was provided else use the "any address" and "any port".
3755 */
3756 if ((ptr = strchr(str,',')))
3757 *ptr = '\0';
3758
3759 if ((src_str = strchr(input_str,'@'))) {
3760 *src_str = '\0';
3761 src_str++;
3762 }
3763
3764 if (parse_host_port(haddr, host_str) < 0)
3765 goto fail;
3766
3767 if (!src_str || *src_str == '\0')
3768 src_str = ":0";
3769
3770 if (parse_host_port(saddr, src_str) < 0)
3771 goto fail;
3772
3773 free(str);
3774 return(0);
3775
3776fail:
3777 free(str);
3778 return -1;
3779}
3780
bellard7c9d8e02005-11-15 22:16:05 +00003781int parse_host_port(struct sockaddr_in *saddr, const char *str)
3782{
3783 char buf[512];
3784 struct hostent *he;
3785 const char *p, *r;
3786 int port;
3787
3788 p = str;
3789 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3790 return -1;
3791 saddr->sin_family = AF_INET;
3792 if (buf[0] == '\0') {
3793 saddr->sin_addr.s_addr = 0;
3794 } else {
3795 if (isdigit(buf[0])) {
3796 if (!inet_aton(buf, &saddr->sin_addr))
3797 return -1;
3798 } else {
bellard7c9d8e02005-11-15 22:16:05 +00003799 if ((he = gethostbyname(buf)) == NULL)
3800 return - 1;
3801 saddr->sin_addr = *(struct in_addr *)he->h_addr;
bellard7c9d8e02005-11-15 22:16:05 +00003802 }
3803 }
3804 port = strtol(p, (char **)&r, 0);
3805 if (r == p)
3806 return -1;
3807 saddr->sin_port = htons(port);
3808 return 0;
3809}
3810
ths52f61fd2006-12-22 21:20:52 +00003811#ifndef _WIN32
3812static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
thsffd843b2006-12-21 19:46:43 +00003813{
3814 const char *p;
3815 int len;
3816
3817 len = MIN(108, strlen(str));
3818 p = strchr(str, ',');
3819 if (p)
3820 len = MIN(len, p - str);
3821
3822 memset(uaddr, 0, sizeof(*uaddr));
3823
3824 uaddr->sun_family = AF_UNIX;
3825 memcpy(uaddr->sun_path, str, len);
3826
3827 return 0;
3828}
ths52f61fd2006-12-22 21:20:52 +00003829#endif
thsffd843b2006-12-21 19:46:43 +00003830
bellard7c9d8e02005-11-15 22:16:05 +00003831/* find or alloc a new VLAN */
3832VLANState *qemu_find_vlan(int id)
3833{
3834 VLANState **pvlan, *vlan;
3835 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3836 if (vlan->id == id)
3837 return vlan;
3838 }
3839 vlan = qemu_mallocz(sizeof(VLANState));
3840 if (!vlan)
3841 return NULL;
3842 vlan->id = id;
3843 vlan->next = NULL;
3844 pvlan = &first_vlan;
3845 while (*pvlan != NULL)
3846 pvlan = &(*pvlan)->next;
3847 *pvlan = vlan;
3848 return vlan;
3849}
3850
3851VLANClientState *qemu_new_vlan_client(VLANState *vlan,
pbrookd861b052006-02-04 22:15:28 +00003852 IOReadHandler *fd_read,
3853 IOCanRWHandler *fd_can_read,
3854 void *opaque)
bellard7c9d8e02005-11-15 22:16:05 +00003855{
3856 VLANClientState *vc, **pvc;
3857 vc = qemu_mallocz(sizeof(VLANClientState));
3858 if (!vc)
3859 return NULL;
3860 vc->fd_read = fd_read;
pbrookd861b052006-02-04 22:15:28 +00003861 vc->fd_can_read = fd_can_read;
bellard7c9d8e02005-11-15 22:16:05 +00003862 vc->opaque = opaque;
3863 vc->vlan = vlan;
3864
3865 vc->next = NULL;
3866 pvc = &vlan->first_client;
3867 while (*pvc != NULL)
3868 pvc = &(*pvc)->next;
3869 *pvc = vc;
3870 return vc;
3871}
3872
pbrookd861b052006-02-04 22:15:28 +00003873int qemu_can_send_packet(VLANClientState *vc1)
3874{
3875 VLANState *vlan = vc1->vlan;
3876 VLANClientState *vc;
3877
3878 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3879 if (vc != vc1) {
balrogfbd17112007-07-02 13:31:53 +00003880 if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
3881 return 1;
pbrookd861b052006-02-04 22:15:28 +00003882 }
3883 }
balrogfbd17112007-07-02 13:31:53 +00003884 return 0;
pbrookd861b052006-02-04 22:15:28 +00003885}
3886
bellard7c9d8e02005-11-15 22:16:05 +00003887void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
3888{
3889 VLANState *vlan = vc1->vlan;
3890 VLANClientState *vc;
3891
3892#if 0
3893 printf("vlan %d send:\n", vlan->id);
3894 hex_dump(stdout, buf, size);
3895#endif
3896 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3897 if (vc != vc1) {
3898 vc->fd_read(vc->opaque, buf, size);
3899 }
3900 }
3901}
3902
3903#if defined(CONFIG_SLIRP)
3904
3905/* slirp network adapter */
3906
3907static int slirp_inited;
3908static VLANClientState *slirp_vc;
3909
3910int slirp_can_output(void)
3911{
pbrook3b7f5d42006-02-10 17:34:02 +00003912 return !slirp_vc || qemu_can_send_packet(slirp_vc);
bellard7c9d8e02005-11-15 22:16:05 +00003913}
3914
3915void slirp_output(const uint8_t *pkt, int pkt_len)
3916{
3917#if 0
3918 printf("slirp output:\n");
3919 hex_dump(stdout, pkt, pkt_len);
3920#endif
pbrook3b7f5d42006-02-10 17:34:02 +00003921 if (!slirp_vc)
3922 return;
bellard7c9d8e02005-11-15 22:16:05 +00003923 qemu_send_packet(slirp_vc, pkt, pkt_len);
3924}
3925
3926static void slirp_receive(void *opaque, const uint8_t *buf, int size)
3927{
3928#if 0
3929 printf("slirp input:\n");
3930 hex_dump(stdout, buf, size);
3931#endif
3932 slirp_input(buf, size);
3933}
3934
3935static int net_slirp_init(VLANState *vlan)
3936{
3937 if (!slirp_inited) {
3938 slirp_inited = 1;
3939 slirp_init();
3940 }
ths5fafdf22007-09-16 21:08:06 +00003941 slirp_vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00003942 slirp_receive, NULL, NULL);
bellard7c9d8e02005-11-15 22:16:05 +00003943 snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
3944 return 0;
3945}
3946
bellard9bf05442004-08-25 22:12:49 +00003947static void net_slirp_redir(const char *redir_str)
3948{
3949 int is_udp;
3950 char buf[256], *r;
3951 const char *p;
3952 struct in_addr guest_addr;
3953 int host_port, guest_port;
ths3b46e622007-09-17 08:09:54 +00003954
bellard9bf05442004-08-25 22:12:49 +00003955 if (!slirp_inited) {
3956 slirp_inited = 1;
3957 slirp_init();
3958 }
3959
3960 p = redir_str;
3961 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3962 goto fail;
3963 if (!strcmp(buf, "tcp")) {
3964 is_udp = 0;
3965 } else if (!strcmp(buf, "udp")) {
3966 is_udp = 1;
3967 } else {
3968 goto fail;
3969 }
3970
3971 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3972 goto fail;
3973 host_port = strtol(buf, &r, 0);
3974 if (r == buf)
3975 goto fail;
3976
3977 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3978 goto fail;
3979 if (buf[0] == '\0') {
3980 pstrcpy(buf, sizeof(buf), "10.0.2.15");
3981 }
3982 if (!inet_aton(buf, &guest_addr))
3983 goto fail;
ths3b46e622007-09-17 08:09:54 +00003984
bellard9bf05442004-08-25 22:12:49 +00003985 guest_port = strtol(p, &r, 0);
3986 if (r == p)
3987 goto fail;
ths3b46e622007-09-17 08:09:54 +00003988
bellard9bf05442004-08-25 22:12:49 +00003989 if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
3990 fprintf(stderr, "qemu: could not set up redirection\n");
3991 exit(1);
3992 }
3993 return;
3994 fail:
3995 fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
3996 exit(1);
3997}
ths3b46e622007-09-17 08:09:54 +00003998
bellardc94c8d62004-09-13 21:37:34 +00003999#ifndef _WIN32
4000
bellard9d728e82004-09-05 23:09:03 +00004001char smb_dir[1024];
4002
balrog044fae82008-01-14 03:11:16 +00004003static void erase_dir(char *dir_name)
bellard9d728e82004-09-05 23:09:03 +00004004{
4005 DIR *d;
4006 struct dirent *de;
4007 char filename[1024];
4008
4009 /* erase all the files in the directory */
balrog044fae82008-01-14 03:11:16 +00004010 if ((d = opendir(dir_name)) != 0) {
4011 for(;;) {
4012 de = readdir(d);
4013 if (!de)
4014 break;
4015 if (strcmp(de->d_name, ".") != 0 &&
4016 strcmp(de->d_name, "..") != 0) {
4017 snprintf(filename, sizeof(filename), "%s/%s",
4018 smb_dir, de->d_name);
4019 if (unlink(filename) != 0) /* is it a directory? */
4020 erase_dir(filename);
4021 }
bellard9d728e82004-09-05 23:09:03 +00004022 }
balrog044fae82008-01-14 03:11:16 +00004023 closedir(d);
4024 rmdir(dir_name);
bellard9d728e82004-09-05 23:09:03 +00004025 }
balrog044fae82008-01-14 03:11:16 +00004026}
4027
4028/* automatic user mode samba server configuration */
4029static void smb_exit(void)
4030{
4031 erase_dir(smb_dir);
bellard9d728e82004-09-05 23:09:03 +00004032}
4033
4034/* automatic user mode samba server configuration */
pbrook9596ebb2007-11-18 01:44:38 +00004035static void net_slirp_smb(const char *exported_dir)
bellard9d728e82004-09-05 23:09:03 +00004036{
4037 char smb_conf[1024];
4038 char smb_cmdline[1024];
4039 FILE *f;
4040
4041 if (!slirp_inited) {
4042 slirp_inited = 1;
4043 slirp_init();
4044 }
4045
4046 /* XXX: better tmp dir construction */
4047 snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
4048 if (mkdir(smb_dir, 0700) < 0) {
4049 fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
4050 exit(1);
4051 }
4052 snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
ths3b46e622007-09-17 08:09:54 +00004053
bellard9d728e82004-09-05 23:09:03 +00004054 f = fopen(smb_conf, "w");
4055 if (!f) {
4056 fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
4057 exit(1);
4058 }
ths5fafdf22007-09-16 21:08:06 +00004059 fprintf(f,
bellard9d728e82004-09-05 23:09:03 +00004060 "[global]\n"
bellard157777e2005-03-01 21:28:45 +00004061 "private dir=%s\n"
4062 "smb ports=0\n"
4063 "socket address=127.0.0.1\n"
bellard9d728e82004-09-05 23:09:03 +00004064 "pid directory=%s\n"
4065 "lock directory=%s\n"
4066 "log file=%s/log.smbd\n"
4067 "smb passwd file=%s/smbpasswd\n"
bellard03ffbb62004-09-06 00:14:04 +00004068 "security = share\n"
bellard9d728e82004-09-05 23:09:03 +00004069 "[qemu]\n"
4070 "path=%s\n"
4071 "read only=no\n"
4072 "guest ok=yes\n",
4073 smb_dir,
4074 smb_dir,
4075 smb_dir,
4076 smb_dir,
bellard157777e2005-03-01 21:28:45 +00004077 smb_dir,
bellard9d728e82004-09-05 23:09:03 +00004078 exported_dir
4079 );
4080 fclose(f);
4081 atexit(smb_exit);
4082
pbrooka14d6c82006-12-23 15:37:33 +00004083 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
4084 SMBD_COMMAND, smb_conf);
ths3b46e622007-09-17 08:09:54 +00004085
bellard9d728e82004-09-05 23:09:03 +00004086 slirp_add_exec(0, smb_cmdline, 4, 139);
4087}
bellard9bf05442004-08-25 22:12:49 +00004088
bellardc94c8d62004-09-13 21:37:34 +00004089#endif /* !defined(_WIN32) */
blueswir131a60e22007-10-26 18:42:59 +00004090void do_info_slirp(void)
4091{
4092 slirp_stats();
4093}
bellardc94c8d62004-09-13 21:37:34 +00004094
bellardc20709a2004-04-21 23:27:19 +00004095#endif /* CONFIG_SLIRP */
4096
4097#if !defined(_WIN32)
bellard7c9d8e02005-11-15 22:16:05 +00004098
4099typedef struct TAPState {
4100 VLANClientState *vc;
4101 int fd;
thsb46a8902007-10-21 23:20:45 +00004102 char down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00004103} TAPState;
4104
4105static void tap_receive(void *opaque, const uint8_t *buf, int size)
4106{
4107 TAPState *s = opaque;
4108 int ret;
4109 for(;;) {
4110 ret = write(s->fd, buf, size);
4111 if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
4112 } else {
4113 break;
4114 }
4115 }
4116}
4117
4118static void tap_send(void *opaque)
4119{
4120 TAPState *s = opaque;
4121 uint8_t buf[4096];
4122 int size;
4123
thsd5d10bc2007-02-17 22:54:49 +00004124#ifdef __sun__
4125 struct strbuf sbuf;
4126 int f = 0;
4127 sbuf.maxlen = sizeof(buf);
4128 sbuf.buf = buf;
4129 size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
4130#else
bellard7c9d8e02005-11-15 22:16:05 +00004131 size = read(s->fd, buf, sizeof(buf));
thsd5d10bc2007-02-17 22:54:49 +00004132#endif
bellard7c9d8e02005-11-15 22:16:05 +00004133 if (size > 0) {
4134 qemu_send_packet(s->vc, buf, size);
4135 }
4136}
4137
4138/* fd support */
4139
4140static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
4141{
4142 TAPState *s;
4143
4144 s = qemu_mallocz(sizeof(TAPState));
4145 if (!s)
4146 return NULL;
4147 s->fd = fd;
pbrookd861b052006-02-04 22:15:28 +00004148 s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004149 qemu_set_fd_handler(s->fd, tap_send, NULL, s);
4150 snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
4151 return s;
4152}
4153
ths5c40d2b2007-06-23 16:03:36 +00004154#if defined (_BSD) || defined (__FreeBSD_kernel__)
bellard7c9d8e02005-11-15 22:16:05 +00004155static int tap_open(char *ifname, int ifname_size)
bellard7d3505c2004-05-12 19:32:15 +00004156{
4157 int fd;
4158 char *dev;
4159 struct stat s;
bellard67b915a2004-03-31 23:37:16 +00004160
balrogaeb30be2007-07-02 15:03:13 +00004161 TFR(fd = open("/dev/tap", O_RDWR));
bellard7d3505c2004-05-12 19:32:15 +00004162 if (fd < 0) {
4163 fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
4164 return -1;
4165 }
4166
4167 fstat(fd, &s);
4168 dev = devname(s.st_rdev, S_IFCHR);
4169 pstrcpy(ifname, ifname_size, dev);
4170
4171 fcntl(fd, F_SETFL, O_NONBLOCK);
4172 return fd;
4173}
bellardec530c82006-04-25 22:36:06 +00004174#elif defined(__sun__)
thsd5d10bc2007-02-17 22:54:49 +00004175#define TUNNEWPPA (('T'<<16) | 0x0001)
ths5fafdf22007-09-16 21:08:06 +00004176/*
4177 * Allocate TAP device, returns opened fd.
thsd5d10bc2007-02-17 22:54:49 +00004178 * Stores dev name in the first arg(must be large enough).
ths3b46e622007-09-17 08:09:54 +00004179 */
thsd5d10bc2007-02-17 22:54:49 +00004180int tap_alloc(char *dev)
4181{
4182 int tap_fd, if_fd, ppa = -1;
4183 static int ip_fd = 0;
4184 char *ptr;
4185
4186 static int arp_fd = 0;
4187 int ip_muxid, arp_muxid;
4188 struct strioctl strioc_if, strioc_ppa;
4189 int link_type = I_PLINK;;
4190 struct lifreq ifr;
4191 char actual_name[32] = "";
4192
4193 memset(&ifr, 0x0, sizeof(ifr));
4194
4195 if( *dev ){
ths5fafdf22007-09-16 21:08:06 +00004196 ptr = dev;
4197 while( *ptr && !isdigit((int)*ptr) ) ptr++;
thsd5d10bc2007-02-17 22:54:49 +00004198 ppa = atoi(ptr);
4199 }
4200
4201 /* Check if IP device was opened */
4202 if( ip_fd )
4203 close(ip_fd);
4204
balrogaeb30be2007-07-02 15:03:13 +00004205 TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
4206 if (ip_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004207 syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
4208 return -1;
4209 }
4210
balrogaeb30be2007-07-02 15:03:13 +00004211 TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
4212 if (tap_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004213 syslog(LOG_ERR, "Can't open /dev/tap");
4214 return -1;
4215 }
4216
4217 /* Assign a new PPA and get its unit number. */
4218 strioc_ppa.ic_cmd = TUNNEWPPA;
4219 strioc_ppa.ic_timout = 0;
4220 strioc_ppa.ic_len = sizeof(ppa);
4221 strioc_ppa.ic_dp = (char *)&ppa;
4222 if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
4223 syslog (LOG_ERR, "Can't assign new interface");
4224
balrogaeb30be2007-07-02 15:03:13 +00004225 TFR(if_fd = open("/dev/tap", O_RDWR, 0));
4226 if (if_fd < 0) {
thsd5d10bc2007-02-17 22:54:49 +00004227 syslog(LOG_ERR, "Can't open /dev/tap (2)");
4228 return -1;
4229 }
4230 if(ioctl(if_fd, I_PUSH, "ip") < 0){
4231 syslog(LOG_ERR, "Can't push IP module");
4232 return -1;
4233 }
4234
4235 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
4236 syslog(LOG_ERR, "Can't get flags\n");
4237
4238 snprintf (actual_name, 32, "tap%d", ppa);
4239 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4240
4241 ifr.lifr_ppa = ppa;
4242 /* Assign ppa according to the unit number returned by tun device */
4243
4244 if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
4245 syslog (LOG_ERR, "Can't set PPA %d", ppa);
4246 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
4247 syslog (LOG_ERR, "Can't get flags\n");
4248 /* Push arp module to if_fd */
4249 if (ioctl (if_fd, I_PUSH, "arp") < 0)
4250 syslog (LOG_ERR, "Can't push ARP module (2)");
4251
4252 /* Push arp module to ip_fd */
4253 if (ioctl (ip_fd, I_POP, NULL) < 0)
4254 syslog (LOG_ERR, "I_POP failed\n");
4255 if (ioctl (ip_fd, I_PUSH, "arp") < 0)
4256 syslog (LOG_ERR, "Can't push ARP module (3)\n");
4257 /* Open arp_fd */
balrogaeb30be2007-07-02 15:03:13 +00004258 TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
4259 if (arp_fd < 0)
thsd5d10bc2007-02-17 22:54:49 +00004260 syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
4261
4262 /* Set ifname to arp */
4263 strioc_if.ic_cmd = SIOCSLIFNAME;
4264 strioc_if.ic_timout = 0;
4265 strioc_if.ic_len = sizeof(ifr);
4266 strioc_if.ic_dp = (char *)&ifr;
4267 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
4268 syslog (LOG_ERR, "Can't set ifname to arp\n");
4269 }
4270
4271 if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
4272 syslog(LOG_ERR, "Can't link TAP device to IP");
4273 return -1;
4274 }
4275
4276 if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
4277 syslog (LOG_ERR, "Can't link TAP device to ARP");
4278
4279 close (if_fd);
4280
4281 memset(&ifr, 0x0, sizeof(ifr));
4282 strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4283 ifr.lifr_ip_muxid = ip_muxid;
4284 ifr.lifr_arp_muxid = arp_muxid;
4285
4286 if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
4287 {
4288 ioctl (ip_fd, I_PUNLINK , arp_muxid);
4289 ioctl (ip_fd, I_PUNLINK, ip_muxid);
4290 syslog (LOG_ERR, "Can't set multiplexor id");
4291 }
4292
4293 sprintf(dev, "tap%d", ppa);
4294 return tap_fd;
4295}
4296
bellardec530c82006-04-25 22:36:06 +00004297static int tap_open(char *ifname, int ifname_size)
4298{
thsd5d10bc2007-02-17 22:54:49 +00004299 char dev[10]="";
4300 int fd;
4301 if( (fd = tap_alloc(dev)) < 0 ){
4302 fprintf(stderr, "Cannot allocate TAP device\n");
4303 return -1;
4304 }
4305 pstrcpy(ifname, ifname_size, dev);
4306 fcntl(fd, F_SETFL, O_NONBLOCK);
4307 return fd;
bellardec530c82006-04-25 22:36:06 +00004308}
bellard7d3505c2004-05-12 19:32:15 +00004309#else
bellard7c9d8e02005-11-15 22:16:05 +00004310static int tap_open(char *ifname, int ifname_size)
bellardf1510b22003-06-25 00:07:40 +00004311{
4312 struct ifreq ifr;
bellardc4b1fcc2004-03-14 21:44:30 +00004313 int fd, ret;
ths3b46e622007-09-17 08:09:54 +00004314
balrogaeb30be2007-07-02 15:03:13 +00004315 TFR(fd = open("/dev/net/tun", O_RDWR));
bellardf1510b22003-06-25 00:07:40 +00004316 if (fd < 0) {
4317 fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4318 return -1;
4319 }
4320 memset(&ifr, 0, sizeof(ifr));
4321 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
bellard7c9d8e02005-11-15 22:16:05 +00004322 if (ifname[0] != '\0')
4323 pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4324 else
4325 pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
bellardf1510b22003-06-25 00:07:40 +00004326 ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4327 if (ret != 0) {
4328 fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4329 close(fd);
4330 return -1;
4331 }
bellardc4b1fcc2004-03-14 21:44:30 +00004332 pstrcpy(ifname, ifname_size, ifr.ifr_name);
bellardf1510b22003-06-25 00:07:40 +00004333 fcntl(fd, F_SETFL, O_NONBLOCK);
bellardc4b1fcc2004-03-14 21:44:30 +00004334 return fd;
4335}
bellard7d3505c2004-05-12 19:32:15 +00004336#endif
bellardf1510b22003-06-25 00:07:40 +00004337
thsb46a8902007-10-21 23:20:45 +00004338static int launch_script(const char *setup_script, const char *ifname, int fd)
bellardc4b1fcc2004-03-14 21:44:30 +00004339{
thsb46a8902007-10-21 23:20:45 +00004340 int pid, status;
bellardc20709a2004-04-21 23:27:19 +00004341 char *args[3];
4342 char **parg;
4343
thsb46a8902007-10-21 23:20:45 +00004344 /* try to launch network script */
bellard7c9d8e02005-11-15 22:16:05 +00004345 pid = fork();
4346 if (pid >= 0) {
4347 if (pid == 0) {
ths50d3eea2007-03-19 16:36:43 +00004348 int open_max = sysconf (_SC_OPEN_MAX), i;
4349 for (i = 0; i < open_max; i++)
4350 if (i != STDIN_FILENO &&
4351 i != STDOUT_FILENO &&
4352 i != STDERR_FILENO &&
4353 i != fd)
4354 close(i);
4355
bellard7c9d8e02005-11-15 22:16:05 +00004356 parg = args;
4357 *parg++ = (char *)setup_script;
thsb46a8902007-10-21 23:20:45 +00004358 *parg++ = (char *)ifname;
bellard7c9d8e02005-11-15 22:16:05 +00004359 *parg++ = NULL;
4360 execv(setup_script, args);
bellard4a389402005-11-26 20:10:07 +00004361 _exit(1);
bellard7c9d8e02005-11-15 22:16:05 +00004362 }
4363 while (waitpid(pid, &status, 0) != pid);
4364 if (!WIFEXITED(status) ||
4365 WEXITSTATUS(status) != 0) {
4366 fprintf(stderr, "%s: could not launch network script\n",
4367 setup_script);
4368 return -1;
4369 }
bellardc20709a2004-04-21 23:27:19 +00004370 }
thsb46a8902007-10-21 23:20:45 +00004371 return 0;
4372}
4373
4374static int net_tap_init(VLANState *vlan, const char *ifname1,
4375 const char *setup_script, const char *down_script)
4376{
4377 TAPState *s;
4378 int fd;
4379 char ifname[128];
4380
4381 if (ifname1 != NULL)
4382 pstrcpy(ifname, sizeof(ifname), ifname1);
4383 else
4384 ifname[0] = '\0';
4385 TFR(fd = tap_open(ifname, sizeof(ifname)));
4386 if (fd < 0)
4387 return -1;
4388
4389 if (!setup_script || !strcmp(setup_script, "no"))
4390 setup_script = "";
4391 if (setup_script[0] != '\0') {
4392 if (launch_script(setup_script, ifname, fd))
4393 return -1;
bellardc20709a2004-04-21 23:27:19 +00004394 }
bellard7c9d8e02005-11-15 22:16:05 +00004395 s = net_tap_fd_init(vlan, fd);
4396 if (!s)
4397 return -1;
ths5fafdf22007-09-16 21:08:06 +00004398 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
bellard7c9d8e02005-11-15 22:16:05 +00004399 "tap: ifname=%s setup_script=%s", ifname, setup_script);
thsb46a8902007-10-21 23:20:45 +00004400 if (down_script && strcmp(down_script, "no"))
4401 snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
bellardc20709a2004-04-21 23:27:19 +00004402 return 0;
4403}
4404
bellardfd1dff42006-02-01 21:29:26 +00004405#endif /* !_WIN32 */
4406
bellard7c9d8e02005-11-15 22:16:05 +00004407/* network connection */
4408typedef struct NetSocketState {
4409 VLANClientState *vc;
4410 int fd;
4411 int state; /* 0 = getting length, 1 = getting data */
4412 int index;
4413 int packet_len;
4414 uint8_t buf[4096];
bellard3d830452005-12-18 16:36:49 +00004415 struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
bellard7c9d8e02005-11-15 22:16:05 +00004416} NetSocketState;
4417
4418typedef struct NetSocketListenState {
4419 VLANState *vlan;
4420 int fd;
4421} NetSocketListenState;
4422
4423/* XXX: we consider we can send the whole packet without blocking */
4424static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
bellardc20709a2004-04-21 23:27:19 +00004425{
bellard7c9d8e02005-11-15 22:16:05 +00004426 NetSocketState *s = opaque;
4427 uint32_t len;
4428 len = htonl(size);
4429
bellardfd1dff42006-02-01 21:29:26 +00004430 send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4431 send_all(s->fd, buf, size);
bellard7c9d8e02005-11-15 22:16:05 +00004432}
4433
bellard3d830452005-12-18 16:36:49 +00004434static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4435{
4436 NetSocketState *s = opaque;
ths5fafdf22007-09-16 21:08:06 +00004437 sendto(s->fd, buf, size, 0,
bellard3d830452005-12-18 16:36:49 +00004438 (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4439}
4440
bellard7c9d8e02005-11-15 22:16:05 +00004441static void net_socket_send(void *opaque)
4442{
4443 NetSocketState *s = opaque;
bellardfd1dff42006-02-01 21:29:26 +00004444 int l, size, err;
bellard7c9d8e02005-11-15 22:16:05 +00004445 uint8_t buf1[4096];
4446 const uint8_t *buf;
4447
bellardfd1dff42006-02-01 21:29:26 +00004448 size = recv(s->fd, buf1, sizeof(buf1), 0);
4449 if (size < 0) {
4450 err = socket_error();
ths5fafdf22007-09-16 21:08:06 +00004451 if (err != EWOULDBLOCK)
bellardfd1dff42006-02-01 21:29:26 +00004452 goto eoc;
4453 } else if (size == 0) {
bellard7c9d8e02005-11-15 22:16:05 +00004454 /* end of connection */
bellardfd1dff42006-02-01 21:29:26 +00004455 eoc:
bellard7c9d8e02005-11-15 22:16:05 +00004456 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
bellardfd1dff42006-02-01 21:29:26 +00004457 closesocket(s->fd);
bellard7c9d8e02005-11-15 22:16:05 +00004458 return;
4459 }
4460 buf = buf1;
4461 while (size > 0) {
4462 /* reassemble a packet from the network */
4463 switch(s->state) {
4464 case 0:
4465 l = 4 - s->index;
4466 if (l > size)
4467 l = size;
4468 memcpy(s->buf + s->index, buf, l);
4469 buf += l;
4470 size -= l;
4471 s->index += l;
4472 if (s->index == 4) {
4473 /* got length */
4474 s->packet_len = ntohl(*(uint32_t *)s->buf);
4475 s->index = 0;
4476 s->state = 1;
4477 }
4478 break;
4479 case 1:
4480 l = s->packet_len - s->index;
4481 if (l > size)
4482 l = size;
4483 memcpy(s->buf + s->index, buf, l);
4484 s->index += l;
4485 buf += l;
4486 size -= l;
4487 if (s->index >= s->packet_len) {
4488 qemu_send_packet(s->vc, s->buf, s->packet_len);
4489 s->index = 0;
4490 s->state = 0;
4491 }
4492 break;
4493 }
4494 }
4495}
4496
bellard3d830452005-12-18 16:36:49 +00004497static void net_socket_send_dgram(void *opaque)
4498{
4499 NetSocketState *s = opaque;
4500 int size;
4501
4502 size = recv(s->fd, s->buf, sizeof(s->buf), 0);
ths5fafdf22007-09-16 21:08:06 +00004503 if (size < 0)
bellard3d830452005-12-18 16:36:49 +00004504 return;
4505 if (size == 0) {
4506 /* end of connection */
4507 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4508 return;
4509 }
4510 qemu_send_packet(s->vc, s->buf, size);
4511}
4512
4513static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4514{
4515 struct ip_mreq imr;
4516 int fd;
4517 int val, ret;
4518 if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4519 fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
ths5fafdf22007-09-16 21:08:06 +00004520 inet_ntoa(mcastaddr->sin_addr),
bellardfd1dff42006-02-01 21:29:26 +00004521 (int)ntohl(mcastaddr->sin_addr.s_addr));
bellard3d830452005-12-18 16:36:49 +00004522 return -1;
4523
4524 }
4525 fd = socket(PF_INET, SOCK_DGRAM, 0);
4526 if (fd < 0) {
4527 perror("socket(PF_INET, SOCK_DGRAM)");
4528 return -1;
4529 }
4530
bellardfd1dff42006-02-01 21:29:26 +00004531 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004532 ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
bellardfd1dff42006-02-01 21:29:26 +00004533 (const char *)&val, sizeof(val));
4534 if (ret < 0) {
4535 perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4536 goto fail;
4537 }
4538
4539 ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4540 if (ret < 0) {
4541 perror("bind");
4542 goto fail;
4543 }
ths3b46e622007-09-17 08:09:54 +00004544
bellard3d830452005-12-18 16:36:49 +00004545 /* Add host to multicast group */
4546 imr.imr_multiaddr = mcastaddr->sin_addr;
4547 imr.imr_interface.s_addr = htonl(INADDR_ANY);
4548
ths5fafdf22007-09-16 21:08:06 +00004549 ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
bellardfd1dff42006-02-01 21:29:26 +00004550 (const char *)&imr, sizeof(struct ip_mreq));
bellard3d830452005-12-18 16:36:49 +00004551 if (ret < 0) {
4552 perror("setsockopt(IP_ADD_MEMBERSHIP)");
4553 goto fail;
4554 }
4555
4556 /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4557 val = 1;
ths5fafdf22007-09-16 21:08:06 +00004558 ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
bellardfd1dff42006-02-01 21:29:26 +00004559 (const char *)&val, sizeof(val));
bellard3d830452005-12-18 16:36:49 +00004560 if (ret < 0) {
4561 perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4562 goto fail;
4563 }
4564
bellardfd1dff42006-02-01 21:29:26 +00004565 socket_set_nonblock(fd);
bellard3d830452005-12-18 16:36:49 +00004566 return fd;
4567fail:
ths5fafdf22007-09-16 21:08:06 +00004568 if (fd >= 0)
bellard0bab00f2006-06-25 14:49:44 +00004569 closesocket(fd);
bellard3d830452005-12-18 16:36:49 +00004570 return -1;
4571}
4572
ths5fafdf22007-09-16 21:08:06 +00004573static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004574 int is_connected)
4575{
4576 struct sockaddr_in saddr;
4577 int newfd;
4578 socklen_t saddr_len;
4579 NetSocketState *s;
4580
4581 /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
ths5fafdf22007-09-16 21:08:06 +00004582 * Because this may be "shared" socket from a "master" process, datagrams would be recv()
bellard3d830452005-12-18 16:36:49 +00004583 * by ONLY ONE process: we must "clone" this dgram socket --jjo
4584 */
4585
4586 if (is_connected) {
4587 if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4588 /* must be bound */
4589 if (saddr.sin_addr.s_addr==0) {
4590 fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4591 fd);
4592 return NULL;
4593 }
4594 /* clone dgram socket */
4595 newfd = net_socket_mcast_create(&saddr);
4596 if (newfd < 0) {
4597 /* error already reported by net_socket_mcast_create() */
4598 close(fd);
4599 return NULL;
4600 }
4601 /* clone newfd to fd, close newfd */
4602 dup2(newfd, fd);
4603 close(newfd);
ths5fafdf22007-09-16 21:08:06 +00004604
bellard3d830452005-12-18 16:36:49 +00004605 } else {
4606 fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4607 fd, strerror(errno));
4608 return NULL;
4609 }
4610 }
4611
4612 s = qemu_mallocz(sizeof(NetSocketState));
4613 if (!s)
4614 return NULL;
4615 s->fd = fd;
4616
pbrookd861b052006-02-04 22:15:28 +00004617 s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
bellard3d830452005-12-18 16:36:49 +00004618 qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4619
4620 /* mcast: save bound address as dst */
4621 if (is_connected) s->dgram_dst=saddr;
4622
4623 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004624 "socket: fd=%d (%s mcast=%s:%d)",
bellard3d830452005-12-18 16:36:49 +00004625 fd, is_connected? "cloned" : "",
4626 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4627 return s;
4628}
4629
bellard7c9d8e02005-11-15 22:16:05 +00004630static void net_socket_connect(void *opaque)
4631{
4632 NetSocketState *s = opaque;
4633 qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4634}
4635
ths5fafdf22007-09-16 21:08:06 +00004636static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
bellard7c9d8e02005-11-15 22:16:05 +00004637 int is_connected)
4638{
4639 NetSocketState *s;
4640 s = qemu_mallocz(sizeof(NetSocketState));
4641 if (!s)
4642 return NULL;
4643 s->fd = fd;
ths5fafdf22007-09-16 21:08:06 +00004644 s->vc = qemu_new_vlan_client(vlan,
pbrookd861b052006-02-04 22:15:28 +00004645 net_socket_receive, NULL, s);
bellard7c9d8e02005-11-15 22:16:05 +00004646 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4647 "socket: fd=%d", fd);
4648 if (is_connected) {
4649 net_socket_connect(s);
4650 } else {
4651 qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4652 }
4653 return s;
4654}
4655
ths5fafdf22007-09-16 21:08:06 +00004656static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
bellard3d830452005-12-18 16:36:49 +00004657 int is_connected)
4658{
4659 int so_type=-1, optlen=sizeof(so_type);
4660
ths69b34972007-12-17 03:15:52 +00004661 if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
4662 (socklen_t *)&optlen)< 0) {
ths931f03e2007-04-28 20:49:36 +00004663 fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
bellard3d830452005-12-18 16:36:49 +00004664 return NULL;
4665 }
4666 switch(so_type) {
4667 case SOCK_DGRAM:
4668 return net_socket_fd_init_dgram(vlan, fd, is_connected);
4669 case SOCK_STREAM:
4670 return net_socket_fd_init_stream(vlan, fd, is_connected);
4671 default:
4672 /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4673 fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4674 return net_socket_fd_init_stream(vlan, fd, is_connected);
4675 }
4676 return NULL;
4677}
4678
bellard7c9d8e02005-11-15 22:16:05 +00004679static void net_socket_accept(void *opaque)
4680{
ths3b46e622007-09-17 08:09:54 +00004681 NetSocketListenState *s = opaque;
bellard7c9d8e02005-11-15 22:16:05 +00004682 NetSocketState *s1;
4683 struct sockaddr_in saddr;
4684 socklen_t len;
4685 int fd;
4686
4687 for(;;) {
4688 len = sizeof(saddr);
4689 fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4690 if (fd < 0 && errno != EINTR) {
4691 return;
4692 } else if (fd >= 0) {
4693 break;
4694 }
4695 }
ths5fafdf22007-09-16 21:08:06 +00004696 s1 = net_socket_fd_init(s->vlan, fd, 1);
bellard7c9d8e02005-11-15 22:16:05 +00004697 if (!s1) {
bellard0bab00f2006-06-25 14:49:44 +00004698 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004699 } else {
4700 snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004701 "socket: connection from %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00004702 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4703 }
4704}
4705
4706static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4707{
4708 NetSocketListenState *s;
4709 int fd, val, ret;
4710 struct sockaddr_in saddr;
4711
4712 if (parse_host_port(&saddr, host_str) < 0)
4713 return -1;
ths3b46e622007-09-17 08:09:54 +00004714
bellard7c9d8e02005-11-15 22:16:05 +00004715 s = qemu_mallocz(sizeof(NetSocketListenState));
4716 if (!s)
4717 return -1;
4718
4719 fd = socket(PF_INET, SOCK_STREAM, 0);
4720 if (fd < 0) {
4721 perror("socket");
4722 return -1;
4723 }
bellardfd1dff42006-02-01 21:29:26 +00004724 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004725
4726 /* allow fast reuse */
4727 val = 1;
bellardfd1dff42006-02-01 21:29:26 +00004728 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
ths3b46e622007-09-17 08:09:54 +00004729
bellard7c9d8e02005-11-15 22:16:05 +00004730 ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4731 if (ret < 0) {
4732 perror("bind");
4733 return -1;
4734 }
4735 ret = listen(fd, 0);
4736 if (ret < 0) {
4737 perror("listen");
4738 return -1;
4739 }
4740 s->vlan = vlan;
4741 s->fd = fd;
4742 qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
4743 return 0;
4744}
4745
4746static int net_socket_connect_init(VLANState *vlan, const char *host_str)
4747{
4748 NetSocketState *s;
bellardfd1dff42006-02-01 21:29:26 +00004749 int fd, connected, ret, err;
bellard7c9d8e02005-11-15 22:16:05 +00004750 struct sockaddr_in saddr;
4751
4752 if (parse_host_port(&saddr, host_str) < 0)
4753 return -1;
4754
4755 fd = socket(PF_INET, SOCK_STREAM, 0);
4756 if (fd < 0) {
4757 perror("socket");
4758 return -1;
4759 }
bellardfd1dff42006-02-01 21:29:26 +00004760 socket_set_nonblock(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004761
4762 connected = 0;
4763 for(;;) {
4764 ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4765 if (ret < 0) {
bellardfd1dff42006-02-01 21:29:26 +00004766 err = socket_error();
4767 if (err == EINTR || err == EWOULDBLOCK) {
4768 } else if (err == EINPROGRESS) {
bellard7c9d8e02005-11-15 22:16:05 +00004769 break;
thsf5b12262007-03-25 15:58:03 +00004770#ifdef _WIN32
4771 } else if (err == WSAEALREADY) {
4772 break;
4773#endif
bellard7c9d8e02005-11-15 22:16:05 +00004774 } else {
4775 perror("connect");
bellardfd1dff42006-02-01 21:29:26 +00004776 closesocket(fd);
bellard7c9d8e02005-11-15 22:16:05 +00004777 return -1;
4778 }
4779 } else {
4780 connected = 1;
4781 break;
4782 }
4783 }
4784 s = net_socket_fd_init(vlan, fd, connected);
4785 if (!s)
4786 return -1;
4787 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004788 "socket: connect to %s:%d",
bellard7c9d8e02005-11-15 22:16:05 +00004789 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
bellardc20709a2004-04-21 23:27:19 +00004790 return 0;
4791}
4792
bellard3d830452005-12-18 16:36:49 +00004793static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
4794{
4795 NetSocketState *s;
4796 int fd;
4797 struct sockaddr_in saddr;
4798
4799 if (parse_host_port(&saddr, host_str) < 0)
4800 return -1;
4801
4802
4803 fd = net_socket_mcast_create(&saddr);
4804 if (fd < 0)
4805 return -1;
4806
4807 s = net_socket_fd_init(vlan, fd, 0);
4808 if (!s)
4809 return -1;
4810
4811 s->dgram_dst = saddr;
ths3b46e622007-09-17 08:09:54 +00004812
bellard3d830452005-12-18 16:36:49 +00004813 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
ths5fafdf22007-09-16 21:08:06 +00004814 "socket: mcast=%s:%d",
bellard3d830452005-12-18 16:36:49 +00004815 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4816 return 0;
4817
4818}
4819
balrog609497a2008-01-14 02:56:53 +00004820static const char *get_opt_name(char *buf, int buf_size, const char *p)
thse4bcb142007-12-02 04:51:10 +00004821{
4822 char *q;
thse4bcb142007-12-02 04:51:10 +00004823
balrog609497a2008-01-14 02:56:53 +00004824 q = buf;
4825 while (*p != '\0' && *p != '=') {
4826 if (q && (q - buf) < buf_size - 1)
4827 *q++ = *p;
4828 p++;
4829 }
4830 if (q)
4831 *q = '\0';
4832
4833 return p;
4834}
4835
4836static const char *get_opt_value(char *buf, int buf_size, const char *p)
4837{
4838 char *q;
4839
thse4bcb142007-12-02 04:51:10 +00004840 q = buf;
4841 while (*p != '\0') {
balrog609497a2008-01-14 02:56:53 +00004842 if (*p == ',') {
4843 if (*(p + 1) != ',')
thse4bcb142007-12-02 04:51:10 +00004844 break;
thse4bcb142007-12-02 04:51:10 +00004845 p++;
balrog609497a2008-01-14 02:56:53 +00004846 }
thse4bcb142007-12-02 04:51:10 +00004847 if (q && (q - buf) < buf_size - 1)
4848 *q++ = *p;
4849 p++;
4850 }
4851 if (q)
4852 *q = '\0';
4853
4854 return p;
4855}
4856
bellard7c9d8e02005-11-15 22:16:05 +00004857static int get_param_value(char *buf, int buf_size,
4858 const char *tag, const char *str)
4859{
4860 const char *p;
bellard7c9d8e02005-11-15 22:16:05 +00004861 char option[128];
4862
4863 p = str;
4864 for(;;) {
balrog609497a2008-01-14 02:56:53 +00004865 p = get_opt_name(option, sizeof(option), p);
bellard7c9d8e02005-11-15 22:16:05 +00004866 if (*p != '=')
4867 break;
4868 p++;
4869 if (!strcmp(tag, option)) {
balrog609497a2008-01-14 02:56:53 +00004870 (void)get_opt_value(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00004871 return strlen(buf);
bellard7c9d8e02005-11-15 22:16:05 +00004872 } else {
balrog609497a2008-01-14 02:56:53 +00004873 p = get_opt_value(NULL, 0, p);
bellard7c9d8e02005-11-15 22:16:05 +00004874 }
4875 if (*p != ',')
4876 break;
4877 p++;
4878 }
4879 return 0;
4880}
4881
thse4bcb142007-12-02 04:51:10 +00004882static int check_params(char *buf, int buf_size,
4883 char **params, const char *str)
4884{
4885 const char *p;
4886 int i;
4887
4888 p = str;
4889 for(;;) {
balrog609497a2008-01-14 02:56:53 +00004890 p = get_opt_name(buf, buf_size, p);
thse4bcb142007-12-02 04:51:10 +00004891 if (*p != '=')
4892 return -1;
4893 p++;
4894 for(i = 0; params[i] != NULL; i++)
4895 if (!strcmp(params[i], buf))
4896 break;
4897 if (params[i] == NULL)
4898 return -1;
balrog609497a2008-01-14 02:56:53 +00004899 p = get_opt_value(NULL, 0, p);
thse4bcb142007-12-02 04:51:10 +00004900 if (*p != ',')
4901 break;
4902 p++;
4903 }
4904 return 0;
4905}
4906
4907
ths52f61fd2006-12-22 21:20:52 +00004908static int net_client_init(const char *str)
bellard7c9d8e02005-11-15 22:16:05 +00004909{
4910 const char *p;
4911 char *q;
4912 char device[64];
4913 char buf[1024];
4914 int vlan_id, ret;
4915 VLANState *vlan;
4916
4917 p = str;
4918 q = device;
4919 while (*p != '\0' && *p != ',') {
4920 if ((q - device) < sizeof(device) - 1)
4921 *q++ = *p;
4922 p++;
4923 }
4924 *q = '\0';
4925 if (*p == ',')
4926 p++;
4927 vlan_id = 0;
4928 if (get_param_value(buf, sizeof(buf), "vlan", p)) {
4929 vlan_id = strtol(buf, NULL, 0);
4930 }
4931 vlan = qemu_find_vlan(vlan_id);
4932 if (!vlan) {
4933 fprintf(stderr, "Could not create vlan %d\n", vlan_id);
4934 return -1;
4935 }
4936 if (!strcmp(device, "nic")) {
4937 NICInfo *nd;
4938 uint8_t *macaddr;
4939
4940 if (nb_nics >= MAX_NICS) {
4941 fprintf(stderr, "Too Many NICs\n");
4942 return -1;
4943 }
4944 nd = &nd_table[nb_nics];
4945 macaddr = nd->macaddr;
4946 macaddr[0] = 0x52;
4947 macaddr[1] = 0x54;
4948 macaddr[2] = 0x00;
4949 macaddr[3] = 0x12;
4950 macaddr[4] = 0x34;
4951 macaddr[5] = 0x56 + nb_nics;
4952
4953 if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
4954 if (parse_macaddr(macaddr, buf) < 0) {
4955 fprintf(stderr, "invalid syntax for ethernet address\n");
4956 return -1;
4957 }
4958 }
pbrooka41b2ff2006-02-05 04:14:41 +00004959 if (get_param_value(buf, sizeof(buf), "model", p)) {
4960 nd->model = strdup(buf);
4961 }
bellard7c9d8e02005-11-15 22:16:05 +00004962 nd->vlan = vlan;
4963 nb_nics++;
blueswir1833c7172007-05-27 19:36:43 +00004964 vlan->nb_guest_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00004965 ret = 0;
4966 } else
4967 if (!strcmp(device, "none")) {
4968 /* does nothing. It is needed to signal that no network cards
4969 are wanted */
4970 ret = 0;
4971 } else
4972#ifdef CONFIG_SLIRP
4973 if (!strcmp(device, "user")) {
pbrook115defd2006-04-16 11:06:58 +00004974 if (get_param_value(buf, sizeof(buf), "hostname", p)) {
bellard3f423c92006-04-30 21:34:15 +00004975 pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
pbrook115defd2006-04-16 11:06:58 +00004976 }
blueswir1833c7172007-05-27 19:36:43 +00004977 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00004978 ret = net_slirp_init(vlan);
4979 } else
4980#endif
bellard7fb843f2006-02-01 23:06:55 +00004981#ifdef _WIN32
4982 if (!strcmp(device, "tap")) {
4983 char ifname[64];
4984 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4985 fprintf(stderr, "tap: no interface name\n");
4986 return -1;
4987 }
blueswir1833c7172007-05-27 19:36:43 +00004988 vlan->nb_host_devs++;
bellard7fb843f2006-02-01 23:06:55 +00004989 ret = tap_win32_init(vlan, ifname);
4990 } else
4991#else
bellard7c9d8e02005-11-15 22:16:05 +00004992 if (!strcmp(device, "tap")) {
4993 char ifname[64];
thsb46a8902007-10-21 23:20:45 +00004994 char setup_script[1024], down_script[1024];
bellard7c9d8e02005-11-15 22:16:05 +00004995 int fd;
pbrook4f010352007-05-28 02:29:59 +00004996 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00004997 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4998 fd = strtol(buf, NULL, 0);
pbrook64538cd2008-03-24 02:31:33 +00004999 fcntl(fd, F_SETFL, O_NONBLOCK);
bellard7c9d8e02005-11-15 22:16:05 +00005000 ret = -1;
5001 if (net_tap_fd_init(vlan, fd))
5002 ret = 0;
5003 } else {
bellardbf8c5342007-01-09 19:44:41 +00005004 if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
5005 ifname[0] = '\0';
5006 }
bellard7c9d8e02005-11-15 22:16:05 +00005007 if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
5008 pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
5009 }
thsb46a8902007-10-21 23:20:45 +00005010 if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
5011 pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
5012 }
5013 ret = net_tap_init(vlan, ifname, setup_script, down_script);
bellard7c9d8e02005-11-15 22:16:05 +00005014 }
5015 } else
bellardfd1dff42006-02-01 21:29:26 +00005016#endif
bellard7c9d8e02005-11-15 22:16:05 +00005017 if (!strcmp(device, "socket")) {
5018 if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
5019 int fd;
5020 fd = strtol(buf, NULL, 0);
5021 ret = -1;
5022 if (net_socket_fd_init(vlan, fd, 1))
5023 ret = 0;
5024 } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
5025 ret = net_socket_listen_init(vlan, buf);
5026 } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
5027 ret = net_socket_connect_init(vlan, buf);
bellard3d830452005-12-18 16:36:49 +00005028 } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
5029 ret = net_socket_mcast_init(vlan, buf);
bellard7c9d8e02005-11-15 22:16:05 +00005030 } else {
5031 fprintf(stderr, "Unknown socket options: %s\n", p);
5032 return -1;
5033 }
blueswir1833c7172007-05-27 19:36:43 +00005034 vlan->nb_host_devs++;
bellard7c9d8e02005-11-15 22:16:05 +00005035 } else
bellard7c9d8e02005-11-15 22:16:05 +00005036 {
5037 fprintf(stderr, "Unknown network device: %s\n", device);
5038 return -1;
5039 }
5040 if (ret < 0) {
5041 fprintf(stderr, "Could not initialize device '%s'\n", device);
5042 }
ths3b46e622007-09-17 08:09:54 +00005043
bellard7c9d8e02005-11-15 22:16:05 +00005044 return ret;
5045}
5046
5047void do_info_network(void)
5048{
5049 VLANState *vlan;
5050 VLANClientState *vc;
5051
5052 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
5053 term_printf("VLAN %d devices:\n", vlan->id);
5054 for(vc = vlan->first_client; vc != NULL; vc = vc->next)
5055 term_printf(" %s\n", vc->info_str);
5056 }
5057}
ths42550fd2006-12-22 16:34:12 +00005058
balrog609497a2008-01-14 02:56:53 +00005059#define HD_ALIAS "index=%d,media=disk"
thse4bcb142007-12-02 04:51:10 +00005060#ifdef TARGET_PPC
5061#define CDROM_ALIAS "index=1,media=cdrom"
5062#else
5063#define CDROM_ALIAS "index=2,media=cdrom"
5064#endif
5065#define FD_ALIAS "index=%d,if=floppy"
balrog609497a2008-01-14 02:56:53 +00005066#define PFLASH_ALIAS "if=pflash"
5067#define MTD_ALIAS "if=mtd"
balrog9d413d12007-12-04 00:10:34 +00005068#define SD_ALIAS "index=0,if=sd"
thse4bcb142007-12-02 04:51:10 +00005069
balrog609497a2008-01-14 02:56:53 +00005070static int drive_add(const char *file, const char *fmt, ...)
thse4bcb142007-12-02 04:51:10 +00005071{
5072 va_list ap;
5073
5074 if (nb_drives_opt >= MAX_DRIVES) {
5075 fprintf(stderr, "qemu: too many drives\n");
5076 exit(1);
5077 }
5078
balrog609497a2008-01-14 02:56:53 +00005079 drives_opt[nb_drives_opt].file = file;
thse4bcb142007-12-02 04:51:10 +00005080 va_start(ap, fmt);
balrog609497a2008-01-14 02:56:53 +00005081 vsnprintf(drives_opt[nb_drives_opt].opt,
5082 sizeof(drives_opt[0].opt), fmt, ap);
thse4bcb142007-12-02 04:51:10 +00005083 va_end(ap);
5084
5085 return nb_drives_opt++;
5086}
5087
thsf60d39b2007-12-17 03:55:57 +00005088int drive_get_index(BlockInterfaceType type, int bus, int unit)
thse4bcb142007-12-02 04:51:10 +00005089{
5090 int index;
5091
5092 /* seek interface, bus and unit */
5093
5094 for (index = 0; index < nb_drives; index++)
thsf60d39b2007-12-17 03:55:57 +00005095 if (drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005096 drives_table[index].bus == bus &&
5097 drives_table[index].unit == unit)
5098 return index;
5099
5100 return -1;
5101}
5102
thsf60d39b2007-12-17 03:55:57 +00005103int drive_get_max_bus(BlockInterfaceType type)
thse4bcb142007-12-02 04:51:10 +00005104{
5105 int max_bus;
5106 int index;
5107
5108 max_bus = -1;
5109 for (index = 0; index < nb_drives; index++) {
thsf60d39b2007-12-17 03:55:57 +00005110 if(drives_table[index].type == type &&
thse4bcb142007-12-02 04:51:10 +00005111 drives_table[index].bus > max_bus)
5112 max_bus = drives_table[index].bus;
5113 }
5114 return max_bus;
5115}
5116
aurel32a1620fa2008-04-29 05:58:01 +00005117static void bdrv_format_print(void *opaque, const char *name)
5118{
5119 fprintf(stderr, " %s", name);
5120}
5121
balrog609497a2008-01-14 02:56:53 +00005122static int drive_init(struct drive_opt *arg, int snapshot,
5123 QEMUMachine *machine)
thse4bcb142007-12-02 04:51:10 +00005124{
5125 char buf[128];
5126 char file[1024];
balrogc8522bd2007-12-06 22:11:20 +00005127 char devname[128];
5128 const char *mediastr = "";
thsf60d39b2007-12-17 03:55:57 +00005129 BlockInterfaceType type;
thse4bcb142007-12-02 04:51:10 +00005130 enum { MEDIA_DISK, MEDIA_CDROM } media;
5131 int bus_id, unit_id;
5132 int cyls, heads, secs, translation;
5133 BlockDriverState *bdrv;
aurel321e72d3b2008-04-28 20:26:45 +00005134 BlockDriver *drv = NULL;
thse4bcb142007-12-02 04:51:10 +00005135 int max_devs;
5136 int index;
balrog33f00272007-12-24 14:33:24 +00005137 int cache;
5138 int bdrv_flags;
balrog609497a2008-01-14 02:56:53 +00005139 char *str = arg->opt;
thse4bcb142007-12-02 04:51:10 +00005140 char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
balrog33f00272007-12-24 14:33:24 +00005141 "secs", "trans", "media", "snapshot", "file",
aurel321e72d3b2008-04-28 20:26:45 +00005142 "cache", "format", NULL };
thse4bcb142007-12-02 04:51:10 +00005143
5144 if (check_params(buf, sizeof(buf), params, str) < 0) {
balrogff993632008-02-10 13:21:25 +00005145 fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
thse4bcb142007-12-02 04:51:10 +00005146 buf, str);
5147 return -1;
5148 }
5149
5150 file[0] = 0;
5151 cyls = heads = secs = 0;
5152 bus_id = 0;
5153 unit_id = -1;
5154 translation = BIOS_ATA_TRANSLATION_AUTO;
5155 index = -1;
balrog33f00272007-12-24 14:33:24 +00005156 cache = 1;
thse4bcb142007-12-02 04:51:10 +00005157
5158 if (!strcmp(machine->name, "realview") ||
5159 !strcmp(machine->name, "SS-5") ||
5160 !strcmp(machine->name, "SS-10") ||
5161 !strcmp(machine->name, "SS-600MP") ||
5162 !strcmp(machine->name, "versatilepb") ||
5163 !strcmp(machine->name, "versatileab")) {
thsf60d39b2007-12-17 03:55:57 +00005164 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005165 max_devs = MAX_SCSI_DEVS;
balrogc8522bd2007-12-06 22:11:20 +00005166 strcpy(devname, "scsi");
thse4bcb142007-12-02 04:51:10 +00005167 } else {
thsf60d39b2007-12-17 03:55:57 +00005168 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005169 max_devs = MAX_IDE_DEVS;
balrogc8522bd2007-12-06 22:11:20 +00005170 strcpy(devname, "ide");
thse4bcb142007-12-02 04:51:10 +00005171 }
5172 media = MEDIA_DISK;
5173
5174 /* extract parameters */
5175
5176 if (get_param_value(buf, sizeof(buf), "bus", str)) {
5177 bus_id = strtol(buf, NULL, 0);
5178 if (bus_id < 0) {
5179 fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
5180 return -1;
5181 }
5182 }
5183
5184 if (get_param_value(buf, sizeof(buf), "unit", str)) {
5185 unit_id = strtol(buf, NULL, 0);
5186 if (unit_id < 0) {
5187 fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
5188 return -1;
5189 }
5190 }
5191
5192 if (get_param_value(buf, sizeof(buf), "if", str)) {
bellardae45d362008-06-11 09:44:44 +00005193 pstrcpy(devname, sizeof(devname), buf);
thse4bcb142007-12-02 04:51:10 +00005194 if (!strcmp(buf, "ide")) {
thsf60d39b2007-12-17 03:55:57 +00005195 type = IF_IDE;
thse4bcb142007-12-02 04:51:10 +00005196 max_devs = MAX_IDE_DEVS;
5197 } else if (!strcmp(buf, "scsi")) {
thsf60d39b2007-12-17 03:55:57 +00005198 type = IF_SCSI;
thse4bcb142007-12-02 04:51:10 +00005199 max_devs = MAX_SCSI_DEVS;
5200 } else if (!strcmp(buf, "floppy")) {
thsf60d39b2007-12-17 03:55:57 +00005201 type = IF_FLOPPY;
thse4bcb142007-12-02 04:51:10 +00005202 max_devs = 0;
5203 } else if (!strcmp(buf, "pflash")) {
thsf60d39b2007-12-17 03:55:57 +00005204 type = IF_PFLASH;
thse4bcb142007-12-02 04:51:10 +00005205 max_devs = 0;
5206 } else if (!strcmp(buf, "mtd")) {
thsf60d39b2007-12-17 03:55:57 +00005207 type = IF_MTD;
thse4bcb142007-12-02 04:51:10 +00005208 max_devs = 0;
5209 } else if (!strcmp(buf, "sd")) {
thsf60d39b2007-12-17 03:55:57 +00005210 type = IF_SD;
thse4bcb142007-12-02 04:51:10 +00005211 max_devs = 0;
5212 } else {
5213 fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
5214 return -1;
5215 }
5216 }
5217
5218 if (get_param_value(buf, sizeof(buf), "index", str)) {
5219 index = strtol(buf, NULL, 0);
5220 if (index < 0) {
5221 fprintf(stderr, "qemu: '%s' invalid index\n", str);
5222 return -1;
5223 }
5224 }
5225
5226 if (get_param_value(buf, sizeof(buf), "cyls", str)) {
5227 cyls = strtol(buf, NULL, 0);
5228 }
5229
5230 if (get_param_value(buf, sizeof(buf), "heads", str)) {
5231 heads = strtol(buf, NULL, 0);
5232 }
5233
5234 if (get_param_value(buf, sizeof(buf), "secs", str)) {
5235 secs = strtol(buf, NULL, 0);
5236 }
5237
5238 if (cyls || heads || secs) {
5239 if (cyls < 1 || cyls > 16383) {
5240 fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
5241 return -1;
5242 }
5243 if (heads < 1 || heads > 16) {
5244 fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
5245 return -1;
5246 }
5247 if (secs < 1 || secs > 63) {
5248 fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
5249 return -1;
5250 }
5251 }
5252
5253 if (get_param_value(buf, sizeof(buf), "trans", str)) {
5254 if (!cyls) {
5255 fprintf(stderr,
5256 "qemu: '%s' trans must be used with cyls,heads and secs\n",
5257 str);
5258 return -1;
5259 }
5260 if (!strcmp(buf, "none"))
5261 translation = BIOS_ATA_TRANSLATION_NONE;
5262 else if (!strcmp(buf, "lba"))
5263 translation = BIOS_ATA_TRANSLATION_LBA;
5264 else if (!strcmp(buf, "auto"))
5265 translation = BIOS_ATA_TRANSLATION_AUTO;
5266 else {
5267 fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
5268 return -1;
5269 }
5270 }
5271
5272 if (get_param_value(buf, sizeof(buf), "media", str)) {
5273 if (!strcmp(buf, "disk")) {
5274 media = MEDIA_DISK;
5275 } else if (!strcmp(buf, "cdrom")) {
5276 if (cyls || secs || heads) {
5277 fprintf(stderr,
5278 "qemu: '%s' invalid physical CHS format\n", str);
5279 return -1;
5280 }
5281 media = MEDIA_CDROM;
5282 } else {
5283 fprintf(stderr, "qemu: '%s' invalid media\n", str);
5284 return -1;
5285 }
5286 }
5287
5288 if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
5289 if (!strcmp(buf, "on"))
5290 snapshot = 1;
5291 else if (!strcmp(buf, "off"))
5292 snapshot = 0;
5293 else {
5294 fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
5295 return -1;
5296 }
5297 }
5298
balrog33f00272007-12-24 14:33:24 +00005299 if (get_param_value(buf, sizeof(buf), "cache", str)) {
5300 if (!strcmp(buf, "off"))
5301 cache = 0;
5302 else if (!strcmp(buf, "on"))
5303 cache = 1;
5304 else {
5305 fprintf(stderr, "qemu: invalid cache option\n");
5306 return -1;
5307 }
5308 }
5309
aurel321e72d3b2008-04-28 20:26:45 +00005310 if (get_param_value(buf, sizeof(buf), "format", str)) {
aurel32a1620fa2008-04-29 05:58:01 +00005311 if (strcmp(buf, "?") == 0) {
5312 fprintf(stderr, "qemu: Supported formats:");
5313 bdrv_iterate_format(bdrv_format_print, NULL);
5314 fprintf(stderr, "\n");
5315 return -1;
5316 }
aurel321e72d3b2008-04-28 20:26:45 +00005317 drv = bdrv_find_format(buf);
5318 if (!drv) {
5319 fprintf(stderr, "qemu: '%s' invalid format\n", buf);
5320 return -1;
5321 }
5322 }
5323
balrog609497a2008-01-14 02:56:53 +00005324 if (arg->file == NULL)
5325 get_param_value(file, sizeof(file), "file", str);
5326 else
5327 pstrcpy(file, sizeof(file), arg->file);
thse4bcb142007-12-02 04:51:10 +00005328
5329 /* compute bus and unit according index */
5330
5331 if (index != -1) {
5332 if (bus_id != 0 || unit_id != -1) {
5333 fprintf(stderr,
5334 "qemu: '%s' index cannot be used with bus and unit\n", str);
5335 return -1;
5336 }
5337 if (max_devs == 0)
5338 {
5339 unit_id = index;
5340 bus_id = 0;
5341 } else {
5342 unit_id = index % max_devs;
5343 bus_id = index / max_devs;
5344 }
5345 }
5346
5347 /* if user doesn't specify a unit_id,
5348 * try to find the first free
5349 */
5350
5351 if (unit_id == -1) {
5352 unit_id = 0;
thsf60d39b2007-12-17 03:55:57 +00005353 while (drive_get_index(type, bus_id, unit_id) != -1) {
thse4bcb142007-12-02 04:51:10 +00005354 unit_id++;
5355 if (max_devs && unit_id >= max_devs) {
5356 unit_id -= max_devs;
5357 bus_id++;
5358 }
5359 }
5360 }
5361
5362 /* check unit id */
5363
5364 if (max_devs && unit_id >= max_devs) {
5365 fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
5366 str, unit_id, max_devs - 1);
5367 return -1;
5368 }
5369
5370 /*
5371 * ignore multiple definitions
5372 */
5373
thsf60d39b2007-12-17 03:55:57 +00005374 if (drive_get_index(type, bus_id, unit_id) != -1)
thse4bcb142007-12-02 04:51:10 +00005375 return 0;
5376
5377 /* init */
5378
thsf60d39b2007-12-17 03:55:57 +00005379 if (type == IF_IDE || type == IF_SCSI)
balrogc8522bd2007-12-06 22:11:20 +00005380 mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
balroge6198a72007-12-24 13:58:47 +00005381 if (max_devs)
5382 snprintf(buf, sizeof(buf), "%s%i%s%i",
5383 devname, bus_id, mediastr, unit_id);
5384 else
5385 snprintf(buf, sizeof(buf), "%s%s%i",
5386 devname, mediastr, unit_id);
thse4bcb142007-12-02 04:51:10 +00005387 bdrv = bdrv_new(buf);
5388 drives_table[nb_drives].bdrv = bdrv;
thsf60d39b2007-12-17 03:55:57 +00005389 drives_table[nb_drives].type = type;
thse4bcb142007-12-02 04:51:10 +00005390 drives_table[nb_drives].bus = bus_id;
5391 drives_table[nb_drives].unit = unit_id;
5392 nb_drives++;
5393
thsf60d39b2007-12-17 03:55:57 +00005394 switch(type) {
thse4bcb142007-12-02 04:51:10 +00005395 case IF_IDE:
5396 case IF_SCSI:
5397 switch(media) {
5398 case MEDIA_DISK:
5399 if (cyls != 0) {
5400 bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
5401 bdrv_set_translation_hint(bdrv, translation);
5402 }
5403 break;
5404 case MEDIA_CDROM:
5405 bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
5406 break;
5407 }
5408 break;
5409 case IF_SD:
5410 /* FIXME: This isn't really a floppy, but it's a reasonable
5411 approximation. */
5412 case IF_FLOPPY:
5413 bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
5414 break;
5415 case IF_PFLASH:
5416 case IF_MTD:
5417 break;
5418 }
5419 if (!file[0])
5420 return 0;
balrog33f00272007-12-24 14:33:24 +00005421 bdrv_flags = 0;
5422 if (snapshot)
5423 bdrv_flags |= BDRV_O_SNAPSHOT;
5424 if (!cache)
5425 bdrv_flags |= BDRV_O_DIRECT;
aurel321e72d3b2008-04-28 20:26:45 +00005426 if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
thse4bcb142007-12-02 04:51:10 +00005427 fprintf(stderr, "qemu: could not open disk image %s\n",
5428 file);
5429 return -1;
5430 }
5431 return 0;
5432}
5433
bellard330d0412003-07-26 18:11:40 +00005434/***********************************************************/
bellarda594cfb2005-11-06 16:13:29 +00005435/* USB devices */
5436
pbrook0d92ed32006-05-21 16:30:15 +00005437static USBPort *used_usb_ports;
5438static USBPort *free_usb_ports;
5439
5440/* ??? Maybe change this to register a hub to keep track of the topology. */
5441void qemu_register_usb_port(USBPort *port, void *opaque, int index,
5442 usb_attachfn attach)
5443{
5444 port->opaque = opaque;
5445 port->index = index;
5446 port->attach = attach;
5447 port->next = free_usb_ports;
5448 free_usb_ports = port;
5449}
5450
bellarda594cfb2005-11-06 16:13:29 +00005451static int usb_device_add(const char *devname)
5452{
5453 const char *p;
5454 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00005455 USBPort *port;
bellarda594cfb2005-11-06 16:13:29 +00005456
pbrook0d92ed32006-05-21 16:30:15 +00005457 if (!free_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005458 return -1;
5459
5460 if (strstart(devname, "host:", &p)) {
5461 dev = usb_host_device_open(p);
bellarda594cfb2005-11-06 16:13:29 +00005462 } else if (!strcmp(devname, "mouse")) {
5463 dev = usb_mouse_init();
bellard09b26c52006-04-12 21:09:08 +00005464 } else if (!strcmp(devname, "tablet")) {
balrog47b2d332007-06-22 08:16:00 +00005465 dev = usb_tablet_init();
5466 } else if (!strcmp(devname, "keyboard")) {
5467 dev = usb_keyboard_init();
pbrook2e5d83b2006-05-25 23:58:51 +00005468 } else if (strstart(devname, "disk:", &p)) {
5469 dev = usb_msd_init(p);
balrogf6d2a312007-06-10 19:21:04 +00005470 } else if (!strcmp(devname, "wacom-tablet")) {
5471 dev = usb_wacom_init();
balroga7954212008-01-14 03:41:02 +00005472 } else if (strstart(devname, "serial:", &p)) {
5473 dev = usb_serial_init(p);
aurel322e4d9fb2008-04-08 06:01:02 +00005474#ifdef CONFIG_BRLAPI
5475 } else if (!strcmp(devname, "braille")) {
5476 dev = usb_baum_init();
5477#endif
bellarda594cfb2005-11-06 16:13:29 +00005478 } else {
5479 return -1;
5480 }
pbrook0d92ed32006-05-21 16:30:15 +00005481 if (!dev)
5482 return -1;
5483
5484 /* Find a USB port to add the device to. */
5485 port = free_usb_ports;
5486 if (!port->next) {
5487 USBDevice *hub;
5488
5489 /* Create a new hub and chain it on. */
5490 free_usb_ports = NULL;
5491 port->next = used_usb_ports;
5492 used_usb_ports = port;
5493
5494 hub = usb_hub_init(VM_USB_HUB_SIZE);
5495 usb_attach(port, hub);
5496 port = free_usb_ports;
5497 }
5498
5499 free_usb_ports = port->next;
5500 port->next = used_usb_ports;
5501 used_usb_ports = port;
5502 usb_attach(port, dev);
bellarda594cfb2005-11-06 16:13:29 +00005503 return 0;
5504}
5505
5506static int usb_device_del(const char *devname)
5507{
pbrook0d92ed32006-05-21 16:30:15 +00005508 USBPort *port;
5509 USBPort **lastp;
bellard059809e2006-07-19 18:06:15 +00005510 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00005511 int bus_num, addr;
bellarda594cfb2005-11-06 16:13:29 +00005512 const char *p;
5513
pbrook0d92ed32006-05-21 16:30:15 +00005514 if (!used_usb_ports)
bellarda594cfb2005-11-06 16:13:29 +00005515 return -1;
5516
5517 p = strchr(devname, '.');
ths5fafdf22007-09-16 21:08:06 +00005518 if (!p)
bellarda594cfb2005-11-06 16:13:29 +00005519 return -1;
5520 bus_num = strtoul(devname, NULL, 0);
5521 addr = strtoul(p + 1, NULL, 0);
5522 if (bus_num != 0)
5523 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005524
5525 lastp = &used_usb_ports;
5526 port = used_usb_ports;
5527 while (port && port->dev->addr != addr) {
5528 lastp = &port->next;
5529 port = port->next;
bellarda594cfb2005-11-06 16:13:29 +00005530 }
pbrook0d92ed32006-05-21 16:30:15 +00005531
5532 if (!port)
bellarda594cfb2005-11-06 16:13:29 +00005533 return -1;
pbrook0d92ed32006-05-21 16:30:15 +00005534
bellard059809e2006-07-19 18:06:15 +00005535 dev = port->dev;
pbrook0d92ed32006-05-21 16:30:15 +00005536 *lastp = port->next;
5537 usb_attach(port, NULL);
bellard059809e2006-07-19 18:06:15 +00005538 dev->handle_destroy(dev);
pbrook0d92ed32006-05-21 16:30:15 +00005539 port->next = free_usb_ports;
5540 free_usb_ports = port;
bellarda594cfb2005-11-06 16:13:29 +00005541 return 0;
5542}
5543
5544void do_usb_add(const char *devname)
5545{
5546 int ret;
5547 ret = usb_device_add(devname);
ths5fafdf22007-09-16 21:08:06 +00005548 if (ret < 0)
bellarda594cfb2005-11-06 16:13:29 +00005549 term_printf("Could not add USB device '%s'\n", devname);
5550}
5551
5552void do_usb_del(const char *devname)
5553{
5554 int ret;
5555 ret = usb_device_del(devname);
ths5fafdf22007-09-16 21:08:06 +00005556 if (ret < 0)
bellarda594cfb2005-11-06 16:13:29 +00005557 term_printf("Could not remove USB device '%s'\n", devname);
5558}
5559
5560void usb_info(void)
5561{
5562 USBDevice *dev;
pbrook0d92ed32006-05-21 16:30:15 +00005563 USBPort *port;
bellarda594cfb2005-11-06 16:13:29 +00005564 const char *speed_str;
5565
pbrook0d92ed32006-05-21 16:30:15 +00005566 if (!usb_enabled) {
bellarda594cfb2005-11-06 16:13:29 +00005567 term_printf("USB support not enabled\n");
5568 return;
5569 }
5570
pbrook0d92ed32006-05-21 16:30:15 +00005571 for (port = used_usb_ports; port; port = port->next) {
5572 dev = port->dev;
5573 if (!dev)
5574 continue;
5575 switch(dev->speed) {
ths5fafdf22007-09-16 21:08:06 +00005576 case USB_SPEED_LOW:
5577 speed_str = "1.5";
pbrook0d92ed32006-05-21 16:30:15 +00005578 break;
ths5fafdf22007-09-16 21:08:06 +00005579 case USB_SPEED_FULL:
5580 speed_str = "12";
pbrook0d92ed32006-05-21 16:30:15 +00005581 break;
ths5fafdf22007-09-16 21:08:06 +00005582 case USB_SPEED_HIGH:
5583 speed_str = "480";
pbrook0d92ed32006-05-21 16:30:15 +00005584 break;
5585 default:
ths5fafdf22007-09-16 21:08:06 +00005586 speed_str = "?";
pbrook0d92ed32006-05-21 16:30:15 +00005587 break;
bellarda594cfb2005-11-06 16:13:29 +00005588 }
ths5fafdf22007-09-16 21:08:06 +00005589 term_printf(" Device %d.%d, Speed %s Mb/s, Product %s\n",
bellard1f6e24e2006-06-26 21:00:51 +00005590 0, dev->addr, speed_str, dev->devname);
bellarda594cfb2005-11-06 16:13:29 +00005591 }
5592}
5593
bellardf7cce892004-12-08 22:21:25 +00005594/***********************************************************/
balrog201a51f2007-04-30 00:51:09 +00005595/* PCMCIA/Cardbus */
5596
5597static struct pcmcia_socket_entry_s {
5598 struct pcmcia_socket_s *socket;
5599 struct pcmcia_socket_entry_s *next;
5600} *pcmcia_sockets = 0;
5601
5602void pcmcia_socket_register(struct pcmcia_socket_s *socket)
5603{
5604 struct pcmcia_socket_entry_s *entry;
5605
5606 entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
5607 entry->socket = socket;
5608 entry->next = pcmcia_sockets;
5609 pcmcia_sockets = entry;
5610}
5611
5612void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
5613{
5614 struct pcmcia_socket_entry_s *entry, **ptr;
5615
5616 ptr = &pcmcia_sockets;
5617 for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
5618 if (entry->socket == socket) {
5619 *ptr = entry->next;
5620 qemu_free(entry);
5621 }
5622}
5623
5624void pcmcia_info(void)
5625{
5626 struct pcmcia_socket_entry_s *iter;
5627 if (!pcmcia_sockets)
5628 term_printf("No PCMCIA sockets\n");
5629
5630 for (iter = pcmcia_sockets; iter; iter = iter->next)
5631 term_printf("%s: %s\n", iter->socket->slot_string,
5632 iter->socket->attached ? iter->socket->card_string :
5633 "Empty");
5634}
5635
5636/***********************************************************/
ths2ff89792007-06-21 23:34:19 +00005637/* dumb display */
5638
5639static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
5640{
5641}
5642
5643static void dumb_resize(DisplayState *ds, int w, int h)
5644{
5645}
5646
5647static void dumb_refresh(DisplayState *ds)
5648{
5649#if defined(CONFIG_SDL)
5650 vga_hw_update();
5651#endif
5652}
5653
5654static void dumb_display_init(DisplayState *ds)
5655{
5656 ds->data = NULL;
5657 ds->linesize = 0;
5658 ds->depth = 0;
5659 ds->dpy_update = dumb_update;
5660 ds->dpy_resize = dumb_resize;
5661 ds->dpy_refresh = dumb_refresh;
5662}
5663
5664/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00005665/* I/O handling */
bellard0824d6f2003-06-24 13:42:40 +00005666
bellardc4b1fcc2004-03-14 21:44:30 +00005667#define MAX_IO_HANDLERS 64
5668
5669typedef struct IOHandlerRecord {
5670 int fd;
bellard7c9d8e02005-11-15 22:16:05 +00005671 IOCanRWHandler *fd_read_poll;
5672 IOHandler *fd_read;
5673 IOHandler *fd_write;
thscafffd42007-02-28 21:59:44 +00005674 int deleted;
bellardc4b1fcc2004-03-14 21:44:30 +00005675 void *opaque;
5676 /* temporary data */
5677 struct pollfd *ufd;
bellard8a7ddc32004-03-31 19:00:16 +00005678 struct IOHandlerRecord *next;
bellardc4b1fcc2004-03-14 21:44:30 +00005679} IOHandlerRecord;
5680
bellard8a7ddc32004-03-31 19:00:16 +00005681static IOHandlerRecord *first_io_handler;
bellardc4b1fcc2004-03-14 21:44:30 +00005682
bellard7c9d8e02005-11-15 22:16:05 +00005683/* XXX: fd_read_poll should be suppressed, but an API change is
5684 necessary in the character devices to suppress fd_can_read(). */
ths5fafdf22007-09-16 21:08:06 +00005685int qemu_set_fd_handler2(int fd,
5686 IOCanRWHandler *fd_read_poll,
5687 IOHandler *fd_read,
5688 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00005689 void *opaque)
bellardb4608c02003-06-27 17:34:32 +00005690{
bellard8a7ddc32004-03-31 19:00:16 +00005691 IOHandlerRecord **pioh, *ioh;
5692
bellard7c9d8e02005-11-15 22:16:05 +00005693 if (!fd_read && !fd_write) {
5694 pioh = &first_io_handler;
5695 for(;;) {
5696 ioh = *pioh;
5697 if (ioh == NULL)
5698 break;
5699 if (ioh->fd == fd) {
thscafffd42007-02-28 21:59:44 +00005700 ioh->deleted = 1;
bellard7c9d8e02005-11-15 22:16:05 +00005701 break;
5702 }
5703 pioh = &ioh->next;
bellard8a7ddc32004-03-31 19:00:16 +00005704 }
bellard7c9d8e02005-11-15 22:16:05 +00005705 } else {
5706 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
5707 if (ioh->fd == fd)
5708 goto found;
5709 }
5710 ioh = qemu_mallocz(sizeof(IOHandlerRecord));
5711 if (!ioh)
5712 return -1;
5713 ioh->next = first_io_handler;
5714 first_io_handler = ioh;
5715 found:
5716 ioh->fd = fd;
5717 ioh->fd_read_poll = fd_read_poll;
5718 ioh->fd_read = fd_read;
5719 ioh->fd_write = fd_write;
5720 ioh->opaque = opaque;
thscafffd42007-02-28 21:59:44 +00005721 ioh->deleted = 0;
bellard8a7ddc32004-03-31 19:00:16 +00005722 }
bellard7c9d8e02005-11-15 22:16:05 +00005723 return 0;
5724}
5725
ths5fafdf22007-09-16 21:08:06 +00005726int qemu_set_fd_handler(int fd,
5727 IOHandler *fd_read,
5728 IOHandler *fd_write,
bellard7c9d8e02005-11-15 22:16:05 +00005729 void *opaque)
5730{
5731 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
bellardb4608c02003-06-27 17:34:32 +00005732}
5733
bellard8a7ddc32004-03-31 19:00:16 +00005734/***********************************************************/
bellardf3311102006-04-12 20:21:17 +00005735/* Polling handling */
5736
5737typedef struct PollingEntry {
5738 PollingFunc *func;
5739 void *opaque;
5740 struct PollingEntry *next;
5741} PollingEntry;
5742
5743static PollingEntry *first_polling_entry;
5744
5745int qemu_add_polling_cb(PollingFunc *func, void *opaque)
5746{
5747 PollingEntry **ppe, *pe;
5748 pe = qemu_mallocz(sizeof(PollingEntry));
5749 if (!pe)
5750 return -1;
5751 pe->func = func;
5752 pe->opaque = opaque;
5753 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
5754 *ppe = pe;
5755 return 0;
5756}
5757
5758void qemu_del_polling_cb(PollingFunc *func, void *opaque)
5759{
5760 PollingEntry **ppe, *pe;
5761 for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
5762 pe = *ppe;
5763 if (pe->func == func && pe->opaque == opaque) {
5764 *ppe = pe->next;
5765 qemu_free(pe);
5766 break;
5767 }
5768 }
5769}
5770
bellarda18e5242006-06-25 17:18:27 +00005771#ifdef _WIN32
5772/***********************************************************/
5773/* Wait objects support */
5774typedef struct WaitObjects {
5775 int num;
5776 HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
5777 WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
5778 void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
5779} WaitObjects;
5780
5781static WaitObjects wait_objects = {0};
ths3b46e622007-09-17 08:09:54 +00005782
bellarda18e5242006-06-25 17:18:27 +00005783int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5784{
5785 WaitObjects *w = &wait_objects;
5786
5787 if (w->num >= MAXIMUM_WAIT_OBJECTS)
5788 return -1;
5789 w->events[w->num] = handle;
5790 w->func[w->num] = func;
5791 w->opaque[w->num] = opaque;
5792 w->num++;
5793 return 0;
5794}
5795
5796void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5797{
5798 int i, found;
5799 WaitObjects *w = &wait_objects;
5800
5801 found = 0;
5802 for (i = 0; i < w->num; i++) {
5803 if (w->events[i] == handle)
5804 found = 1;
5805 if (found) {
5806 w->events[i] = w->events[i + 1];
5807 w->func[i] = w->func[i + 1];
5808 w->opaque[i] = w->opaque[i + 1];
ths3b46e622007-09-17 08:09:54 +00005809 }
bellarda18e5242006-06-25 17:18:27 +00005810 }
5811 if (found)
5812 w->num--;
5813}
5814#endif
5815
bellardf3311102006-04-12 20:21:17 +00005816/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00005817/* savevm/loadvm support */
bellardb4608c02003-06-27 17:34:32 +00005818
bellardfaea38e2006-08-05 21:31:00 +00005819#define IO_BUF_SIZE 32768
5820
5821struct QEMUFile {
5822 FILE *outfile;
5823 BlockDriverState *bs;
5824 int is_file;
5825 int is_writable;
5826 int64_t base_offset;
5827 int64_t buf_offset; /* start of buffer when writing, end of buffer
5828 when reading */
5829 int buf_index;
5830 int buf_size; /* 0 when writing */
5831 uint8_t buf[IO_BUF_SIZE];
5832};
5833
5834QEMUFile *qemu_fopen(const char *filename, const char *mode)
5835{
5836 QEMUFile *f;
5837
5838 f = qemu_mallocz(sizeof(QEMUFile));
5839 if (!f)
5840 return NULL;
5841 if (!strcmp(mode, "wb")) {
5842 f->is_writable = 1;
5843 } else if (!strcmp(mode, "rb")) {
5844 f->is_writable = 0;
5845 } else {
5846 goto fail;
5847 }
5848 f->outfile = fopen(filename, mode);
5849 if (!f->outfile)
5850 goto fail;
5851 f->is_file = 1;
5852 return f;
5853 fail:
5854 if (f->outfile)
5855 fclose(f->outfile);
5856 qemu_free(f);
5857 return NULL;
5858}
5859
pbrook9596ebb2007-11-18 01:44:38 +00005860static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
bellardfaea38e2006-08-05 21:31:00 +00005861{
5862 QEMUFile *f;
5863
5864 f = qemu_mallocz(sizeof(QEMUFile));
5865 if (!f)
5866 return NULL;
5867 f->is_file = 0;
5868 f->bs = bs;
5869 f->is_writable = is_writable;
5870 f->base_offset = offset;
5871 return f;
5872}
5873
5874void qemu_fflush(QEMUFile *f)
5875{
5876 if (!f->is_writable)
5877 return;
5878 if (f->buf_index > 0) {
5879 if (f->is_file) {
5880 fseek(f->outfile, f->buf_offset, SEEK_SET);
5881 fwrite(f->buf, 1, f->buf_index, f->outfile);
5882 } else {
ths5fafdf22007-09-16 21:08:06 +00005883 bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00005884 f->buf, f->buf_index);
5885 }
5886 f->buf_offset += f->buf_index;
5887 f->buf_index = 0;
5888 }
5889}
5890
5891static void qemu_fill_buffer(QEMUFile *f)
5892{
5893 int len;
5894
5895 if (f->is_writable)
5896 return;
5897 if (f->is_file) {
5898 fseek(f->outfile, f->buf_offset, SEEK_SET);
5899 len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
5900 if (len < 0)
5901 len = 0;
5902 } else {
ths5fafdf22007-09-16 21:08:06 +00005903 len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
bellardfaea38e2006-08-05 21:31:00 +00005904 f->buf, IO_BUF_SIZE);
5905 if (len < 0)
5906 len = 0;
5907 }
5908 f->buf_index = 0;
5909 f->buf_size = len;
5910 f->buf_offset += len;
5911}
5912
5913void qemu_fclose(QEMUFile *f)
5914{
5915 if (f->is_writable)
5916 qemu_fflush(f);
5917 if (f->is_file) {
5918 fclose(f->outfile);
5919 }
5920 qemu_free(f);
5921}
5922
bellard8a7ddc32004-03-31 19:00:16 +00005923void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
5924{
bellardfaea38e2006-08-05 21:31:00 +00005925 int l;
5926 while (size > 0) {
5927 l = IO_BUF_SIZE - f->buf_index;
5928 if (l > size)
5929 l = size;
5930 memcpy(f->buf + f->buf_index, buf, l);
5931 f->buf_index += l;
5932 buf += l;
5933 size -= l;
5934 if (f->buf_index >= IO_BUF_SIZE)
5935 qemu_fflush(f);
5936 }
bellard8a7ddc32004-03-31 19:00:16 +00005937}
5938
5939void qemu_put_byte(QEMUFile *f, int v)
5940{
bellardfaea38e2006-08-05 21:31:00 +00005941 f->buf[f->buf_index++] = v;
5942 if (f->buf_index >= IO_BUF_SIZE)
5943 qemu_fflush(f);
5944}
5945
5946int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
5947{
5948 int size, l;
5949
5950 size = size1;
5951 while (size > 0) {
5952 l = f->buf_size - f->buf_index;
5953 if (l == 0) {
5954 qemu_fill_buffer(f);
5955 l = f->buf_size - f->buf_index;
5956 if (l == 0)
5957 break;
5958 }
5959 if (l > size)
5960 l = size;
5961 memcpy(buf, f->buf + f->buf_index, l);
5962 f->buf_index += l;
5963 buf += l;
5964 size -= l;
5965 }
5966 return size1 - size;
5967}
5968
5969int qemu_get_byte(QEMUFile *f)
5970{
5971 if (f->buf_index >= f->buf_size) {
5972 qemu_fill_buffer(f);
5973 if (f->buf_index >= f->buf_size)
5974 return 0;
5975 }
5976 return f->buf[f->buf_index++];
5977}
5978
5979int64_t qemu_ftell(QEMUFile *f)
5980{
5981 return f->buf_offset - f->buf_size + f->buf_index;
5982}
5983
5984int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
5985{
5986 if (whence == SEEK_SET) {
5987 /* nothing to do */
5988 } else if (whence == SEEK_CUR) {
5989 pos += qemu_ftell(f);
5990 } else {
5991 /* SEEK_END not supported */
5992 return -1;
5993 }
5994 if (f->is_writable) {
5995 qemu_fflush(f);
5996 f->buf_offset = pos;
5997 } else {
5998 f->buf_offset = pos;
5999 f->buf_index = 0;
6000 f->buf_size = 0;
6001 }
6002 return pos;
bellard8a7ddc32004-03-31 19:00:16 +00006003}
6004
6005void qemu_put_be16(QEMUFile *f, unsigned int v)
6006{
6007 qemu_put_byte(f, v >> 8);
6008 qemu_put_byte(f, v);
6009}
6010
6011void qemu_put_be32(QEMUFile *f, unsigned int v)
6012{
6013 qemu_put_byte(f, v >> 24);
6014 qemu_put_byte(f, v >> 16);
6015 qemu_put_byte(f, v >> 8);
6016 qemu_put_byte(f, v);
6017}
6018
6019void qemu_put_be64(QEMUFile *f, uint64_t v)
6020{
6021 qemu_put_be32(f, v >> 32);
6022 qemu_put_be32(f, v);
6023}
6024
bellard8a7ddc32004-03-31 19:00:16 +00006025unsigned int qemu_get_be16(QEMUFile *f)
6026{
6027 unsigned int v;
6028 v = qemu_get_byte(f) << 8;
6029 v |= qemu_get_byte(f);
6030 return v;
6031}
6032
6033unsigned int qemu_get_be32(QEMUFile *f)
6034{
6035 unsigned int v;
6036 v = qemu_get_byte(f) << 24;
6037 v |= qemu_get_byte(f) << 16;
6038 v |= qemu_get_byte(f) << 8;
6039 v |= qemu_get_byte(f);
6040 return v;
6041}
6042
6043uint64_t qemu_get_be64(QEMUFile *f)
6044{
6045 uint64_t v;
6046 v = (uint64_t)qemu_get_be32(f) << 32;
6047 v |= qemu_get_be32(f);
6048 return v;
6049}
6050
bellard8a7ddc32004-03-31 19:00:16 +00006051typedef struct SaveStateEntry {
6052 char idstr[256];
6053 int instance_id;
6054 int version_id;
6055 SaveStateHandler *save_state;
6056 LoadStateHandler *load_state;
6057 void *opaque;
6058 struct SaveStateEntry *next;
6059} SaveStateEntry;
6060
6061static SaveStateEntry *first_se;
6062
pbrook18be5182008-07-01 21:31:54 +00006063/* TODO: Individual devices generally have very little idea about the rest
6064 of the system, so instance_id should be removed/replaced. */
ths5fafdf22007-09-16 21:08:06 +00006065int register_savevm(const char *idstr,
6066 int instance_id,
bellard8a7ddc32004-03-31 19:00:16 +00006067 int version_id,
6068 SaveStateHandler *save_state,
6069 LoadStateHandler *load_state,
6070 void *opaque)
6071{
6072 SaveStateEntry *se, **pse;
6073
6074 se = qemu_malloc(sizeof(SaveStateEntry));
6075 if (!se)
6076 return -1;
6077 pstrcpy(se->idstr, sizeof(se->idstr), idstr);
pbrook18be5182008-07-01 21:31:54 +00006078 se->instance_id = (instance_id == -1) ? 0 : instance_id;
bellard8a7ddc32004-03-31 19:00:16 +00006079 se->version_id = version_id;
6080 se->save_state = save_state;
6081 se->load_state = load_state;
6082 se->opaque = opaque;
6083 se->next = NULL;
6084
6085 /* add at the end of list */
6086 pse = &first_se;
pbrook18be5182008-07-01 21:31:54 +00006087 while (*pse != NULL) {
6088 if (instance_id == -1
6089 && strcmp(se->idstr, (*pse)->idstr) == 0
6090 && se->instance_id <= (*pse)->instance_id)
6091 se->instance_id = (*pse)->instance_id + 1;
bellard8a7ddc32004-03-31 19:00:16 +00006092 pse = &(*pse)->next;
pbrook18be5182008-07-01 21:31:54 +00006093 }
bellard8a7ddc32004-03-31 19:00:16 +00006094 *pse = se;
6095 return 0;
6096}
6097
6098#define QEMU_VM_FILE_MAGIC 0x5145564d
bellardfaea38e2006-08-05 21:31:00 +00006099#define QEMU_VM_FILE_VERSION 0x00000002
bellard8a7ddc32004-03-31 19:00:16 +00006100
pbrook9596ebb2007-11-18 01:44:38 +00006101static int qemu_savevm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006102{
6103 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006104 int len, ret;
6105 int64_t cur_pos, len_pos, total_len_pos;
bellard313aa562003-08-10 21:52:11 +00006106
bellard8a7ddc32004-03-31 19:00:16 +00006107 qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
6108 qemu_put_be32(f, QEMU_VM_FILE_VERSION);
bellardfaea38e2006-08-05 21:31:00 +00006109 total_len_pos = qemu_ftell(f);
6110 qemu_put_be64(f, 0); /* total size */
bellard8a7ddc32004-03-31 19:00:16 +00006111
6112 for(se = first_se; se != NULL; se = se->next) {
aurel32d978c022008-06-18 22:10:21 +00006113 if (se->save_state == NULL)
6114 /* this one has a loader only, for backwards compatibility */
6115 continue;
6116
bellard8a7ddc32004-03-31 19:00:16 +00006117 /* ID string */
6118 len = strlen(se->idstr);
6119 qemu_put_byte(f, len);
thsffe8ab82007-12-16 03:16:05 +00006120 qemu_put_buffer(f, (uint8_t *)se->idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006121
6122 qemu_put_be32(f, se->instance_id);
6123 qemu_put_be32(f, se->version_id);
6124
6125 /* record size: filled later */
bellardfaea38e2006-08-05 21:31:00 +00006126 len_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006127 qemu_put_be32(f, 0);
bellard8a7ddc32004-03-31 19:00:16 +00006128 se->save_state(f, se->opaque);
6129
6130 /* fill record size */
bellardfaea38e2006-08-05 21:31:00 +00006131 cur_pos = qemu_ftell(f);
6132 len = cur_pos - len_pos - 4;
6133 qemu_fseek(f, len_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006134 qemu_put_be32(f, len);
bellardfaea38e2006-08-05 21:31:00 +00006135 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006136 }
bellardfaea38e2006-08-05 21:31:00 +00006137 cur_pos = qemu_ftell(f);
6138 qemu_fseek(f, total_len_pos, SEEK_SET);
6139 qemu_put_be64(f, cur_pos - total_len_pos - 8);
6140 qemu_fseek(f, cur_pos, SEEK_SET);
bellard8a7ddc32004-03-31 19:00:16 +00006141
bellard8a7ddc32004-03-31 19:00:16 +00006142 ret = 0;
bellard8a7ddc32004-03-31 19:00:16 +00006143 return ret;
6144}
6145
6146static SaveStateEntry *find_se(const char *idstr, int instance_id)
6147{
6148 SaveStateEntry *se;
6149
6150 for(se = first_se; se != NULL; se = se->next) {
ths5fafdf22007-09-16 21:08:06 +00006151 if (!strcmp(se->idstr, idstr) &&
bellard8a7ddc32004-03-31 19:00:16 +00006152 instance_id == se->instance_id)
6153 return se;
6154 }
6155 return NULL;
6156}
6157
pbrook9596ebb2007-11-18 01:44:38 +00006158static int qemu_loadvm_state(QEMUFile *f)
bellard8a7ddc32004-03-31 19:00:16 +00006159{
6160 SaveStateEntry *se;
bellardfaea38e2006-08-05 21:31:00 +00006161 int len, ret, instance_id, record_len, version_id;
6162 int64_t total_len, end_pos, cur_pos;
bellard8a7ddc32004-03-31 19:00:16 +00006163 unsigned int v;
6164 char idstr[256];
ths3b46e622007-09-17 08:09:54 +00006165
bellard8a7ddc32004-03-31 19:00:16 +00006166 v = qemu_get_be32(f);
6167 if (v != QEMU_VM_FILE_MAGIC)
6168 goto fail;
6169 v = qemu_get_be32(f);
6170 if (v != QEMU_VM_FILE_VERSION) {
6171 fail:
bellard8a7ddc32004-03-31 19:00:16 +00006172 ret = -1;
6173 goto the_end;
6174 }
bellardfaea38e2006-08-05 21:31:00 +00006175 total_len = qemu_get_be64(f);
6176 end_pos = total_len + qemu_ftell(f);
bellardb4608c02003-06-27 17:34:32 +00006177 for(;;) {
bellardfaea38e2006-08-05 21:31:00 +00006178 if (qemu_ftell(f) >= end_pos)
bellard8a7ddc32004-03-31 19:00:16 +00006179 break;
bellardfaea38e2006-08-05 21:31:00 +00006180 len = qemu_get_byte(f);
thsffe8ab82007-12-16 03:16:05 +00006181 qemu_get_buffer(f, (uint8_t *)idstr, len);
bellard8a7ddc32004-03-31 19:00:16 +00006182 idstr[len] = '\0';
6183 instance_id = qemu_get_be32(f);
6184 version_id = qemu_get_be32(f);
6185 record_len = qemu_get_be32(f);
6186#if 0
ths5fafdf22007-09-16 21:08:06 +00006187 printf("idstr=%s instance=0x%x version=%d len=%d\n",
bellard8a7ddc32004-03-31 19:00:16 +00006188 idstr, instance_id, version_id, record_len);
bellardc45886d2004-01-05 00:02:06 +00006189#endif
bellardfaea38e2006-08-05 21:31:00 +00006190 cur_pos = qemu_ftell(f);
bellard8a7ddc32004-03-31 19:00:16 +00006191 se = find_se(idstr, instance_id);
6192 if (!se) {
ths5fafdf22007-09-16 21:08:06 +00006193 fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
bellard8a7ddc32004-03-31 19:00:16 +00006194 instance_id, idstr);
6195 } else {
6196 ret = se->load_state(f, se->opaque, version_id);
6197 if (ret < 0) {
ths5fafdf22007-09-16 21:08:06 +00006198 fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
bellard8a7ddc32004-03-31 19:00:16 +00006199 instance_id, idstr);
6200 }
bellard34865132003-10-05 14:28:56 +00006201 }
bellard8a7ddc32004-03-31 19:00:16 +00006202 /* always seek to exact end of record */
6203 qemu_fseek(f, cur_pos + record_len, SEEK_SET);
6204 }
bellard8a7ddc32004-03-31 19:00:16 +00006205 ret = 0;
6206 the_end:
bellardfaea38e2006-08-05 21:31:00 +00006207 return ret;
6208}
6209
6210/* device can contain snapshots */
6211static int bdrv_can_snapshot(BlockDriverState *bs)
6212{
6213 return (bs &&
6214 !bdrv_is_removable(bs) &&
6215 !bdrv_is_read_only(bs));
6216}
6217
6218/* device must be snapshots in order to have a reliable snapshot */
6219static int bdrv_has_snapshot(BlockDriverState *bs)
6220{
6221 return (bs &&
6222 !bdrv_is_removable(bs) &&
6223 !bdrv_is_read_only(bs));
6224}
6225
6226static BlockDriverState *get_bs_snapshots(void)
6227{
6228 BlockDriverState *bs;
6229 int i;
6230
6231 if (bs_snapshots)
6232 return bs_snapshots;
thse4bcb142007-12-02 04:51:10 +00006233 for(i = 0; i <= nb_drives; i++) {
6234 bs = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006235 if (bdrv_can_snapshot(bs))
6236 goto ok;
6237 }
6238 return NULL;
6239 ok:
6240 bs_snapshots = bs;
6241 return bs;
6242}
6243
6244static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
6245 const char *name)
6246{
6247 QEMUSnapshotInfo *sn_tab, *sn;
6248 int nb_sns, i, ret;
ths3b46e622007-09-17 08:09:54 +00006249
bellardfaea38e2006-08-05 21:31:00 +00006250 ret = -ENOENT;
6251 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6252 if (nb_sns < 0)
6253 return ret;
6254 for(i = 0; i < nb_sns; i++) {
6255 sn = &sn_tab[i];
6256 if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
6257 *sn_info = *sn;
6258 ret = 0;
6259 break;
6260 }
6261 }
6262 qemu_free(sn_tab);
6263 return ret;
6264}
6265
6266void do_savevm(const char *name)
6267{
6268 BlockDriverState *bs, *bs1;
6269 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
6270 int must_delete, ret, i;
6271 BlockDriverInfo bdi1, *bdi = &bdi1;
6272 QEMUFile *f;
6273 int saved_vm_running;
bellard4c279bd2006-08-17 09:43:50 +00006274#ifdef _WIN32
6275 struct _timeb tb;
6276#else
bellardfaea38e2006-08-05 21:31:00 +00006277 struct timeval tv;
bellard4c279bd2006-08-17 09:43:50 +00006278#endif
bellardfaea38e2006-08-05 21:31:00 +00006279
6280 bs = get_bs_snapshots();
6281 if (!bs) {
6282 term_printf("No block device can accept snapshots\n");
6283 return;
6284 }
6285
pbrook6192bc32006-09-03 12:08:37 +00006286 /* ??? Should this occur after vm_stop? */
6287 qemu_aio_flush();
6288
bellardfaea38e2006-08-05 21:31:00 +00006289 saved_vm_running = vm_running;
6290 vm_stop(0);
ths3b46e622007-09-17 08:09:54 +00006291
bellardfaea38e2006-08-05 21:31:00 +00006292 must_delete = 0;
6293 if (name) {
6294 ret = bdrv_snapshot_find(bs, old_sn, name);
6295 if (ret >= 0) {
6296 must_delete = 1;
6297 }
6298 }
6299 memset(sn, 0, sizeof(*sn));
6300 if (must_delete) {
6301 pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
6302 pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
6303 } else {
6304 if (name)
6305 pstrcpy(sn->name, sizeof(sn->name), name);
6306 }
6307
6308 /* fill auxiliary fields */
bellard4c279bd2006-08-17 09:43:50 +00006309#ifdef _WIN32
6310 _ftime(&tb);
6311 sn->date_sec = tb.time;
6312 sn->date_nsec = tb.millitm * 1000000;
6313#else
bellardfaea38e2006-08-05 21:31:00 +00006314 gettimeofday(&tv, NULL);
6315 sn->date_sec = tv.tv_sec;
6316 sn->date_nsec = tv.tv_usec * 1000;
bellard4c279bd2006-08-17 09:43:50 +00006317#endif
bellardfaea38e2006-08-05 21:31:00 +00006318 sn->vm_clock_nsec = qemu_get_clock(vm_clock);
ths3b46e622007-09-17 08:09:54 +00006319
bellardfaea38e2006-08-05 21:31:00 +00006320 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6321 term_printf("Device %s does not support VM state snapshots\n",
6322 bdrv_get_device_name(bs));
6323 goto the_end;
6324 }
ths3b46e622007-09-17 08:09:54 +00006325
bellardfaea38e2006-08-05 21:31:00 +00006326 /* save the VM state */
6327 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
6328 if (!f) {
6329 term_printf("Could not open VM state file\n");
6330 goto the_end;
6331 }
6332 ret = qemu_savevm_state(f);
6333 sn->vm_state_size = qemu_ftell(f);
6334 qemu_fclose(f);
6335 if (ret < 0) {
6336 term_printf("Error %d while writing VM\n", ret);
6337 goto the_end;
6338 }
ths3b46e622007-09-17 08:09:54 +00006339
bellardfaea38e2006-08-05 21:31:00 +00006340 /* create the snapshots */
6341
thse4bcb142007-12-02 04:51:10 +00006342 for(i = 0; i < nb_drives; i++) {
6343 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006344 if (bdrv_has_snapshot(bs1)) {
6345 if (must_delete) {
6346 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
6347 if (ret < 0) {
6348 term_printf("Error while deleting snapshot on '%s'\n",
6349 bdrv_get_device_name(bs1));
6350 }
6351 }
6352 ret = bdrv_snapshot_create(bs1, sn);
6353 if (ret < 0) {
6354 term_printf("Error while creating snapshot on '%s'\n",
6355 bdrv_get_device_name(bs1));
6356 }
6357 }
6358 }
6359
6360 the_end:
bellard8a7ddc32004-03-31 19:00:16 +00006361 if (saved_vm_running)
6362 vm_start();
bellardfaea38e2006-08-05 21:31:00 +00006363}
6364
6365void do_loadvm(const char *name)
6366{
6367 BlockDriverState *bs, *bs1;
6368 BlockDriverInfo bdi1, *bdi = &bdi1;
6369 QEMUFile *f;
6370 int i, ret;
6371 int saved_vm_running;
6372
6373 bs = get_bs_snapshots();
6374 if (!bs) {
6375 term_printf("No block device supports snapshots\n");
6376 return;
6377 }
ths3b46e622007-09-17 08:09:54 +00006378
pbrook6192bc32006-09-03 12:08:37 +00006379 /* Flush all IO requests so they don't interfere with the new state. */
6380 qemu_aio_flush();
6381
bellardfaea38e2006-08-05 21:31:00 +00006382 saved_vm_running = vm_running;
6383 vm_stop(0);
6384
thse4bcb142007-12-02 04:51:10 +00006385 for(i = 0; i <= nb_drives; i++) {
6386 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006387 if (bdrv_has_snapshot(bs1)) {
6388 ret = bdrv_snapshot_goto(bs1, name);
6389 if (ret < 0) {
6390 if (bs != bs1)
6391 term_printf("Warning: ");
6392 switch(ret) {
6393 case -ENOTSUP:
6394 term_printf("Snapshots not supported on device '%s'\n",
6395 bdrv_get_device_name(bs1));
6396 break;
6397 case -ENOENT:
6398 term_printf("Could not find snapshot '%s' on device '%s'\n",
6399 name, bdrv_get_device_name(bs1));
6400 break;
6401 default:
6402 term_printf("Error %d while activating snapshot on '%s'\n",
6403 ret, bdrv_get_device_name(bs1));
6404 break;
6405 }
6406 /* fatal on snapshot block device */
6407 if (bs == bs1)
6408 goto the_end;
6409 }
6410 }
6411 }
6412
6413 if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6414 term_printf("Device %s does not support VM state snapshots\n",
6415 bdrv_get_device_name(bs));
6416 return;
6417 }
ths3b46e622007-09-17 08:09:54 +00006418
bellardfaea38e2006-08-05 21:31:00 +00006419 /* restore the VM state */
6420 f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
6421 if (!f) {
6422 term_printf("Could not open VM state file\n");
6423 goto the_end;
6424 }
6425 ret = qemu_loadvm_state(f);
6426 qemu_fclose(f);
6427 if (ret < 0) {
6428 term_printf("Error %d while loading VM state\n", ret);
6429 }
6430 the_end:
6431 if (saved_vm_running)
6432 vm_start();
6433}
6434
6435void do_delvm(const char *name)
6436{
6437 BlockDriverState *bs, *bs1;
6438 int i, ret;
6439
6440 bs = get_bs_snapshots();
6441 if (!bs) {
6442 term_printf("No block device supports snapshots\n");
6443 return;
6444 }
ths3b46e622007-09-17 08:09:54 +00006445
thse4bcb142007-12-02 04:51:10 +00006446 for(i = 0; i <= nb_drives; i++) {
6447 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006448 if (bdrv_has_snapshot(bs1)) {
6449 ret = bdrv_snapshot_delete(bs1, name);
6450 if (ret < 0) {
6451 if (ret == -ENOTSUP)
6452 term_printf("Snapshots not supported on device '%s'\n",
6453 bdrv_get_device_name(bs1));
6454 else
6455 term_printf("Error %d while deleting snapshot on '%s'\n",
6456 ret, bdrv_get_device_name(bs1));
6457 }
6458 }
6459 }
6460}
6461
6462void do_info_snapshots(void)
6463{
6464 BlockDriverState *bs, *bs1;
6465 QEMUSnapshotInfo *sn_tab, *sn;
6466 int nb_sns, i;
6467 char buf[256];
6468
6469 bs = get_bs_snapshots();
6470 if (!bs) {
6471 term_printf("No available block device supports snapshots\n");
6472 return;
6473 }
6474 term_printf("Snapshot devices:");
thse4bcb142007-12-02 04:51:10 +00006475 for(i = 0; i <= nb_drives; i++) {
6476 bs1 = drives_table[i].bdrv;
bellardfaea38e2006-08-05 21:31:00 +00006477 if (bdrv_has_snapshot(bs1)) {
6478 if (bs == bs1)
6479 term_printf(" %s", bdrv_get_device_name(bs1));
6480 }
6481 }
6482 term_printf("\n");
6483
6484 nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6485 if (nb_sns < 0) {
6486 term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
6487 return;
6488 }
6489 term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
6490 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
6491 for(i = 0; i < nb_sns; i++) {
6492 sn = &sn_tab[i];
6493 term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
6494 }
6495 qemu_free(sn_tab);
bellard8a7ddc32004-03-31 19:00:16 +00006496}
6497
6498/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006499/* ram save/restore */
6500
bellard8a7ddc32004-03-31 19:00:16 +00006501static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6502{
6503 int v;
6504
6505 v = qemu_get_byte(f);
6506 switch(v) {
6507 case 0:
6508 if (qemu_get_buffer(f, buf, len) != len)
6509 return -EIO;
6510 break;
6511 case 1:
6512 v = qemu_get_byte(f);
6513 memset(buf, v, len);
6514 break;
6515 default:
6516 return -EINVAL;
6517 }
6518 return 0;
6519}
6520
bellardc88676f2006-08-06 13:36:11 +00006521static int ram_load_v1(QEMUFile *f, void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00006522{
aurel3200f82b82008-04-27 21:12:55 +00006523 int ret;
6524 ram_addr_t i;
bellard8a7ddc32004-03-31 19:00:16 +00006525
bellard8a7ddc32004-03-31 19:00:16 +00006526 if (qemu_get_be32(f) != phys_ram_size)
6527 return -EINVAL;
6528 for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6529 ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6530 if (ret)
6531 return ret;
6532 }
6533 return 0;
6534}
6535
bellardc88676f2006-08-06 13:36:11 +00006536#define BDRV_HASH_BLOCK_SIZE 1024
6537#define IOBUF_SIZE 4096
6538#define RAM_CBLOCK_MAGIC 0xfabe
6539
6540typedef struct RamCompressState {
6541 z_stream zstream;
6542 QEMUFile *f;
6543 uint8_t buf[IOBUF_SIZE];
6544} RamCompressState;
6545
6546static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6547{
6548 int ret;
6549 memset(s, 0, sizeof(*s));
6550 s->f = f;
6551 ret = deflateInit2(&s->zstream, 1,
ths5fafdf22007-09-16 21:08:06 +00006552 Z_DEFLATED, 15,
bellardc88676f2006-08-06 13:36:11 +00006553 9, Z_DEFAULT_STRATEGY);
6554 if (ret != Z_OK)
6555 return -1;
6556 s->zstream.avail_out = IOBUF_SIZE;
6557 s->zstream.next_out = s->buf;
6558 return 0;
6559}
6560
6561static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6562{
6563 qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6564 qemu_put_be16(s->f, len);
6565 qemu_put_buffer(s->f, buf, len);
6566}
6567
6568static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6569{
6570 int ret;
6571
6572 s->zstream.avail_in = len;
6573 s->zstream.next_in = (uint8_t *)buf;
6574 while (s->zstream.avail_in > 0) {
6575 ret = deflate(&s->zstream, Z_NO_FLUSH);
6576 if (ret != Z_OK)
6577 return -1;
6578 if (s->zstream.avail_out == 0) {
6579 ram_put_cblock(s, s->buf, IOBUF_SIZE);
6580 s->zstream.avail_out = IOBUF_SIZE;
6581 s->zstream.next_out = s->buf;
6582 }
6583 }
6584 return 0;
6585}
6586
6587static void ram_compress_close(RamCompressState *s)
6588{
6589 int len, ret;
6590
6591 /* compress last bytes */
6592 for(;;) {
6593 ret = deflate(&s->zstream, Z_FINISH);
6594 if (ret == Z_OK || ret == Z_STREAM_END) {
6595 len = IOBUF_SIZE - s->zstream.avail_out;
6596 if (len > 0) {
6597 ram_put_cblock(s, s->buf, len);
6598 }
6599 s->zstream.avail_out = IOBUF_SIZE;
6600 s->zstream.next_out = s->buf;
6601 if (ret == Z_STREAM_END)
6602 break;
6603 } else {
6604 goto fail;
6605 }
6606 }
6607fail:
6608 deflateEnd(&s->zstream);
6609}
6610
6611typedef struct RamDecompressState {
6612 z_stream zstream;
6613 QEMUFile *f;
6614 uint8_t buf[IOBUF_SIZE];
6615} RamDecompressState;
6616
6617static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6618{
6619 int ret;
6620 memset(s, 0, sizeof(*s));
6621 s->f = f;
6622 ret = inflateInit(&s->zstream);
6623 if (ret != Z_OK)
6624 return -1;
6625 return 0;
6626}
6627
6628static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6629{
6630 int ret, clen;
6631
6632 s->zstream.avail_out = len;
6633 s->zstream.next_out = buf;
6634 while (s->zstream.avail_out > 0) {
6635 if (s->zstream.avail_in == 0) {
6636 if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6637 return -1;
6638 clen = qemu_get_be16(s->f);
6639 if (clen > IOBUF_SIZE)
6640 return -1;
6641 qemu_get_buffer(s->f, s->buf, clen);
6642 s->zstream.avail_in = clen;
6643 s->zstream.next_in = s->buf;
6644 }
6645 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6646 if (ret != Z_OK && ret != Z_STREAM_END) {
6647 return -1;
6648 }
6649 }
6650 return 0;
6651}
6652
6653static void ram_decompress_close(RamDecompressState *s)
6654{
6655 inflateEnd(&s->zstream);
6656}
6657
6658static void ram_save(QEMUFile *f, void *opaque)
6659{
aurel3200f82b82008-04-27 21:12:55 +00006660 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00006661 RamCompressState s1, *s = &s1;
6662 uint8_t buf[10];
ths3b46e622007-09-17 08:09:54 +00006663
bellardc88676f2006-08-06 13:36:11 +00006664 qemu_put_be32(f, phys_ram_size);
6665 if (ram_compress_open(s, f) < 0)
6666 return;
6667 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6668#if 0
6669 if (tight_savevm_enabled) {
6670 int64_t sector_num;
6671 int j;
6672
6673 /* find if the memory block is available on a virtual
6674 block device */
6675 sector_num = -1;
thse4bcb142007-12-02 04:51:10 +00006676 for(j = 0; j < nb_drives; j++) {
6677 sector_num = bdrv_hash_find(drives_table[j].bdrv,
6678 phys_ram_base + i,
6679 BDRV_HASH_BLOCK_SIZE);
6680 if (sector_num >= 0)
6681 break;
bellardc88676f2006-08-06 13:36:11 +00006682 }
thse4bcb142007-12-02 04:51:10 +00006683 if (j == nb_drives)
bellardc88676f2006-08-06 13:36:11 +00006684 goto normal_compress;
6685 buf[0] = 1;
6686 buf[1] = j;
6687 cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
6688 ram_compress_buf(s, buf, 10);
ths5fafdf22007-09-16 21:08:06 +00006689 } else
bellardc88676f2006-08-06 13:36:11 +00006690#endif
6691 {
6692 // normal_compress:
6693 buf[0] = 0;
6694 ram_compress_buf(s, buf, 1);
6695 ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6696 }
6697 }
6698 ram_compress_close(s);
6699}
6700
6701static int ram_load(QEMUFile *f, void *opaque, int version_id)
6702{
6703 RamDecompressState s1, *s = &s1;
6704 uint8_t buf[10];
aurel3200f82b82008-04-27 21:12:55 +00006705 ram_addr_t i;
bellardc88676f2006-08-06 13:36:11 +00006706
6707 if (version_id == 1)
6708 return ram_load_v1(f, opaque);
6709 if (version_id != 2)
6710 return -EINVAL;
6711 if (qemu_get_be32(f) != phys_ram_size)
6712 return -EINVAL;
6713 if (ram_decompress_open(s, f) < 0)
6714 return -EINVAL;
6715 for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6716 if (ram_decompress_buf(s, buf, 1) < 0) {
6717 fprintf(stderr, "Error while reading ram block header\n");
6718 goto error;
6719 }
6720 if (buf[0] == 0) {
6721 if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
aurel3200f82b82008-04-27 21:12:55 +00006722 fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
bellardc88676f2006-08-06 13:36:11 +00006723 goto error;
6724 }
ths5fafdf22007-09-16 21:08:06 +00006725 } else
bellardc88676f2006-08-06 13:36:11 +00006726#if 0
6727 if (buf[0] == 1) {
6728 int bs_index;
6729 int64_t sector_num;
6730
6731 ram_decompress_buf(s, buf + 1, 9);
6732 bs_index = buf[1];
6733 sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
thse4bcb142007-12-02 04:51:10 +00006734 if (bs_index >= nb_drives) {
bellardc88676f2006-08-06 13:36:11 +00006735 fprintf(stderr, "Invalid block device index %d\n", bs_index);
6736 goto error;
6737 }
thse4bcb142007-12-02 04:51:10 +00006738 if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
6739 phys_ram_base + i,
bellardc88676f2006-08-06 13:36:11 +00006740 BDRV_HASH_BLOCK_SIZE / 512) < 0) {
ths5fafdf22007-09-16 21:08:06 +00006741 fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
bellardc88676f2006-08-06 13:36:11 +00006742 bs_index, sector_num);
6743 goto error;
6744 }
ths5fafdf22007-09-16 21:08:06 +00006745 } else
bellardc88676f2006-08-06 13:36:11 +00006746#endif
6747 {
6748 error:
6749 printf("Error block header\n");
6750 return -EINVAL;
6751 }
6752 }
6753 ram_decompress_close(s);
6754 return 0;
6755}
6756
bellard8a7ddc32004-03-31 19:00:16 +00006757/***********************************************************/
bellard83f64092006-08-01 16:21:11 +00006758/* bottom halves (can be seen as timers which expire ASAP) */
6759
6760struct QEMUBH {
6761 QEMUBHFunc *cb;
6762 void *opaque;
6763 int scheduled;
6764 QEMUBH *next;
6765};
6766
6767static QEMUBH *first_bh = NULL;
6768
6769QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
6770{
6771 QEMUBH *bh;
6772 bh = qemu_mallocz(sizeof(QEMUBH));
6773 if (!bh)
6774 return NULL;
6775 bh->cb = cb;
6776 bh->opaque = opaque;
6777 return bh;
6778}
6779
bellard6eb57332006-08-06 09:51:25 +00006780int qemu_bh_poll(void)
bellard83f64092006-08-01 16:21:11 +00006781{
6782 QEMUBH *bh, **pbh;
bellard6eb57332006-08-06 09:51:25 +00006783 int ret;
bellard83f64092006-08-01 16:21:11 +00006784
bellard6eb57332006-08-06 09:51:25 +00006785 ret = 0;
bellard83f64092006-08-01 16:21:11 +00006786 for(;;) {
6787 pbh = &first_bh;
6788 bh = *pbh;
6789 if (!bh)
6790 break;
bellard6eb57332006-08-06 09:51:25 +00006791 ret = 1;
bellard83f64092006-08-01 16:21:11 +00006792 *pbh = bh->next;
6793 bh->scheduled = 0;
6794 bh->cb(bh->opaque);
6795 }
bellard6eb57332006-08-06 09:51:25 +00006796 return ret;
bellard83f64092006-08-01 16:21:11 +00006797}
6798
6799void qemu_bh_schedule(QEMUBH *bh)
6800{
6801 CPUState *env = cpu_single_env;
6802 if (bh->scheduled)
6803 return;
6804 bh->scheduled = 1;
6805 bh->next = first_bh;
6806 first_bh = bh;
6807
6808 /* stop the currently executing CPU to execute the BH ASAP */
6809 if (env) {
6810 cpu_interrupt(env, CPU_INTERRUPT_EXIT);
6811 }
6812}
6813
6814void qemu_bh_cancel(QEMUBH *bh)
6815{
6816 QEMUBH **pbh;
6817 if (bh->scheduled) {
6818 pbh = &first_bh;
6819 while (*pbh != bh)
6820 pbh = &(*pbh)->next;
6821 *pbh = bh->next;
6822 bh->scheduled = 0;
6823 }
6824}
6825
6826void qemu_bh_delete(QEMUBH *bh)
6827{
6828 qemu_bh_cancel(bh);
6829 qemu_free(bh);
6830}
6831
6832/***********************************************************/
bellardcc1daa42005-06-05 14:49:17 +00006833/* machine registration */
6834
6835QEMUMachine *first_machine = NULL;
6836
6837int qemu_register_machine(QEMUMachine *m)
6838{
6839 QEMUMachine **pm;
6840 pm = &first_machine;
6841 while (*pm != NULL)
6842 pm = &(*pm)->next;
6843 m->next = NULL;
6844 *pm = m;
6845 return 0;
6846}
6847
pbrook9596ebb2007-11-18 01:44:38 +00006848static QEMUMachine *find_machine(const char *name)
bellardcc1daa42005-06-05 14:49:17 +00006849{
6850 QEMUMachine *m;
6851
6852 for(m = first_machine; m != NULL; m = m->next) {
6853 if (!strcmp(m->name, name))
6854 return m;
6855 }
6856 return NULL;
6857}
6858
6859/***********************************************************/
bellard8a7ddc32004-03-31 19:00:16 +00006860/* main execution loop */
6861
pbrook9596ebb2007-11-18 01:44:38 +00006862static void gui_update(void *opaque)
bellard8a7ddc32004-03-31 19:00:16 +00006863{
ths740733b2007-06-08 01:57:56 +00006864 DisplayState *ds = opaque;
6865 ds->dpy_refresh(ds);
aurel32f442e082008-03-13 19:20:33 +00006866 qemu_mod_timer(ds->gui_timer,
6867 (ds->gui_timer_interval ?
6868 ds->gui_timer_interval :
6869 GUI_REFRESH_INTERVAL)
6870 + qemu_get_clock(rt_clock));
bellard8a7ddc32004-03-31 19:00:16 +00006871}
6872
bellard0bd48852005-11-11 00:00:47 +00006873struct vm_change_state_entry {
6874 VMChangeStateHandler *cb;
6875 void *opaque;
6876 LIST_ENTRY (vm_change_state_entry) entries;
6877};
6878
6879static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
6880
6881VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
6882 void *opaque)
6883{
6884 VMChangeStateEntry *e;
6885
6886 e = qemu_mallocz(sizeof (*e));
6887 if (!e)
6888 return NULL;
6889
6890 e->cb = cb;
6891 e->opaque = opaque;
6892 LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
6893 return e;
6894}
6895
6896void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
6897{
6898 LIST_REMOVE (e, entries);
6899 qemu_free (e);
6900}
6901
6902static void vm_state_notify(int running)
6903{
6904 VMChangeStateEntry *e;
6905
6906 for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
6907 e->cb(e->opaque, running);
6908 }
6909}
6910
bellard8a7ddc32004-03-31 19:00:16 +00006911/* XXX: support several handlers */
bellard0bd48852005-11-11 00:00:47 +00006912static VMStopHandler *vm_stop_cb;
6913static void *vm_stop_opaque;
bellard8a7ddc32004-03-31 19:00:16 +00006914
6915int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
6916{
6917 vm_stop_cb = cb;
6918 vm_stop_opaque = opaque;
6919 return 0;
6920}
6921
6922void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
6923{
6924 vm_stop_cb = NULL;
6925}
6926
6927void vm_start(void)
6928{
6929 if (!vm_running) {
6930 cpu_enable_ticks();
6931 vm_running = 1;
bellard0bd48852005-11-11 00:00:47 +00006932 vm_state_notify(1);
thsefe75412007-08-24 01:36:32 +00006933 qemu_rearm_alarm_timer(alarm_timer);
bellard8a7ddc32004-03-31 19:00:16 +00006934 }
6935}
6936
ths5fafdf22007-09-16 21:08:06 +00006937void vm_stop(int reason)
bellard8a7ddc32004-03-31 19:00:16 +00006938{
6939 if (vm_running) {
6940 cpu_disable_ticks();
6941 vm_running = 0;
6942 if (reason != 0) {
6943 if (vm_stop_cb) {
6944 vm_stop_cb(vm_stop_opaque, reason);
6945 }
6946 }
bellard0bd48852005-11-11 00:00:47 +00006947 vm_state_notify(0);
bellard8a7ddc32004-03-31 19:00:16 +00006948 }
6949}
6950
bellardbb0c6722004-06-20 12:37:32 +00006951/* reset/shutdown handler */
6952
6953typedef struct QEMUResetEntry {
6954 QEMUResetHandler *func;
6955 void *opaque;
6956 struct QEMUResetEntry *next;
6957} QEMUResetEntry;
6958
6959static QEMUResetEntry *first_reset_entry;
6960static int reset_requested;
6961static int shutdown_requested;
bellard34751872005-07-02 14:31:34 +00006962static int powerdown_requested;
bellardbb0c6722004-06-20 12:37:32 +00006963
aurel32cf7a2fe2008-03-18 06:53:05 +00006964int qemu_shutdown_requested(void)
6965{
6966 int r = shutdown_requested;
6967 shutdown_requested = 0;
6968 return r;
6969}
6970
6971int qemu_reset_requested(void)
6972{
6973 int r = reset_requested;
6974 reset_requested = 0;
6975 return r;
6976}
6977
6978int qemu_powerdown_requested(void)
6979{
6980 int r = powerdown_requested;
6981 powerdown_requested = 0;
6982 return r;
6983}
6984
bellardbb0c6722004-06-20 12:37:32 +00006985void qemu_register_reset(QEMUResetHandler *func, void *opaque)
6986{
6987 QEMUResetEntry **pre, *re;
6988
6989 pre = &first_reset_entry;
6990 while (*pre != NULL)
6991 pre = &(*pre)->next;
6992 re = qemu_mallocz(sizeof(QEMUResetEntry));
6993 re->func = func;
6994 re->opaque = opaque;
6995 re->next = NULL;
6996 *pre = re;
6997}
6998
aurel32cf7a2fe2008-03-18 06:53:05 +00006999void qemu_system_reset(void)
bellardbb0c6722004-06-20 12:37:32 +00007000{
7001 QEMUResetEntry *re;
7002
7003 /* reset all devices */
7004 for(re = first_reset_entry; re != NULL; re = re->next) {
7005 re->func(re->opaque);
7006 }
7007}
7008
7009void qemu_system_reset_request(void)
7010{
bellardd1beab82006-10-02 19:44:22 +00007011 if (no_reboot) {
7012 shutdown_requested = 1;
7013 } else {
7014 reset_requested = 1;
7015 }
bellard6a00d602005-11-21 23:25:50 +00007016 if (cpu_single_env)
7017 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007018}
7019
7020void qemu_system_shutdown_request(void)
7021{
7022 shutdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007023 if (cpu_single_env)
7024 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007025}
7026
bellard34751872005-07-02 14:31:34 +00007027void qemu_system_powerdown_request(void)
7028{
7029 powerdown_requested = 1;
bellard6a00d602005-11-21 23:25:50 +00007030 if (cpu_single_env)
7031 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
bellardbb0c6722004-06-20 12:37:32 +00007032}
7033
bellard5905b2e2004-08-01 21:53:26 +00007034void main_loop_wait(int timeout)
bellard8a7ddc32004-03-31 19:00:16 +00007035{
thscafffd42007-02-28 21:59:44 +00007036 IOHandlerRecord *ioh;
bellarde0356492006-05-01 13:33:02 +00007037 fd_set rfds, wfds, xfds;
ths877cf882007-04-18 18:11:47 +00007038 int ret, nfds;
7039#ifdef _WIN32
7040 int ret2, i;
7041#endif
bellardfd1dff42006-02-01 21:29:26 +00007042 struct timeval tv;
bellardf3311102006-04-12 20:21:17 +00007043 PollingEntry *pe;
bellardc4b1fcc2004-03-14 21:44:30 +00007044
bellardf3311102006-04-12 20:21:17 +00007045
7046 /* XXX: need to suppress polling by better using win32 events */
7047 ret = 0;
7048 for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
7049 ret |= pe->func(pe->opaque);
7050 }
bellard38e205a2004-04-06 19:29:17 +00007051#ifdef _WIN32
thse6b1e552007-04-18 17:56:02 +00007052 if (ret == 0) {
bellarda18e5242006-06-25 17:18:27 +00007053 int err;
7054 WaitObjects *w = &wait_objects;
ths3b46e622007-09-17 08:09:54 +00007055
bellarda18e5242006-06-25 17:18:27 +00007056 ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
7057 if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
7058 if (w->func[ret - WAIT_OBJECT_0])
7059 w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
ths3b46e622007-09-17 08:09:54 +00007060
ths5fafdf22007-09-16 21:08:06 +00007061 /* Check for additional signaled events */
thse6b1e552007-04-18 17:56:02 +00007062 for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
ths3b46e622007-09-17 08:09:54 +00007063
thse6b1e552007-04-18 17:56:02 +00007064 /* Check if event is signaled */
7065 ret2 = WaitForSingleObject(w->events[i], 0);
7066 if(ret2 == WAIT_OBJECT_0) {
7067 if (w->func[i])
7068 w->func[i](w->opaque[i]);
7069 } else if (ret2 == WAIT_TIMEOUT) {
7070 } else {
7071 err = GetLastError();
7072 fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
ths3b46e622007-09-17 08:09:54 +00007073 }
7074 }
bellarda18e5242006-06-25 17:18:27 +00007075 } else if (ret == WAIT_TIMEOUT) {
7076 } else {
7077 err = GetLastError();
thse6b1e552007-04-18 17:56:02 +00007078 fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
bellarda18e5242006-06-25 17:18:27 +00007079 }
bellardf3311102006-04-12 20:21:17 +00007080 }
bellardfd1dff42006-02-01 21:29:26 +00007081#endif
7082 /* poll any events */
7083 /* XXX: separate device handlers from system ones */
7084 nfds = -1;
7085 FD_ZERO(&rfds);
7086 FD_ZERO(&wfds);
bellarde0356492006-05-01 13:33:02 +00007087 FD_ZERO(&xfds);
bellardfd1dff42006-02-01 21:29:26 +00007088 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
thscafffd42007-02-28 21:59:44 +00007089 if (ioh->deleted)
7090 continue;
bellardfd1dff42006-02-01 21:29:26 +00007091 if (ioh->fd_read &&
7092 (!ioh->fd_read_poll ||
7093 ioh->fd_read_poll(ioh->opaque) != 0)) {
7094 FD_SET(ioh->fd, &rfds);
7095 if (ioh->fd > nfds)
7096 nfds = ioh->fd;
7097 }
7098 if (ioh->fd_write) {
7099 FD_SET(ioh->fd, &wfds);
7100 if (ioh->fd > nfds)
7101 nfds = ioh->fd;
7102 }
7103 }
ths3b46e622007-09-17 08:09:54 +00007104
bellardfd1dff42006-02-01 21:29:26 +00007105 tv.tv_sec = 0;
7106#ifdef _WIN32
7107 tv.tv_usec = 0;
bellard38e205a2004-04-06 19:29:17 +00007108#else
bellardfd1dff42006-02-01 21:29:26 +00007109 tv.tv_usec = timeout * 1000;
7110#endif
bellarde0356492006-05-01 13:33:02 +00007111#if defined(CONFIG_SLIRP)
7112 if (slirp_inited) {
7113 slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
7114 }
7115#endif
7116 ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
bellardfd1dff42006-02-01 21:29:26 +00007117 if (ret > 0) {
thscafffd42007-02-28 21:59:44 +00007118 IOHandlerRecord **pioh;
7119
7120 for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
ths6ab43fd2007-08-25 01:34:19 +00007121 if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007122 ioh->fd_read(ioh->opaque);
bellardc4b1fcc2004-03-14 21:44:30 +00007123 }
ths6ab43fd2007-08-25 01:34:19 +00007124 if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
bellardfd1dff42006-02-01 21:29:26 +00007125 ioh->fd_write(ioh->opaque);
bellardb4608c02003-06-27 17:34:32 +00007126 }
7127 }
thscafffd42007-02-28 21:59:44 +00007128
7129 /* remove deleted IO handlers */
7130 pioh = &first_io_handler;
7131 while (*pioh) {
7132 ioh = *pioh;
7133 if (ioh->deleted) {
7134 *pioh = ioh->next;
7135 qemu_free(ioh);
ths5fafdf22007-09-16 21:08:06 +00007136 } else
thscafffd42007-02-28 21:59:44 +00007137 pioh = &ioh->next;
7138 }
bellardfd1dff42006-02-01 21:29:26 +00007139 }
bellarde0356492006-05-01 13:33:02 +00007140#if defined(CONFIG_SLIRP)
7141 if (slirp_inited) {
7142 if (ret < 0) {
7143 FD_ZERO(&rfds);
7144 FD_ZERO(&wfds);
7145 FD_ZERO(&xfds);
7146 }
7147 slirp_select_poll(&rfds, &wfds, &xfds);
7148 }
7149#endif
bellard83f64092006-08-01 16:21:11 +00007150 qemu_aio_poll();
bellardc20709a2004-04-21 23:27:19 +00007151
bellardfd1dff42006-02-01 21:29:26 +00007152 if (vm_running) {
edgar_igl21b20812008-05-15 19:54:00 +00007153 if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
ths5fafdf22007-09-16 21:08:06 +00007154 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
bellardfd1dff42006-02-01 21:29:26 +00007155 qemu_get_clock(vm_clock));
7156 /* run dma transfers, if any */
7157 DMA_run();
7158 }
pbrook423f0742007-05-23 00:06:54 +00007159
bellardfd1dff42006-02-01 21:29:26 +00007160 /* real time timers */
ths5fafdf22007-09-16 21:08:06 +00007161 qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
bellardfd1dff42006-02-01 21:29:26 +00007162 qemu_get_clock(rt_clock));
pbrook423f0742007-05-23 00:06:54 +00007163
balrogd5d08332008-01-05 19:41:47 +00007164 if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
7165 alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED);
7166 qemu_rearm_alarm_timer(alarm_timer);
7167 }
balrogb99dc0d2007-12-16 13:17:12 +00007168
pbrook423f0742007-05-23 00:06:54 +00007169 /* Check bottom-halves last in case any of the earlier events triggered
7170 them. */
7171 qemu_bh_poll();
ths3b46e622007-09-17 08:09:54 +00007172
bellard5905b2e2004-08-01 21:53:26 +00007173}
7174
pbrook9596ebb2007-11-18 01:44:38 +00007175static int main_loop(void)
bellard5905b2e2004-08-01 21:53:26 +00007176{
7177 int ret, timeout;
bellard89bfc102006-02-08 22:46:31 +00007178#ifdef CONFIG_PROFILER
7179 int64_t ti;
7180#endif
bellard6a00d602005-11-21 23:25:50 +00007181 CPUState *env;
bellard5905b2e2004-08-01 21:53:26 +00007182
bellard6a00d602005-11-21 23:25:50 +00007183 cur_cpu = first_cpu;
balrogee5605e2007-12-03 03:01:40 +00007184 next_cpu = cur_cpu->next_cpu ?: first_cpu;
bellard5905b2e2004-08-01 21:53:26 +00007185 for(;;) {
7186 if (vm_running) {
bellard15a76442005-11-23 21:01:03 +00007187
bellard15a76442005-11-23 21:01:03 +00007188 for(;;) {
7189 /* get next cpu */
balrogee5605e2007-12-03 03:01:40 +00007190 env = next_cpu;
bellard89bfc102006-02-08 22:46:31 +00007191#ifdef CONFIG_PROFILER
7192 ti = profile_getclock();
7193#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007194 if (use_icount) {
7195 int64_t count;
7196 int decr;
7197 qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
7198 env->icount_decr.u16.low = 0;
7199 env->icount_extra = 0;
7200 count = qemu_next_deadline();
7201 count = (count + (1 << icount_time_shift) - 1)
7202 >> icount_time_shift;
7203 qemu_icount += count;
7204 decr = (count > 0xffff) ? 0xffff : count;
7205 count -= decr;
7206 env->icount_decr.u16.low = decr;
7207 env->icount_extra = count;
7208 }
bellard6a00d602005-11-21 23:25:50 +00007209 ret = cpu_exec(env);
bellard89bfc102006-02-08 22:46:31 +00007210#ifdef CONFIG_PROFILER
7211 qemu_time += profile_getclock() - ti;
7212#endif
pbrook2e70f6e2008-06-29 01:03:05 +00007213 if (use_icount) {
7214 /* Fold pending instructions back into the
7215 instruction counter, and clear the interrupt flag. */
7216 qemu_icount -= (env->icount_decr.u16.low
7217 + env->icount_extra);
7218 env->icount_decr.u32 = 0;
7219 env->icount_extra = 0;
7220 }
balrogee5605e2007-12-03 03:01:40 +00007221 next_cpu = env->next_cpu ?: first_cpu;
aurel3295b01002008-04-04 17:16:35 +00007222 if (event_pending && likely(ret != EXCP_DEBUG)) {
balrogee5605e2007-12-03 03:01:40 +00007223 ret = EXCP_INTERRUPT;
7224 event_pending = 0;
7225 break;
7226 }
pbrookbd967e02007-03-11 18:54:57 +00007227 if (ret == EXCP_HLT) {
7228 /* Give the next CPU a chance to run. */
7229 cur_cpu = env;
7230 continue;
7231 }
bellard15a76442005-11-23 21:01:03 +00007232 if (ret != EXCP_HALTED)
7233 break;
7234 /* all CPUs are halted ? */
pbrookbd967e02007-03-11 18:54:57 +00007235 if (env == cur_cpu)
bellard15a76442005-11-23 21:01:03 +00007236 break;
bellard15a76442005-11-23 21:01:03 +00007237 }
7238 cur_cpu = env;
7239
bellard5905b2e2004-08-01 21:53:26 +00007240 if (shutdown_requested) {
bellard34751872005-07-02 14:31:34 +00007241 ret = EXCP_INTERRUPT;
aurel32b2f76162008-04-11 21:35:52 +00007242 if (no_shutdown) {
7243 vm_stop(0);
7244 no_shutdown = 0;
7245 }
7246 else
7247 break;
bellard5905b2e2004-08-01 21:53:26 +00007248 }
7249 if (reset_requested) {
7250 reset_requested = 0;
7251 qemu_system_reset();
bellard34751872005-07-02 14:31:34 +00007252 ret = EXCP_INTERRUPT;
7253 }
7254 if (powerdown_requested) {
7255 powerdown_requested = 0;
7256 qemu_system_powerdown();
7257 ret = EXCP_INTERRUPT;
bellard5905b2e2004-08-01 21:53:26 +00007258 }
aurel3295b01002008-04-04 17:16:35 +00007259 if (unlikely(ret == EXCP_DEBUG)) {
bellard5905b2e2004-08-01 21:53:26 +00007260 vm_stop(EXCP_DEBUG);
7261 }
pbrookbd967e02007-03-11 18:54:57 +00007262 /* If all cpus are halted then wait until the next IRQ */
bellard5905b2e2004-08-01 21:53:26 +00007263 /* XXX: use timeout computed from timers */
pbrook2e70f6e2008-06-29 01:03:05 +00007264 if (ret == EXCP_HALTED) {
7265 if (use_icount) {
7266 int64_t add;
7267 int64_t delta;
7268 /* Advance virtual time to the next event. */
7269 if (use_icount == 1) {
7270 /* When not using an adaptive execution frequency
7271 we tend to get badly out of sync with real time,
thsbf20dc02008-06-30 17:22:19 +00007272 so just delay for a reasonable amount of time. */
pbrook2e70f6e2008-06-29 01:03:05 +00007273 delta = 0;
7274 } else {
7275 delta = cpu_get_icount() - cpu_get_clock();
7276 }
7277 if (delta > 0) {
7278 /* If virtual time is ahead of real time then just
7279 wait for IO. */
7280 timeout = (delta / 1000000) + 1;
7281 } else {
7282 /* Wait for either IO to occur or the next
7283 timer event. */
7284 add = qemu_next_deadline();
7285 /* We advance the timer before checking for IO.
7286 Limit the amount we advance so that early IO
7287 activity won't get the guest too far ahead. */
7288 if (add > 10000000)
7289 add = 10000000;
7290 delta += add;
7291 add = (add + (1 << icount_time_shift) - 1)
7292 >> icount_time_shift;
7293 qemu_icount += add;
7294 timeout = delta / 1000000;
7295 if (timeout < 0)
7296 timeout = 0;
7297 }
7298 } else {
7299 timeout = 10;
7300 }
7301 } else {
bellard5905b2e2004-08-01 21:53:26 +00007302 timeout = 0;
pbrook2e70f6e2008-06-29 01:03:05 +00007303 }
bellard5905b2e2004-08-01 21:53:26 +00007304 } else {
7305 timeout = 10;
7306 }
bellard89bfc102006-02-08 22:46:31 +00007307#ifdef CONFIG_PROFILER
7308 ti = profile_getclock();
7309#endif
bellard5905b2e2004-08-01 21:53:26 +00007310 main_loop_wait(timeout);
bellard89bfc102006-02-08 22:46:31 +00007311#ifdef CONFIG_PROFILER
7312 dev_time += profile_getclock() - ti;
7313#endif
bellardb4608c02003-06-27 17:34:32 +00007314 }
bellard34865132003-10-05 14:28:56 +00007315 cpu_disable_ticks();
7316 return ret;
bellardb4608c02003-06-27 17:34:32 +00007317}
7318
ths15f82202007-06-29 23:26:08 +00007319static void help(int exitcode)
bellard0824d6f2003-06-24 13:42:40 +00007320{
bellard68d0f702008-01-06 17:21:48 +00007321 printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
bellard0db63472003-10-27 21:37:46 +00007322 "usage: %s [options] [disk_image]\n"
bellard0824d6f2003-06-24 13:42:40 +00007323 "\n"
bellarda20dd502003-09-30 21:07:02 +00007324 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
bellardfc01f7e2003-06-30 10:03:06 +00007325 "\n"
bellarda20dd502003-09-30 21:07:02 +00007326 "Standard options:\n"
bellardcc1daa42005-06-05 14:49:17 +00007327 "-M machine select emulated machine (-M ? for list)\n"
pbrook5adb4832007-03-08 03:15:18 +00007328 "-cpu cpu select CPU (-cpu ? for list)\n"
bellardc45886d2004-01-05 00:02:06 +00007329 "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
bellard36b486b2003-11-11 13:36:08 +00007330 "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
7331 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007332 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
aurel32a1620fa2008-04-29 05:58:01 +00007333 "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
7334 " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
7335 " [,cache=on|off][,format=f]\n"
thse4bcb142007-12-02 04:51:10 +00007336 " use 'file' as a drive image\n"
balrog3e3d5812007-04-30 02:09:25 +00007337 "-mtdblock file use 'file' as on-board Flash memory image\n"
pbrooka1bb27b2007-04-06 16:49:48 +00007338 "-sd file use 'file' as SecureDigital card image\n"
j_mayer86f55662007-04-24 06:52:59 +00007339 "-pflash file use 'file' as a parallel flash image\n"
thseec85c22007-01-05 17:41:07 +00007340 "-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 +00007341 "-snapshot write to temporary files instead of disk image files\n"
7342#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007343 "-no-frame open SDL window without a frame and window decorations\n"
ths3780e192007-06-21 21:08:02 +00007344 "-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
ths667acca2006-12-11 02:08:05 +00007345 "-no-quit disable SDL window close capability\n"
7346#endif
bellard52ca8d62006-06-14 16:03:05 +00007347#ifdef TARGET_I386
7348 "-no-fd-bootchk disable boot signature checking for floppy disks\n"
7349#endif
bellarda00bad72004-05-22 21:39:06 +00007350 "-m megs set virtual RAM size to megs MB [default=%d]\n"
bellard91fc2112005-12-18 19:09:37 +00007351 "-smp n set the number of CPUs to 'n' [default=1]\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007352 "-nographic disable graphical output and redirect serial I/Os to console\n"
balroga171fe32007-04-30 01:48:07 +00007353 "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
bellard4ca00742004-12-12 22:20:04 +00007354#ifndef _WIN32
ths667acca2006-12-11 02:08:05 +00007355 "-k language use keyboard layout (for example \"fr\" for French)\n"
bellard4ca00742004-12-12 22:20:04 +00007356#endif
bellard1d14ffa2005-10-30 18:58:22 +00007357#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007358 "-audio-help print list of audio drivers and their options\n"
bellardc0fe3822005-11-05 18:55:28 +00007359 "-soundhw c1,... enable audio support\n"
7360 " and only specified sound cards (comma separated list)\n"
7361 " use -soundhw ? to get the list of supported cards\n"
bellard6a36d842005-12-18 20:34:32 +00007362 " use -soundhw all to enable all of them\n"
bellard1d14ffa2005-10-30 18:58:22 +00007363#endif
bellard89980282004-06-03 14:04:03 +00007364 "-localtime set the real time clock to local time [default=utc]\n"
bellardd63d3072004-10-03 13:29:03 +00007365 "-full-screen start in full screen\n"
bellarda09db212005-04-30 16:10:35 +00007366#ifdef TARGET_I386
7367 "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
7368#endif
bellardb389dbf2005-11-06 16:49:55 +00007369 "-usb enable the USB driver (will be the default soon)\n"
7370 "-usbdevice name add the host or guest USB device 'name'\n"
bellard6f7e9ae2005-03-13 09:43:36 +00007371#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7372 "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
bellardbb0c6722004-06-20 12:37:32 +00007373#endif
thsc35734b2007-03-19 15:17:08 +00007374 "-name string set the name of the guest\n"
bellarda20dd502003-09-30 21:07:02 +00007375 "\n"
bellardc4b1fcc2004-03-14 21:44:30 +00007376 "Network options:\n"
pbrooka41b2ff2006-02-05 04:14:41 +00007377 "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007378 " create a new Network Interface Card and connect it to VLAN 'n'\n"
bellardc20709a2004-04-21 23:27:19 +00007379#ifdef CONFIG_SLIRP
pbrook115defd2006-04-16 11:06:58 +00007380 "-net user[,vlan=n][,hostname=host]\n"
7381 " connect the user mode network stack to VLAN 'n' and send\n"
7382 " hostname 'host' to DHCP clients\n"
bellard7c9d8e02005-11-15 22:16:05 +00007383#endif
bellard7fb843f2006-02-01 23:06:55 +00007384#ifdef _WIN32
7385 "-net tap[,vlan=n],ifname=name\n"
7386 " connect the host TAP network interface to VLAN 'n'\n"
7387#else
thsb46a8902007-10-21 23:20:45 +00007388 "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7389 " connect the host TAP network interface to VLAN 'n' and use the\n"
7390 " network scripts 'file' (default=%s)\n"
7391 " and 'dfile' (default=%s);\n"
7392 " use '[down]script=no' to disable script execution;\n"
bellard7c9d8e02005-11-15 22:16:05 +00007393 " use 'fd=h' to connect to an already opened TAP interface\n"
bellard7fb843f2006-02-01 23:06:55 +00007394#endif
bellard6a00d602005-11-21 23:25:50 +00007395 "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
bellard7c9d8e02005-11-15 22:16:05 +00007396 " connect the vlan 'n' to another VLAN using a socket connection\n"
bellard3d830452005-12-18 16:36:49 +00007397 "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7398 " connect the vlan 'n' to multicast maddr and port\n"
bellard7c9d8e02005-11-15 22:16:05 +00007399 "-net none use it alone to have zero network devices; if no -net option\n"
7400 " is provided, the default is '-net nic -net user'\n"
7401 "\n"
7402#ifdef CONFIG_SLIRP
ths0db11372007-02-20 00:12:07 +00007403 "-tftp dir allow tftp access to files in dir [-net user]\n"
ths47d5d012007-02-20 00:05:08 +00007404 "-bootp file advertise file in BOOTP replies\n"
bellard7c9d8e02005-11-15 22:16:05 +00007405#ifndef _WIN32
7406 "-smb dir allow SMB access to files in 'dir' [-net user]\n"
bellardc94c8d62004-09-13 21:37:34 +00007407#endif
bellard9bf05442004-08-25 22:12:49 +00007408 "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
bellard7c9d8e02005-11-15 22:16:05 +00007409 " redirect TCP or UDP connections from host to guest [-net user]\n"
bellardc20709a2004-04-21 23:27:19 +00007410#endif
bellardc4b1fcc2004-03-14 21:44:30 +00007411 "\n"
7412 "Linux boot specific:\n"
bellarda20dd502003-09-30 21:07:02 +00007413 "-kernel bzImage use 'bzImage' as kernel image\n"
7414 "-append cmdline use 'cmdline' as kernel command line\n"
7415 "-initrd file use 'file' as initial ram disk\n"
bellardfc01f7e2003-06-30 10:03:06 +00007416 "\n"
bellard330d0412003-07-26 18:11:40 +00007417 "Debug/Expert options:\n"
bellard82c643f2004-07-14 17:28:13 +00007418 "-monitor dev redirect the monitor to char device 'dev'\n"
7419 "-serial dev redirect the serial port to char device 'dev'\n"
bellard6508fe52005-01-15 12:02:56 +00007420 "-parallel dev redirect the parallel port to char device 'dev'\n"
bellardf7cce892004-12-08 22:21:25 +00007421 "-pidfile file Write PID to 'file'\n"
bellardcd6f1162004-05-13 22:02:20 +00007422 "-S freeze CPU at startup (use 'c' to start execution)\n"
pbrookcfc34752007-02-22 01:48:01 +00007423 "-s wait gdb connection to port\n"
7424 "-p port set gdb connection port [default=%s]\n"
bellardf193c792004-03-21 17:06:25 +00007425 "-d item1,... output log to %s (use -d ? for a list of log items)\n"
bellard46d47672004-11-16 01:45:27 +00007426 "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
7427 " translation (t=none or lba) (usually qemu can guess them)\n"
bellard87b47352006-08-17 17:22:54 +00007428 "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
bellardd993e022005-02-10 22:00:06 +00007429#ifdef USE_KQEMU
bellard6515b202006-05-03 22:02:44 +00007430 "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
bellardd993e022005-02-10 22:00:06 +00007431 "-no-kqemu disable KQEMU kernel module usage\n"
7432#endif
bellardbb0c6722004-06-20 12:37:32 +00007433#ifdef TARGET_I386
bellard1bfe8562004-07-08 21:17:50 +00007434 "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
7435 " (default is CL-GD5446 PCI VGA)\n"
bellard6515b202006-05-03 22:02:44 +00007436 "-no-acpi disable ACPI\n"
bellardbb0c6722004-06-20 12:37:32 +00007437#endif
balrog4d3b6f62008-02-10 16:33:14 +00007438#ifdef CONFIG_CURSES
7439 "-curses use a curses/ncurses interface instead of SDL\n"
7440#endif
bellardd1beab82006-10-02 19:44:22 +00007441 "-no-reboot exit instead of rebooting\n"
aurel32b2f76162008-04-11 21:35:52 +00007442 "-no-shutdown stop before shutdown\n"
aurel32a8080002008-05-10 23:28:26 +00007443 "-loadvm [tag|id] start right away with a saved state (loadvm in monitor)\n"
bellard24236862006-04-30 21:28:36 +00007444 "-vnc display start a VNC server on display\n"
ths71e3ceb2006-12-22 02:11:31 +00007445#ifndef _WIN32
7446 "-daemonize daemonize QEMU after initializing\n"
7447#endif
ths9ae02552007-01-05 17:39:04 +00007448 "-option-rom rom load a file, rom, into the option ROM space\n"
blueswir166508602007-05-01 14:16:52 +00007449#ifdef TARGET_SPARC
7450 "-prom-env variable=value set OpenBIOS nvram variables\n"
7451#endif
thsf3dcfad2007-08-24 01:26:02 +00007452 "-clock force the use of the given methods for timer alarm.\n"
aurel323adda042008-03-09 23:43:49 +00007453 " To see what timers are available use -clock ?\n"
bellardbce61842008-02-01 22:18:51 +00007454 "-startdate select initial date of the clock\n"
pbrook2e70f6e2008-06-29 01:03:05 +00007455 "-icount [N|auto]\n"
pbrookdd5d6fe2008-06-29 10:43:16 +00007456 " Enable virtual instruction counter with 2^N clock ticks per instruction\n"
bellard0824d6f2003-06-24 13:42:40 +00007457 "\n"
bellard82c643f2004-07-14 17:28:13 +00007458 "During emulation, the following keys are useful:\n"
bellard032a8c92004-10-09 22:56:44 +00007459 "ctrl-alt-f toggle full screen\n"
7460 "ctrl-alt-n switch to virtual console 'n'\n"
7461 "ctrl-alt toggle mouse and keyboard grab\n"
bellard82c643f2004-07-14 17:28:13 +00007462 "\n"
7463 "When using -nographic, press 'ctrl-a h' to get some help.\n"
7464 ,
bellard0db63472003-10-27 21:37:46 +00007465 "qemu",
bellarda00bad72004-05-22 21:39:06 +00007466 DEFAULT_RAM_SIZE,
bellard7c9d8e02005-11-15 22:16:05 +00007467#ifndef _WIN32
bellarda00bad72004-05-22 21:39:06 +00007468 DEFAULT_NETWORK_SCRIPT,
thsb46a8902007-10-21 23:20:45 +00007469 DEFAULT_NETWORK_DOWN_SCRIPT,
bellard7c9d8e02005-11-15 22:16:05 +00007470#endif
bellard6e44ba72004-01-18 21:56:49 +00007471 DEFAULT_GDBSTUB_PORT,
bellardbce61842008-02-01 22:18:51 +00007472 "/tmp/qemu.log");
ths15f82202007-06-29 23:26:08 +00007473 exit(exitcode);
bellard0824d6f2003-06-24 13:42:40 +00007474}
7475
bellardcd6f1162004-05-13 22:02:20 +00007476#define HAS_ARG 0x0001
7477
7478enum {
7479 QEMU_OPTION_h,
7480
bellardcc1daa42005-06-05 14:49:17 +00007481 QEMU_OPTION_M,
j_mayer94fc95c2007-03-05 19:44:02 +00007482 QEMU_OPTION_cpu,
bellardcd6f1162004-05-13 22:02:20 +00007483 QEMU_OPTION_fda,
7484 QEMU_OPTION_fdb,
7485 QEMU_OPTION_hda,
7486 QEMU_OPTION_hdb,
7487 QEMU_OPTION_hdc,
7488 QEMU_OPTION_hdd,
thse4bcb142007-12-02 04:51:10 +00007489 QEMU_OPTION_drive,
bellardcd6f1162004-05-13 22:02:20 +00007490 QEMU_OPTION_cdrom,
balrog3e3d5812007-04-30 02:09:25 +00007491 QEMU_OPTION_mtdblock,
pbrooka1bb27b2007-04-06 16:49:48 +00007492 QEMU_OPTION_sd,
j_mayer86f55662007-04-24 06:52:59 +00007493 QEMU_OPTION_pflash,
bellardcd6f1162004-05-13 22:02:20 +00007494 QEMU_OPTION_boot,
7495 QEMU_OPTION_snapshot,
bellard52ca8d62006-06-14 16:03:05 +00007496#ifdef TARGET_I386
7497 QEMU_OPTION_no_fd_bootchk,
7498#endif
bellardcd6f1162004-05-13 22:02:20 +00007499 QEMU_OPTION_m,
7500 QEMU_OPTION_nographic,
balroga171fe32007-04-30 01:48:07 +00007501 QEMU_OPTION_portrait,
bellard1d14ffa2005-10-30 18:58:22 +00007502#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007503 QEMU_OPTION_audio_help,
7504 QEMU_OPTION_soundhw,
7505#endif
bellardcd6f1162004-05-13 22:02:20 +00007506
bellard7c9d8e02005-11-15 22:16:05 +00007507 QEMU_OPTION_net,
bellardc7f74642004-08-24 21:57:12 +00007508 QEMU_OPTION_tftp,
ths47d5d012007-02-20 00:05:08 +00007509 QEMU_OPTION_bootp,
bellard9d728e82004-09-05 23:09:03 +00007510 QEMU_OPTION_smb,
bellard9bf05442004-08-25 22:12:49 +00007511 QEMU_OPTION_redir,
bellardcd6f1162004-05-13 22:02:20 +00007512
7513 QEMU_OPTION_kernel,
7514 QEMU_OPTION_append,
7515 QEMU_OPTION_initrd,
7516
7517 QEMU_OPTION_S,
7518 QEMU_OPTION_s,
7519 QEMU_OPTION_p,
7520 QEMU_OPTION_d,
7521 QEMU_OPTION_hdachs,
7522 QEMU_OPTION_L,
j_mayer1192dad2007-10-05 13:08:35 +00007523 QEMU_OPTION_bios,
bellard3d11d0e2004-12-12 16:56:30 +00007524 QEMU_OPTION_k,
bellardee22c2f2004-06-03 12:49:50 +00007525 QEMU_OPTION_localtime,
bellard1f042752004-06-05 13:46:47 +00007526 QEMU_OPTION_cirrusvga,
thsd34cab92007-04-02 01:10:46 +00007527 QEMU_OPTION_vmsvga,
bellarde9b137c2004-06-21 16:46:10 +00007528 QEMU_OPTION_g,
bellard1bfe8562004-07-08 21:17:50 +00007529 QEMU_OPTION_std_vga,
ths20d8a3e2007-02-18 17:04:49 +00007530 QEMU_OPTION_echr,
bellard82c643f2004-07-14 17:28:13 +00007531 QEMU_OPTION_monitor,
7532 QEMU_OPTION_serial,
bellard6508fe52005-01-15 12:02:56 +00007533 QEMU_OPTION_parallel,
bellardd63d3072004-10-03 13:29:03 +00007534 QEMU_OPTION_loadvm,
7535 QEMU_OPTION_full_screen,
ths43523e92007-02-18 18:19:32 +00007536 QEMU_OPTION_no_frame,
ths3780e192007-06-21 21:08:02 +00007537 QEMU_OPTION_alt_grab,
ths667acca2006-12-11 02:08:05 +00007538 QEMU_OPTION_no_quit,
bellardf7cce892004-12-08 22:21:25 +00007539 QEMU_OPTION_pidfile,
bellardd993e022005-02-10 22:00:06 +00007540 QEMU_OPTION_no_kqemu,
bellard89bfc102006-02-08 22:46:31 +00007541 QEMU_OPTION_kernel_kqemu,
bellarda09db212005-04-30 16:10:35 +00007542 QEMU_OPTION_win2k_hack,
bellardbb36d472005-11-05 14:22:28 +00007543 QEMU_OPTION_usb,
bellarda594cfb2005-11-06 16:13:29 +00007544 QEMU_OPTION_usbdevice,
bellard6a00d602005-11-21 23:25:50 +00007545 QEMU_OPTION_smp,
bellard24236862006-04-30 21:28:36 +00007546 QEMU_OPTION_vnc,
bellard6515b202006-05-03 22:02:44 +00007547 QEMU_OPTION_no_acpi,
balrog4d3b6f62008-02-10 16:33:14 +00007548 QEMU_OPTION_curses,
bellardd1beab82006-10-02 19:44:22 +00007549 QEMU_OPTION_no_reboot,
aurel32b2f76162008-04-11 21:35:52 +00007550 QEMU_OPTION_no_shutdown,
balrog9467cd42007-05-01 01:34:14 +00007551 QEMU_OPTION_show_cursor,
ths71e3ceb2006-12-22 02:11:31 +00007552 QEMU_OPTION_daemonize,
ths9ae02552007-01-05 17:39:04 +00007553 QEMU_OPTION_option_rom,
thsc35734b2007-03-19 15:17:08 +00007554 QEMU_OPTION_semihosting,
7555 QEMU_OPTION_name,
blueswir166508602007-05-01 14:16:52 +00007556 QEMU_OPTION_prom_env,
balrog2b8f2d42007-07-27 22:08:46 +00007557 QEMU_OPTION_old_param,
thsf3dcfad2007-08-24 01:26:02 +00007558 QEMU_OPTION_clock,
bellard7e0af5d02007-11-07 16:24:33 +00007559 QEMU_OPTION_startdate,
bellard26a5f132008-05-28 12:30:31 +00007560 QEMU_OPTION_tb_size,
pbrook2e70f6e2008-06-29 01:03:05 +00007561 QEMU_OPTION_icount,
bellardcd6f1162004-05-13 22:02:20 +00007562};
7563
7564typedef struct QEMUOption {
7565 const char *name;
7566 int flags;
7567 int index;
7568} QEMUOption;
7569
7570const QEMUOption qemu_options[] = {
7571 { "h", 0, QEMU_OPTION_h },
pbrook64423fb2007-01-27 17:11:41 +00007572 { "help", 0, QEMU_OPTION_h },
bellardcd6f1162004-05-13 22:02:20 +00007573
bellardcc1daa42005-06-05 14:49:17 +00007574 { "M", HAS_ARG, QEMU_OPTION_M },
j_mayer94fc95c2007-03-05 19:44:02 +00007575 { "cpu", HAS_ARG, QEMU_OPTION_cpu },
bellardcd6f1162004-05-13 22:02:20 +00007576 { "fda", HAS_ARG, QEMU_OPTION_fda },
7577 { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7578 { "hda", HAS_ARG, QEMU_OPTION_hda },
7579 { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7580 { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7581 { "hdd", HAS_ARG, QEMU_OPTION_hdd },
thse4bcb142007-12-02 04:51:10 +00007582 { "drive", HAS_ARG, QEMU_OPTION_drive },
bellardcd6f1162004-05-13 22:02:20 +00007583 { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
balrog3e3d5812007-04-30 02:09:25 +00007584 { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
pbrooka1bb27b2007-04-06 16:49:48 +00007585 { "sd", HAS_ARG, QEMU_OPTION_sd },
j_mayer86f55662007-04-24 06:52:59 +00007586 { "pflash", HAS_ARG, QEMU_OPTION_pflash },
bellardcd6f1162004-05-13 22:02:20 +00007587 { "boot", HAS_ARG, QEMU_OPTION_boot },
7588 { "snapshot", 0, QEMU_OPTION_snapshot },
bellard52ca8d62006-06-14 16:03:05 +00007589#ifdef TARGET_I386
7590 { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7591#endif
bellardcd6f1162004-05-13 22:02:20 +00007592 { "m", HAS_ARG, QEMU_OPTION_m },
7593 { "nographic", 0, QEMU_OPTION_nographic },
balroga171fe32007-04-30 01:48:07 +00007594 { "portrait", 0, QEMU_OPTION_portrait },
bellard3d11d0e2004-12-12 16:56:30 +00007595 { "k", HAS_ARG, QEMU_OPTION_k },
bellard1d14ffa2005-10-30 18:58:22 +00007596#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00007597 { "audio-help", 0, QEMU_OPTION_audio_help },
7598 { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7599#endif
bellardcd6f1162004-05-13 22:02:20 +00007600
bellard7c9d8e02005-11-15 22:16:05 +00007601 { "net", HAS_ARG, QEMU_OPTION_net},
bellard158156d2004-05-17 21:13:42 +00007602#ifdef CONFIG_SLIRP
bellardc7f74642004-08-24 21:57:12 +00007603 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
ths47d5d012007-02-20 00:05:08 +00007604 { "bootp", HAS_ARG, QEMU_OPTION_bootp },
bellardc94c8d62004-09-13 21:37:34 +00007605#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00007606 { "smb", HAS_ARG, QEMU_OPTION_smb },
bellardc94c8d62004-09-13 21:37:34 +00007607#endif
bellard9bf05442004-08-25 22:12:49 +00007608 { "redir", HAS_ARG, QEMU_OPTION_redir },
bellard158156d2004-05-17 21:13:42 +00007609#endif
bellardcd6f1162004-05-13 22:02:20 +00007610
7611 { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7612 { "append", HAS_ARG, QEMU_OPTION_append },
7613 { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7614
7615 { "S", 0, QEMU_OPTION_S },
7616 { "s", 0, QEMU_OPTION_s },
7617 { "p", HAS_ARG, QEMU_OPTION_p },
7618 { "d", HAS_ARG, QEMU_OPTION_d },
7619 { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7620 { "L", HAS_ARG, QEMU_OPTION_L },
j_mayer1192dad2007-10-05 13:08:35 +00007621 { "bios", HAS_ARG, QEMU_OPTION_bios },
bellardd993e022005-02-10 22:00:06 +00007622#ifdef USE_KQEMU
7623 { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
bellard89bfc102006-02-08 22:46:31 +00007624 { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
bellardd993e022005-02-10 22:00:06 +00007625#endif
bellard6f7e9ae2005-03-13 09:43:36 +00007626#if defined(TARGET_PPC) || defined(TARGET_SPARC)
bellarde9b137c2004-06-21 16:46:10 +00007627 { "g", 1, QEMU_OPTION_g },
bellard77d4bc32004-05-26 22:13:53 +00007628#endif
bellardee22c2f2004-06-03 12:49:50 +00007629 { "localtime", 0, QEMU_OPTION_localtime },
bellard1bfe8562004-07-08 21:17:50 +00007630 { "std-vga", 0, QEMU_OPTION_std_vga },
balrog8b6e0722007-06-22 08:23:44 +00007631 { "echr", HAS_ARG, QEMU_OPTION_echr },
7632 { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7633 { "serial", HAS_ARG, QEMU_OPTION_serial },
7634 { "parallel", HAS_ARG, QEMU_OPTION_parallel },
bellardd63d3072004-10-03 13:29:03 +00007635 { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7636 { "full-screen", 0, QEMU_OPTION_full_screen },
ths667acca2006-12-11 02:08:05 +00007637#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00007638 { "no-frame", 0, QEMU_OPTION_no_frame },
ths3780e192007-06-21 21:08:02 +00007639 { "alt-grab", 0, QEMU_OPTION_alt_grab },
ths667acca2006-12-11 02:08:05 +00007640 { "no-quit", 0, QEMU_OPTION_no_quit },
7641#endif
bellardf7cce892004-12-08 22:21:25 +00007642 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
bellarda09db212005-04-30 16:10:35 +00007643 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
bellarda594cfb2005-11-06 16:13:29 +00007644 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
bellard6a00d602005-11-21 23:25:50 +00007645 { "smp", HAS_ARG, QEMU_OPTION_smp },
bellard24236862006-04-30 21:28:36 +00007646 { "vnc", HAS_ARG, QEMU_OPTION_vnc },
balrog4d3b6f62008-02-10 16:33:14 +00007647#ifdef CONFIG_CURSES
7648 { "curses", 0, QEMU_OPTION_curses },
7649#endif
ths96d30e42007-01-07 20:42:14 +00007650
bellard1f042752004-06-05 13:46:47 +00007651 /* temporary options */
bellarda594cfb2005-11-06 16:13:29 +00007652 { "usb", 0, QEMU_OPTION_usb },
bellard1f042752004-06-05 13:46:47 +00007653 { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
thsd34cab92007-04-02 01:10:46 +00007654 { "vmwarevga", 0, QEMU_OPTION_vmsvga },
bellard6515b202006-05-03 22:02:44 +00007655 { "no-acpi", 0, QEMU_OPTION_no_acpi },
bellardd1beab82006-10-02 19:44:22 +00007656 { "no-reboot", 0, QEMU_OPTION_no_reboot },
aurel32b2f76162008-04-11 21:35:52 +00007657 { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
balrog9467cd42007-05-01 01:34:14 +00007658 { "show-cursor", 0, QEMU_OPTION_show_cursor },
ths71e3ceb2006-12-22 02:11:31 +00007659 { "daemonize", 0, QEMU_OPTION_daemonize },
ths9ae02552007-01-05 17:39:04 +00007660 { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
pbrooka87295e2007-05-26 15:09:38 +00007661#if defined(TARGET_ARM) || defined(TARGET_M68K)
pbrook8e716212007-01-20 17:12:09 +00007662 { "semihosting", 0, QEMU_OPTION_semihosting },
7663#endif
thsc35734b2007-03-19 15:17:08 +00007664 { "name", HAS_ARG, QEMU_OPTION_name },
blueswir166508602007-05-01 14:16:52 +00007665#if defined(TARGET_SPARC)
7666 { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
7667#endif
balrog2b8f2d42007-07-27 22:08:46 +00007668#if defined(TARGET_ARM)
7669 { "old-param", 0, QEMU_OPTION_old_param },
7670#endif
thsf3dcfad2007-08-24 01:26:02 +00007671 { "clock", HAS_ARG, QEMU_OPTION_clock },
bellard7e0af5d02007-11-07 16:24:33 +00007672 { "startdate", HAS_ARG, QEMU_OPTION_startdate },
bellard26a5f132008-05-28 12:30:31 +00007673 { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
pbrook2e70f6e2008-06-29 01:03:05 +00007674 { "icount", HAS_ARG, QEMU_OPTION_icount },
bellardcd6f1162004-05-13 22:02:20 +00007675 { NULL },
bellardfc01f7e2003-06-30 10:03:06 +00007676};
7677
bellard5905b2e2004-08-01 21:53:26 +00007678/* password input */
7679
balrog2bac6012007-04-30 01:34:31 +00007680int qemu_key_check(BlockDriverState *bs, const char *name)
7681{
7682 char password[256];
7683 int i;
7684
7685 if (!bdrv_is_encrypted(bs))
7686 return 0;
7687
7688 term_printf("%s is encrypted.\n", name);
7689 for(i = 0; i < 3; i++) {
7690 monitor_readline("Password: ", 1, password, sizeof(password));
7691 if (bdrv_set_key(bs, password) == 0)
7692 return 0;
7693 term_printf("invalid password\n");
7694 }
7695 return -EPERM;
7696}
7697
bellard5905b2e2004-08-01 21:53:26 +00007698static BlockDriverState *get_bdrv(int index)
7699{
thse4bcb142007-12-02 04:51:10 +00007700 if (index > nb_drives)
7701 return NULL;
7702 return drives_table[index].bdrv;
bellard5905b2e2004-08-01 21:53:26 +00007703}
7704
7705static void read_passwords(void)
7706{
7707 BlockDriverState *bs;
balrog2bac6012007-04-30 01:34:31 +00007708 int i;
bellard5905b2e2004-08-01 21:53:26 +00007709
7710 for(i = 0; i < 6; i++) {
7711 bs = get_bdrv(i);
balrog2bac6012007-04-30 01:34:31 +00007712 if (bs)
7713 qemu_key_check(bs, bdrv_get_device_name(bs));
bellard5905b2e2004-08-01 21:53:26 +00007714 }
7715}
7716
bellard1d14ffa2005-10-30 18:58:22 +00007717#ifdef HAS_AUDIO
bellard6a36d842005-12-18 20:34:32 +00007718struct soundhw soundhw[] = {
balrogb00052e2007-04-30 02:22:06 +00007719#ifdef HAS_AUDIO_CHOICE
aurel324ce7ff62008-04-07 19:47:14 +00007720#if defined(TARGET_I386) || defined(TARGET_MIPS)
bellardfd06c372006-04-24 21:58:30 +00007721 {
7722 "pcspk",
7723 "PC speaker",
7724 0,
7725 1,
7726 { .init_isa = pcspk_audio_init }
7727 },
7728#endif
bellard6a36d842005-12-18 20:34:32 +00007729 {
7730 "sb16",
7731 "Creative Sound Blaster 16",
7732 0,
7733 1,
7734 { .init_isa = SB16_init }
7735 },
7736
malccc53d262008-06-13 10:48:22 +00007737#ifdef CONFIG_CS4231A
7738 {
7739 "cs4231a",
7740 "CS4231A",
7741 0,
7742 1,
7743 { .init_isa = cs4231a_init }
7744 },
7745#endif
7746
bellard6a36d842005-12-18 20:34:32 +00007747#ifdef CONFIG_ADLIB
7748 {
7749 "adlib",
7750#ifdef HAS_YMF262
7751 "Yamaha YMF262 (OPL3)",
7752#else
7753 "Yamaha YM3812 (OPL2)",
7754#endif
7755 0,
7756 1,
7757 { .init_isa = Adlib_init }
7758 },
7759#endif
7760
7761#ifdef CONFIG_GUS
7762 {
7763 "gus",
7764 "Gravis Ultrasound GF1",
7765 0,
7766 1,
7767 { .init_isa = GUS_init }
7768 },
7769#endif
7770
balroge5c9a132008-01-14 04:27:55 +00007771#ifdef CONFIG_AC97
7772 {
7773 "ac97",
7774 "Intel 82801AA AC97 Audio",
7775 0,
7776 0,
7777 { .init_pci = ac97_init }
7778 },
7779#endif
7780
bellard6a36d842005-12-18 20:34:32 +00007781 {
7782 "es1370",
7783 "ENSONIQ AudioPCI ES1370",
7784 0,
7785 0,
7786 { .init_pci = es1370_init }
7787 },
balrogb00052e2007-04-30 02:22:06 +00007788#endif
bellard6a36d842005-12-18 20:34:32 +00007789
7790 { NULL, NULL, 0, 0, { NULL } }
7791};
7792
bellard1d14ffa2005-10-30 18:58:22 +00007793static void select_soundhw (const char *optarg)
7794{
bellard6a36d842005-12-18 20:34:32 +00007795 struct soundhw *c;
7796
bellard1d14ffa2005-10-30 18:58:22 +00007797 if (*optarg == '?') {
7798 show_valid_cards:
bellard6a36d842005-12-18 20:34:32 +00007799
bellard1d14ffa2005-10-30 18:58:22 +00007800 printf ("Valid sound card names (comma separated):\n");
bellard6a36d842005-12-18 20:34:32 +00007801 for (c = soundhw; c->name; ++c) {
7802 printf ("%-11s %s\n", c->name, c->descr);
7803 }
7804 printf ("\n-soundhw all will enable all of the above\n");
bellard1d14ffa2005-10-30 18:58:22 +00007805 exit (*optarg != '?');
7806 }
7807 else {
bellard6a36d842005-12-18 20:34:32 +00007808 size_t l;
bellard1d14ffa2005-10-30 18:58:22 +00007809 const char *p;
7810 char *e;
7811 int bad_card = 0;
7812
bellard6a36d842005-12-18 20:34:32 +00007813 if (!strcmp (optarg, "all")) {
7814 for (c = soundhw; c->name; ++c) {
7815 c->enabled = 1;
7816 }
7817 return;
7818 }
bellard1d14ffa2005-10-30 18:58:22 +00007819
bellard6a36d842005-12-18 20:34:32 +00007820 p = optarg;
bellard1d14ffa2005-10-30 18:58:22 +00007821 while (*p) {
7822 e = strchr (p, ',');
7823 l = !e ? strlen (p) : (size_t) (e - p);
bellard6a36d842005-12-18 20:34:32 +00007824
7825 for (c = soundhw; c->name; ++c) {
7826 if (!strncmp (c->name, p, l)) {
7827 c->enabled = 1;
bellard1d14ffa2005-10-30 18:58:22 +00007828 break;
7829 }
7830 }
bellard6a36d842005-12-18 20:34:32 +00007831
7832 if (!c->name) {
bellard1d14ffa2005-10-30 18:58:22 +00007833 if (l > 80) {
7834 fprintf (stderr,
7835 "Unknown sound card name (too big to show)\n");
7836 }
7837 else {
7838 fprintf (stderr, "Unknown sound card name `%.*s'\n",
7839 (int) l, p);
7840 }
7841 bad_card = 1;
7842 }
7843 p += l + (e != NULL);
7844 }
7845
7846 if (bad_card)
7847 goto show_valid_cards;
7848 }
7849}
7850#endif
7851
bellard3587d7e2006-06-26 20:03:44 +00007852#ifdef _WIN32
7853static BOOL WINAPI qemu_ctrl_handler(DWORD type)
7854{
7855 exit(STATUS_CONTROL_C_EXIT);
7856 return TRUE;
7857}
7858#endif
7859
bellard7c9d8e02005-11-15 22:16:05 +00007860#define MAX_NET_CLIENTS 32
bellardc20709a2004-04-21 23:27:19 +00007861
bellard0824d6f2003-06-24 13:42:40 +00007862int main(int argc, char **argv)
7863{
bellard67b915a2004-03-31 23:37:16 +00007864#ifdef CONFIG_GDBSTUB
pbrookcfc34752007-02-22 01:48:01 +00007865 int use_gdbstub;
7866 const char *gdbstub_port;
bellard67b915a2004-03-31 23:37:16 +00007867#endif
j_mayer28c5af52007-11-11 01:50:45 +00007868 uint32_t boot_devices_bitmap = 0;
thse4bcb142007-12-02 04:51:10 +00007869 int i;
j_mayer28c5af52007-11-11 01:50:45 +00007870 int snapshot, linux_boot, net_boot;
bellard7f7f9872003-10-30 01:11:23 +00007871 const char *initrd_filename;
bellarda20dd502003-09-30 21:07:02 +00007872 const char *kernel_filename, *kernel_cmdline;
j_mayer28c5af52007-11-11 01:50:45 +00007873 const char *boot_devices = "";
bellard313aa562003-08-10 21:52:11 +00007874 DisplayState *ds = &display_state;
bellard46d47672004-11-16 01:45:27 +00007875 int cyls, heads, secs, translation;
pbrookfd5f3932008-03-26 20:55:43 +00007876 const char *net_clients[MAX_NET_CLIENTS];
bellard7c9d8e02005-11-15 22:16:05 +00007877 int nb_net_clients;
thse4bcb142007-12-02 04:51:10 +00007878 int hda_index;
bellardcd6f1162004-05-13 22:02:20 +00007879 int optind;
7880 const char *r, *optarg;
bellard82c643f2004-07-14 17:28:13 +00007881 CharDriverState *monitor_hd;
pbrookfd5f3932008-03-26 20:55:43 +00007882 const char *monitor_device;
7883 const char *serial_devices[MAX_SERIAL_PORTS];
bellard8d11df92004-08-24 21:13:40 +00007884 int serial_device_index;
pbrookfd5f3932008-03-26 20:55:43 +00007885 const char *parallel_devices[MAX_PARALLEL_PORTS];
bellard6508fe52005-01-15 12:02:56 +00007886 int parallel_device_index;
bellardd63d3072004-10-03 13:29:03 +00007887 const char *loadvm = NULL;
bellardcc1daa42005-06-05 14:49:17 +00007888 QEMUMachine *machine;
j_mayer94fc95c2007-03-05 19:44:02 +00007889 const char *cpu_model;
pbrookfd5f3932008-03-26 20:55:43 +00007890 const char *usb_devices[MAX_USB_CMDLINE];
bellarda594cfb2005-11-06 16:13:29 +00007891 int usb_devices_index;
ths71e3ceb2006-12-22 02:11:31 +00007892 int fds[2];
bellard26a5f132008-05-28 12:30:31 +00007893 int tb_size;
ths93815bc2007-03-19 15:58:31 +00007894 const char *pid_file = NULL;
blueswir1833c7172007-05-27 19:36:43 +00007895 VLANState *vlan;
bellard0bd48852005-11-11 00:00:47 +00007896
7897 LIST_INIT (&vm_change_state_head);
bellardbe995c22006-06-25 16:25:21 +00007898#ifndef _WIN32
7899 {
7900 struct sigaction act;
7901 sigfillset(&act.sa_mask);
7902 act.sa_flags = 0;
7903 act.sa_handler = SIG_IGN;
7904 sigaction(SIGPIPE, &act, NULL);
7905 }
bellard3587d7e2006-06-26 20:03:44 +00007906#else
7907 SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
bellarda8e5ac32006-07-14 09:36:13 +00007908 /* Note: cpu_interrupt() is currently not SMP safe, so we force
7909 QEMU to run on a single CPU */
7910 {
7911 HANDLE h;
7912 DWORD mask, smask;
7913 int i;
7914 h = GetCurrentProcess();
7915 if (GetProcessAffinityMask(h, &mask, &smask)) {
7916 for(i = 0; i < 32; i++) {
7917 if (mask & (1 << i))
7918 break;
7919 }
7920 if (i != 32) {
7921 mask = 1 << i;
7922 SetProcessAffinityMask(h, mask);
7923 }
7924 }
7925 }
bellard67b915a2004-03-31 23:37:16 +00007926#endif
bellardbe995c22006-06-25 16:25:21 +00007927
bellardcc1daa42005-06-05 14:49:17 +00007928 register_machines();
7929 machine = first_machine;
j_mayer94fc95c2007-03-05 19:44:02 +00007930 cpu_model = NULL;
bellardfc01f7e2003-06-30 10:03:06 +00007931 initrd_filename = NULL;
aurel324fc5d072008-04-27 21:39:40 +00007932 ram_size = 0;
bellard313aa562003-08-10 21:52:11 +00007933 vga_ram_size = VGA_RAM_SIZE;
bellard67b915a2004-03-31 23:37:16 +00007934#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00007935 use_gdbstub = 0;
bellardc636bb62007-02-05 20:46:05 +00007936 gdbstub_port = DEFAULT_GDBSTUB_PORT;
bellard67b915a2004-03-31 23:37:16 +00007937#endif
bellard33e39632003-07-06 17:15:21 +00007938 snapshot = 0;
bellarda20dd502003-09-30 21:07:02 +00007939 nographic = 0;
balrog4d3b6f62008-02-10 16:33:14 +00007940 curses = 0;
bellarda20dd502003-09-30 21:07:02 +00007941 kernel_filename = NULL;
7942 kernel_cmdline = "";
bellardc4b1fcc2004-03-14 21:44:30 +00007943 cyls = heads = secs = 0;
bellard46d47672004-11-16 01:45:27 +00007944 translation = BIOS_ATA_TRANSLATION_AUTO;
pbrookc60e08d2008-07-01 16:24:38 +00007945 monitor_device = "vc";
bellardc4b1fcc2004-03-14 21:44:30 +00007946
aurel32c75a8232008-05-04 00:50:34 +00007947 serial_devices[0] = "vc:80Cx24C";
bellard8d11df92004-08-24 21:13:40 +00007948 for(i = 1; i < MAX_SERIAL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00007949 serial_devices[i] = NULL;
bellard8d11df92004-08-24 21:13:40 +00007950 serial_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00007951
aurel32c75a8232008-05-04 00:50:34 +00007952 parallel_devices[0] = "vc:640x480";
bellard6508fe52005-01-15 12:02:56 +00007953 for(i = 1; i < MAX_PARALLEL_PORTS; i++)
pbrookfd5f3932008-03-26 20:55:43 +00007954 parallel_devices[i] = NULL;
bellard6508fe52005-01-15 12:02:56 +00007955 parallel_device_index = 0;
ths3b46e622007-09-17 08:09:54 +00007956
bellarda594cfb2005-11-06 16:13:29 +00007957 usb_devices_index = 0;
ths3b46e622007-09-17 08:09:54 +00007958
bellard7c9d8e02005-11-15 22:16:05 +00007959 nb_net_clients = 0;
thse4bcb142007-12-02 04:51:10 +00007960 nb_drives = 0;
7961 nb_drives_opt = 0;
7962 hda_index = -1;
bellard7c9d8e02005-11-15 22:16:05 +00007963
7964 nb_nics = 0;
ths3b46e622007-09-17 08:09:54 +00007965
bellard26a5f132008-05-28 12:30:31 +00007966 tb_size = 0;
7967
bellardcd6f1162004-05-13 22:02:20 +00007968 optind = 1;
bellard0824d6f2003-06-24 13:42:40 +00007969 for(;;) {
bellardcd6f1162004-05-13 22:02:20 +00007970 if (optind >= argc)
bellard0824d6f2003-06-24 13:42:40 +00007971 break;
bellardcd6f1162004-05-13 22:02:20 +00007972 r = argv[optind];
7973 if (r[0] != '-') {
balrog609497a2008-01-14 02:56:53 +00007974 hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
bellardcd6f1162004-05-13 22:02:20 +00007975 } else {
7976 const QEMUOption *popt;
7977
7978 optind++;
pbrookdff5efc2007-01-27 17:19:39 +00007979 /* Treat --foo the same as -foo. */
7980 if (r[1] == '-')
7981 r++;
bellardcd6f1162004-05-13 22:02:20 +00007982 popt = qemu_options;
7983 for(;;) {
7984 if (!popt->name) {
ths5fafdf22007-09-16 21:08:06 +00007985 fprintf(stderr, "%s: invalid option -- '%s'\n",
bellardcd6f1162004-05-13 22:02:20 +00007986 argv[0], r);
7987 exit(1);
7988 }
7989 if (!strcmp(popt->name, r + 1))
7990 break;
7991 popt++;
7992 }
7993 if (popt->flags & HAS_ARG) {
7994 if (optind >= argc) {
7995 fprintf(stderr, "%s: option '%s' requires an argument\n",
7996 argv[0], r);
7997 exit(1);
7998 }
7999 optarg = argv[optind++];
8000 } else {
8001 optarg = NULL;
8002 }
8003
8004 switch(popt->index) {
bellardcc1daa42005-06-05 14:49:17 +00008005 case QEMU_OPTION_M:
8006 machine = find_machine(optarg);
8007 if (!machine) {
8008 QEMUMachine *m;
8009 printf("Supported machines are:\n");
8010 for(m = first_machine; m != NULL; m = m->next) {
8011 printf("%-10s %s%s\n",
ths5fafdf22007-09-16 21:08:06 +00008012 m->name, m->desc,
bellardcc1daa42005-06-05 14:49:17 +00008013 m == first_machine ? " (default)" : "");
8014 }
ths15f82202007-06-29 23:26:08 +00008015 exit(*optarg != '?');
bellardcc1daa42005-06-05 14:49:17 +00008016 }
8017 break;
j_mayer94fc95c2007-03-05 19:44:02 +00008018 case QEMU_OPTION_cpu:
8019 /* hw initialization will check this */
ths15f82202007-06-29 23:26:08 +00008020 if (*optarg == '?') {
j_mayerc732abe2007-10-12 06:47:46 +00008021/* XXX: implement xxx_cpu_list for targets that still miss it */
8022#if defined(cpu_list)
8023 cpu_list(stdout, &fprintf);
j_mayer94fc95c2007-03-05 19:44:02 +00008024#endif
ths15f82202007-06-29 23:26:08 +00008025 exit(0);
j_mayer94fc95c2007-03-05 19:44:02 +00008026 } else {
8027 cpu_model = optarg;
8028 }
8029 break;
bellardcd6f1162004-05-13 22:02:20 +00008030 case QEMU_OPTION_initrd:
bellardfc01f7e2003-06-30 10:03:06 +00008031 initrd_filename = optarg;
8032 break;
bellardcd6f1162004-05-13 22:02:20 +00008033 case QEMU_OPTION_hda:
thse4bcb142007-12-02 04:51:10 +00008034 if (cyls == 0)
balrog609497a2008-01-14 02:56:53 +00008035 hda_index = drive_add(optarg, HD_ALIAS, 0);
thse4bcb142007-12-02 04:51:10 +00008036 else
balrog609497a2008-01-14 02:56:53 +00008037 hda_index = drive_add(optarg, HD_ALIAS
thse4bcb142007-12-02 04:51:10 +00008038 ",cyls=%d,heads=%d,secs=%d%s",
balrog609497a2008-01-14 02:56:53 +00008039 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008040 translation == BIOS_ATA_TRANSLATION_LBA ?
8041 ",trans=lba" :
8042 translation == BIOS_ATA_TRANSLATION_NONE ?
8043 ",trans=none" : "");
8044 break;
bellardcd6f1162004-05-13 22:02:20 +00008045 case QEMU_OPTION_hdb:
bellardcc1daa42005-06-05 14:49:17 +00008046 case QEMU_OPTION_hdc:
8047 case QEMU_OPTION_hdd:
balrog609497a2008-01-14 02:56:53 +00008048 drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
bellardfc01f7e2003-06-30 10:03:06 +00008049 break;
thse4bcb142007-12-02 04:51:10 +00008050 case QEMU_OPTION_drive:
balrog609497a2008-01-14 02:56:53 +00008051 drive_add(NULL, "%s", optarg);
thse4bcb142007-12-02 04:51:10 +00008052 break;
balrog3e3d5812007-04-30 02:09:25 +00008053 case QEMU_OPTION_mtdblock:
balrog609497a2008-01-14 02:56:53 +00008054 drive_add(optarg, MTD_ALIAS);
balrog3e3d5812007-04-30 02:09:25 +00008055 break;
pbrooka1bb27b2007-04-06 16:49:48 +00008056 case QEMU_OPTION_sd:
balrog609497a2008-01-14 02:56:53 +00008057 drive_add(optarg, SD_ALIAS);
pbrooka1bb27b2007-04-06 16:49:48 +00008058 break;
j_mayer86f55662007-04-24 06:52:59 +00008059 case QEMU_OPTION_pflash:
balrog609497a2008-01-14 02:56:53 +00008060 drive_add(optarg, PFLASH_ALIAS);
j_mayer86f55662007-04-24 06:52:59 +00008061 break;
bellardcd6f1162004-05-13 22:02:20 +00008062 case QEMU_OPTION_snapshot:
bellard33e39632003-07-06 17:15:21 +00008063 snapshot = 1;
8064 break;
bellardcd6f1162004-05-13 22:02:20 +00008065 case QEMU_OPTION_hdachs:
bellard330d0412003-07-26 18:11:40 +00008066 {
bellard330d0412003-07-26 18:11:40 +00008067 const char *p;
8068 p = optarg;
8069 cyls = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008070 if (cyls < 1 || cyls > 16383)
8071 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008072 if (*p != ',')
8073 goto chs_fail;
8074 p++;
8075 heads = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008076 if (heads < 1 || heads > 16)
8077 goto chs_fail;
bellard330d0412003-07-26 18:11:40 +00008078 if (*p != ',')
8079 goto chs_fail;
8080 p++;
8081 secs = strtol(p, (char **)&p, 0);
bellard46d47672004-11-16 01:45:27 +00008082 if (secs < 1 || secs > 63)
8083 goto chs_fail;
8084 if (*p == ',') {
8085 p++;
8086 if (!strcmp(p, "none"))
8087 translation = BIOS_ATA_TRANSLATION_NONE;
8088 else if (!strcmp(p, "lba"))
8089 translation = BIOS_ATA_TRANSLATION_LBA;
8090 else if (!strcmp(p, "auto"))
8091 translation = BIOS_ATA_TRANSLATION_AUTO;
8092 else
8093 goto chs_fail;
8094 } else if (*p != '\0') {
bellardc4b1fcc2004-03-14 21:44:30 +00008095 chs_fail:
bellard46d47672004-11-16 01:45:27 +00008096 fprintf(stderr, "qemu: invalid physical CHS format\n");
8097 exit(1);
bellardc4b1fcc2004-03-14 21:44:30 +00008098 }
thse4bcb142007-12-02 04:51:10 +00008099 if (hda_index != -1)
balrog609497a2008-01-14 02:56:53 +00008100 snprintf(drives_opt[hda_index].opt,
8101 sizeof(drives_opt[hda_index].opt),
8102 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
8103 0, cyls, heads, secs,
thse4bcb142007-12-02 04:51:10 +00008104 translation == BIOS_ATA_TRANSLATION_LBA ?
8105 ",trans=lba" :
8106 translation == BIOS_ATA_TRANSLATION_NONE ?
8107 ",trans=none" : "");
bellard330d0412003-07-26 18:11:40 +00008108 }
8109 break;
bellardcd6f1162004-05-13 22:02:20 +00008110 case QEMU_OPTION_nographic:
pbrookfd5f3932008-03-26 20:55:43 +00008111 serial_devices[0] = "stdio";
8112 parallel_devices[0] = "null";
8113 monitor_device = "stdio";
bellarda20dd502003-09-30 21:07:02 +00008114 nographic = 1;
8115 break;
balrog4d3b6f62008-02-10 16:33:14 +00008116#ifdef CONFIG_CURSES
8117 case QEMU_OPTION_curses:
8118 curses = 1;
8119 break;
8120#endif
balroga171fe32007-04-30 01:48:07 +00008121 case QEMU_OPTION_portrait:
8122 graphic_rotate = 1;
8123 break;
bellardcd6f1162004-05-13 22:02:20 +00008124 case QEMU_OPTION_kernel:
bellarda20dd502003-09-30 21:07:02 +00008125 kernel_filename = optarg;
8126 break;
bellardcd6f1162004-05-13 22:02:20 +00008127 case QEMU_OPTION_append:
bellarda20dd502003-09-30 21:07:02 +00008128 kernel_cmdline = optarg;
bellard313aa562003-08-10 21:52:11 +00008129 break;
bellardcd6f1162004-05-13 22:02:20 +00008130 case QEMU_OPTION_cdrom:
balrog609497a2008-01-14 02:56:53 +00008131 drive_add(optarg, CDROM_ALIAS);
bellard36b486b2003-11-11 13:36:08 +00008132 break;
bellardcd6f1162004-05-13 22:02:20 +00008133 case QEMU_OPTION_boot:
j_mayer28c5af52007-11-11 01:50:45 +00008134 boot_devices = optarg;
8135 /* We just do some generic consistency checks */
8136 {
8137 /* Could easily be extended to 64 devices if needed */
ths60fe76f2007-12-16 03:02:09 +00008138 const char *p;
j_mayer28c5af52007-11-11 01:50:45 +00008139
8140 boot_devices_bitmap = 0;
8141 for (p = boot_devices; *p != '\0'; p++) {
8142 /* Allowed boot devices are:
8143 * a b : floppy disk drives
8144 * c ... f : IDE disk drives
8145 * g ... m : machine implementation dependant drives
8146 * n ... p : network devices
8147 * It's up to each machine implementation to check
8148 * if the given boot devices match the actual hardware
8149 * implementation and firmware features.
8150 */
8151 if (*p < 'a' || *p > 'q') {
8152 fprintf(stderr, "Invalid boot device '%c'\n", *p);
8153 exit(1);
8154 }
8155 if (boot_devices_bitmap & (1 << (*p - 'a'))) {
8156 fprintf(stderr,
8157 "Boot device '%c' was given twice\n",*p);
8158 exit(1);
8159 }
8160 boot_devices_bitmap |= 1 << (*p - 'a');
8161 }
bellard36b486b2003-11-11 13:36:08 +00008162 }
8163 break;
bellardcd6f1162004-05-13 22:02:20 +00008164 case QEMU_OPTION_fda:
bellardcd6f1162004-05-13 22:02:20 +00008165 case QEMU_OPTION_fdb:
balrog609497a2008-01-14 02:56:53 +00008166 drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
bellardc45886d2004-01-05 00:02:06 +00008167 break;
bellard52ca8d62006-06-14 16:03:05 +00008168#ifdef TARGET_I386
8169 case QEMU_OPTION_no_fd_bootchk:
8170 fd_bootchk = 0;
8171 break;
8172#endif
bellard7c9d8e02005-11-15 22:16:05 +00008173 case QEMU_OPTION_net:
8174 if (nb_net_clients >= MAX_NET_CLIENTS) {
8175 fprintf(stderr, "qemu: too many network clients\n");
bellardc4b1fcc2004-03-14 21:44:30 +00008176 exit(1);
8177 }
pbrookfd5f3932008-03-26 20:55:43 +00008178 net_clients[nb_net_clients] = optarg;
bellard7c9d8e02005-11-15 22:16:05 +00008179 nb_net_clients++;
bellard702c6512004-04-02 21:21:32 +00008180 break;
bellardc7f74642004-08-24 21:57:12 +00008181#ifdef CONFIG_SLIRP
8182 case QEMU_OPTION_tftp:
bellardc7f74642004-08-24 21:57:12 +00008183 tftp_prefix = optarg;
bellard9bf05442004-08-25 22:12:49 +00008184 break;
ths47d5d012007-02-20 00:05:08 +00008185 case QEMU_OPTION_bootp:
8186 bootp_filename = optarg;
8187 break;
bellardc94c8d62004-09-13 21:37:34 +00008188#ifndef _WIN32
bellard9d728e82004-09-05 23:09:03 +00008189 case QEMU_OPTION_smb:
8190 net_slirp_smb(optarg);
8191 break;
bellardc94c8d62004-09-13 21:37:34 +00008192#endif
bellard9bf05442004-08-25 22:12:49 +00008193 case QEMU_OPTION_redir:
ths3b46e622007-09-17 08:09:54 +00008194 net_slirp_redir(optarg);
bellard9bf05442004-08-25 22:12:49 +00008195 break;
bellardc7f74642004-08-24 21:57:12 +00008196#endif
bellard1d14ffa2005-10-30 18:58:22 +00008197#ifdef HAS_AUDIO
bellard1d14ffa2005-10-30 18:58:22 +00008198 case QEMU_OPTION_audio_help:
8199 AUD_help ();
8200 exit (0);
8201 break;
8202 case QEMU_OPTION_soundhw:
8203 select_soundhw (optarg);
8204 break;
8205#endif
bellardcd6f1162004-05-13 22:02:20 +00008206 case QEMU_OPTION_h:
ths15f82202007-06-29 23:26:08 +00008207 help(0);
bellardcd6f1162004-05-13 22:02:20 +00008208 break;
aurel3200f82b82008-04-27 21:12:55 +00008209 case QEMU_OPTION_m: {
8210 uint64_t value;
8211 char *ptr;
8212
8213 value = strtoul(optarg, &ptr, 10);
8214 switch (*ptr) {
8215 case 0: case 'M': case 'm':
8216 value <<= 20;
8217 break;
8218 case 'G': case 'g':
8219 value <<= 30;
8220 break;
8221 default:
8222 fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
bellardcd6f1162004-05-13 22:02:20 +00008223 exit(1);
8224 }
aurel3200f82b82008-04-27 21:12:55 +00008225
8226 /* On 32-bit hosts, QEMU is limited by virtual address space */
8227 if (value > (2047 << 20)
8228#ifndef USE_KQEMU
8229 && HOST_LONG_BITS == 32
8230#endif
8231 ) {
8232 fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
8233 exit(1);
8234 }
8235 if (value != (uint64_t)(ram_addr_t)value) {
8236 fprintf(stderr, "qemu: ram size too large\n");
8237 exit(1);
8238 }
8239 ram_size = value;
bellardcd6f1162004-05-13 22:02:20 +00008240 break;
aurel3200f82b82008-04-27 21:12:55 +00008241 }
bellardcd6f1162004-05-13 22:02:20 +00008242 case QEMU_OPTION_d:
8243 {
8244 int mask;
8245 CPULogItem *item;
ths3b46e622007-09-17 08:09:54 +00008246
bellardcd6f1162004-05-13 22:02:20 +00008247 mask = cpu_str_to_log_mask(optarg);
8248 if (!mask) {
8249 printf("Log items (comma separated):\n");
bellardf193c792004-03-21 17:06:25 +00008250 for(item = cpu_log_items; item->mask != 0; item++) {
8251 printf("%-10s %s\n", item->name, item->help);
8252 }
8253 exit(1);
bellardcd6f1162004-05-13 22:02:20 +00008254 }
8255 cpu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00008256 }
bellardcd6f1162004-05-13 22:02:20 +00008257 break;
bellard67b915a2004-03-31 23:37:16 +00008258#ifdef CONFIG_GDBSTUB
bellardcd6f1162004-05-13 22:02:20 +00008259 case QEMU_OPTION_s:
8260 use_gdbstub = 1;
8261 break;
8262 case QEMU_OPTION_p:
pbrookcfc34752007-02-22 01:48:01 +00008263 gdbstub_port = optarg;
bellardcd6f1162004-05-13 22:02:20 +00008264 break;
bellard67b915a2004-03-31 23:37:16 +00008265#endif
bellardcd6f1162004-05-13 22:02:20 +00008266 case QEMU_OPTION_L:
8267 bios_dir = optarg;
8268 break;
j_mayer1192dad2007-10-05 13:08:35 +00008269 case QEMU_OPTION_bios:
8270 bios_name = optarg;
8271 break;
bellardcd6f1162004-05-13 22:02:20 +00008272 case QEMU_OPTION_S:
pbrook3c07f8e2007-01-21 16:47:01 +00008273 autostart = 0;
bellardcd6f1162004-05-13 22:02:20 +00008274 break;
bellard3d11d0e2004-12-12 16:56:30 +00008275 case QEMU_OPTION_k:
8276 keyboard_layout = optarg;
8277 break;
bellardee22c2f2004-06-03 12:49:50 +00008278 case QEMU_OPTION_localtime:
8279 rtc_utc = 0;
8280 break;
bellard1f042752004-06-05 13:46:47 +00008281 case QEMU_OPTION_cirrusvga:
8282 cirrus_vga_enabled = 1;
thsd34cab92007-04-02 01:10:46 +00008283 vmsvga_enabled = 0;
8284 break;
8285 case QEMU_OPTION_vmsvga:
8286 cirrus_vga_enabled = 0;
8287 vmsvga_enabled = 1;
bellard1f042752004-06-05 13:46:47 +00008288 break;
bellard1bfe8562004-07-08 21:17:50 +00008289 case QEMU_OPTION_std_vga:
8290 cirrus_vga_enabled = 0;
thsd34cab92007-04-02 01:10:46 +00008291 vmsvga_enabled = 0;
bellard1bfe8562004-07-08 21:17:50 +00008292 break;
bellarde9b137c2004-06-21 16:46:10 +00008293 case QEMU_OPTION_g:
8294 {
8295 const char *p;
8296 int w, h, depth;
8297 p = optarg;
8298 w = strtol(p, (char **)&p, 10);
8299 if (w <= 0) {
8300 graphic_error:
8301 fprintf(stderr, "qemu: invalid resolution or depth\n");
8302 exit(1);
8303 }
8304 if (*p != 'x')
8305 goto graphic_error;
8306 p++;
8307 h = strtol(p, (char **)&p, 10);
8308 if (h <= 0)
8309 goto graphic_error;
8310 if (*p == 'x') {
8311 p++;
8312 depth = strtol(p, (char **)&p, 10);
ths5fafdf22007-09-16 21:08:06 +00008313 if (depth != 8 && depth != 15 && depth != 16 &&
bellarde9b137c2004-06-21 16:46:10 +00008314 depth != 24 && depth != 32)
8315 goto graphic_error;
8316 } else if (*p == '\0') {
8317 depth = graphic_depth;
8318 } else {
8319 goto graphic_error;
8320 }
ths3b46e622007-09-17 08:09:54 +00008321
bellarde9b137c2004-06-21 16:46:10 +00008322 graphic_width = w;
8323 graphic_height = h;
8324 graphic_depth = depth;
8325 }
8326 break;
ths20d8a3e2007-02-18 17:04:49 +00008327 case QEMU_OPTION_echr:
8328 {
8329 char *r;
8330 term_escape_char = strtol(optarg, &r, 0);
8331 if (r == optarg)
8332 printf("Bad argument to echr\n");
8333 break;
8334 }
bellard82c643f2004-07-14 17:28:13 +00008335 case QEMU_OPTION_monitor:
pbrookfd5f3932008-03-26 20:55:43 +00008336 monitor_device = optarg;
bellard82c643f2004-07-14 17:28:13 +00008337 break;
8338 case QEMU_OPTION_serial:
bellard8d11df92004-08-24 21:13:40 +00008339 if (serial_device_index >= MAX_SERIAL_PORTS) {
8340 fprintf(stderr, "qemu: too many serial ports\n");
8341 exit(1);
8342 }
pbrookfd5f3932008-03-26 20:55:43 +00008343 serial_devices[serial_device_index] = optarg;
bellard8d11df92004-08-24 21:13:40 +00008344 serial_device_index++;
bellard82c643f2004-07-14 17:28:13 +00008345 break;
bellard6508fe52005-01-15 12:02:56 +00008346 case QEMU_OPTION_parallel:
8347 if (parallel_device_index >= MAX_PARALLEL_PORTS) {
8348 fprintf(stderr, "qemu: too many parallel ports\n");
8349 exit(1);
8350 }
pbrookfd5f3932008-03-26 20:55:43 +00008351 parallel_devices[parallel_device_index] = optarg;
bellard6508fe52005-01-15 12:02:56 +00008352 parallel_device_index++;
8353 break;
bellardd63d3072004-10-03 13:29:03 +00008354 case QEMU_OPTION_loadvm:
8355 loadvm = optarg;
8356 break;
8357 case QEMU_OPTION_full_screen:
8358 full_screen = 1;
8359 break;
ths667acca2006-12-11 02:08:05 +00008360#ifdef CONFIG_SDL
ths43523e92007-02-18 18:19:32 +00008361 case QEMU_OPTION_no_frame:
8362 no_frame = 1;
8363 break;
ths3780e192007-06-21 21:08:02 +00008364 case QEMU_OPTION_alt_grab:
8365 alt_grab = 1;
8366 break;
ths667acca2006-12-11 02:08:05 +00008367 case QEMU_OPTION_no_quit:
8368 no_quit = 1;
8369 break;
8370#endif
bellardf7cce892004-12-08 22:21:25 +00008371 case QEMU_OPTION_pidfile:
ths93815bc2007-03-19 15:58:31 +00008372 pid_file = optarg;
bellardf7cce892004-12-08 22:21:25 +00008373 break;
bellarda09db212005-04-30 16:10:35 +00008374#ifdef TARGET_I386
8375 case QEMU_OPTION_win2k_hack:
8376 win2k_install_hack = 1;
8377 break;
8378#endif
bellardd993e022005-02-10 22:00:06 +00008379#ifdef USE_KQEMU
8380 case QEMU_OPTION_no_kqemu:
8381 kqemu_allowed = 0;
8382 break;
bellard89bfc102006-02-08 22:46:31 +00008383 case QEMU_OPTION_kernel_kqemu:
8384 kqemu_allowed = 2;
8385 break;
bellardd993e022005-02-10 22:00:06 +00008386#endif
bellardbb36d472005-11-05 14:22:28 +00008387 case QEMU_OPTION_usb:
8388 usb_enabled = 1;
8389 break;
bellarda594cfb2005-11-06 16:13:29 +00008390 case QEMU_OPTION_usbdevice:
8391 usb_enabled = 1;
pbrook0d92ed32006-05-21 16:30:15 +00008392 if (usb_devices_index >= MAX_USB_CMDLINE) {
bellarda594cfb2005-11-06 16:13:29 +00008393 fprintf(stderr, "Too many USB devices\n");
8394 exit(1);
8395 }
pbrookfd5f3932008-03-26 20:55:43 +00008396 usb_devices[usb_devices_index] = optarg;
bellarda594cfb2005-11-06 16:13:29 +00008397 usb_devices_index++;
8398 break;
bellard6a00d602005-11-21 23:25:50 +00008399 case QEMU_OPTION_smp:
8400 smp_cpus = atoi(optarg);
bellardba3c64f2005-12-05 20:31:52 +00008401 if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
bellard6a00d602005-11-21 23:25:50 +00008402 fprintf(stderr, "Invalid number of CPUs\n");
8403 exit(1);
8404 }
8405 break;
bellard24236862006-04-30 21:28:36 +00008406 case QEMU_OPTION_vnc:
ths73fc9742006-12-22 02:09:07 +00008407 vnc_display = optarg;
bellard24236862006-04-30 21:28:36 +00008408 break;
bellard6515b202006-05-03 22:02:44 +00008409 case QEMU_OPTION_no_acpi:
8410 acpi_enabled = 0;
8411 break;
bellardd1beab82006-10-02 19:44:22 +00008412 case QEMU_OPTION_no_reboot:
8413 no_reboot = 1;
8414 break;
aurel32b2f76162008-04-11 21:35:52 +00008415 case QEMU_OPTION_no_shutdown:
8416 no_shutdown = 1;
8417 break;
balrog9467cd42007-05-01 01:34:14 +00008418 case QEMU_OPTION_show_cursor:
8419 cursor_hide = 0;
8420 break;
ths71e3ceb2006-12-22 02:11:31 +00008421 case QEMU_OPTION_daemonize:
8422 daemonize = 1;
8423 break;
ths9ae02552007-01-05 17:39:04 +00008424 case QEMU_OPTION_option_rom:
8425 if (nb_option_roms >= MAX_OPTION_ROMS) {
8426 fprintf(stderr, "Too many option ROMs\n");
8427 exit(1);
8428 }
8429 option_rom[nb_option_roms] = optarg;
8430 nb_option_roms++;
8431 break;
pbrook8e716212007-01-20 17:12:09 +00008432 case QEMU_OPTION_semihosting:
8433 semihosting_enabled = 1;
8434 break;
thsc35734b2007-03-19 15:17:08 +00008435 case QEMU_OPTION_name:
8436 qemu_name = optarg;
8437 break;
blueswir166508602007-05-01 14:16:52 +00008438#ifdef TARGET_SPARC
8439 case QEMU_OPTION_prom_env:
8440 if (nb_prom_envs >= MAX_PROM_ENVS) {
8441 fprintf(stderr, "Too many prom variables\n");
8442 exit(1);
8443 }
8444 prom_envs[nb_prom_envs] = optarg;
8445 nb_prom_envs++;
8446 break;
8447#endif
balrog2b8f2d42007-07-27 22:08:46 +00008448#ifdef TARGET_ARM
8449 case QEMU_OPTION_old_param:
8450 old_param = 1;
ths05ebd532008-01-08 19:32:16 +00008451 break;
balrog2b8f2d42007-07-27 22:08:46 +00008452#endif
thsf3dcfad2007-08-24 01:26:02 +00008453 case QEMU_OPTION_clock:
8454 configure_alarms(optarg);
8455 break;
bellard7e0af5d02007-11-07 16:24:33 +00008456 case QEMU_OPTION_startdate:
8457 {
8458 struct tm tm;
balrogf6503052008-02-17 11:42:19 +00008459 time_t rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008460 if (!strcmp(optarg, "now")) {
balrogf6503052008-02-17 11:42:19 +00008461 rtc_date_offset = -1;
bellard7e0af5d02007-11-07 16:24:33 +00008462 } else {
8463 if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8464 &tm.tm_year,
8465 &tm.tm_mon,
8466 &tm.tm_mday,
8467 &tm.tm_hour,
8468 &tm.tm_min,
8469 &tm.tm_sec) == 6) {
8470 /* OK */
8471 } else if (sscanf(optarg, "%d-%d-%d",
8472 &tm.tm_year,
8473 &tm.tm_mon,
8474 &tm.tm_mday) == 3) {
8475 tm.tm_hour = 0;
8476 tm.tm_min = 0;
8477 tm.tm_sec = 0;
8478 } else {
8479 goto date_fail;
8480 }
8481 tm.tm_year -= 1900;
8482 tm.tm_mon--;
bellard3c6b2082007-11-10 19:36:39 +00008483 rtc_start_date = mktimegm(&tm);
bellard7e0af5d02007-11-07 16:24:33 +00008484 if (rtc_start_date == -1) {
8485 date_fail:
8486 fprintf(stderr, "Invalid date format. Valid format are:\n"
8487 "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8488 exit(1);
8489 }
balrogf6503052008-02-17 11:42:19 +00008490 rtc_date_offset = time(NULL) - rtc_start_date;
bellard7e0af5d02007-11-07 16:24:33 +00008491 }
8492 }
8493 break;
bellard26a5f132008-05-28 12:30:31 +00008494 case QEMU_OPTION_tb_size:
8495 tb_size = strtol(optarg, NULL, 0);
8496 if (tb_size < 0)
8497 tb_size = 0;
8498 break;
pbrook2e70f6e2008-06-29 01:03:05 +00008499 case QEMU_OPTION_icount:
8500 use_icount = 1;
8501 if (strcmp(optarg, "auto") == 0) {
8502 icount_time_shift = -1;
8503 } else {
8504 icount_time_shift = strtol(optarg, NULL, 0);
8505 }
8506 break;
bellardcd6f1162004-05-13 22:02:20 +00008507 }
bellard0824d6f2003-06-24 13:42:40 +00008508 }
8509 }
bellard330d0412003-07-26 18:11:40 +00008510
ths71e3ceb2006-12-22 02:11:31 +00008511#ifndef _WIN32
8512 if (daemonize && !nographic && vnc_display == NULL) {
8513 fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
8514 daemonize = 0;
8515 }
8516
8517 if (daemonize) {
8518 pid_t pid;
8519
8520 if (pipe(fds) == -1)
8521 exit(1);
8522
8523 pid = fork();
8524 if (pid > 0) {
8525 uint8_t status;
8526 ssize_t len;
8527
8528 close(fds[1]);
8529
8530 again:
ths93815bc2007-03-19 15:58:31 +00008531 len = read(fds[0], &status, 1);
8532 if (len == -1 && (errno == EINTR))
8533 goto again;
8534
8535 if (len != 1)
8536 exit(1);
8537 else if (status == 1) {
8538 fprintf(stderr, "Could not acquire pidfile\n");
8539 exit(1);
8540 } else
8541 exit(0);
ths71e3ceb2006-12-22 02:11:31 +00008542 } else if (pid < 0)
ths93815bc2007-03-19 15:58:31 +00008543 exit(1);
ths71e3ceb2006-12-22 02:11:31 +00008544
8545 setsid();
8546
8547 pid = fork();
8548 if (pid > 0)
8549 exit(0);
8550 else if (pid < 0)
8551 exit(1);
8552
8553 umask(027);
8554 chdir("/");
8555
8556 signal(SIGTSTP, SIG_IGN);
8557 signal(SIGTTOU, SIG_IGN);
8558 signal(SIGTTIN, SIG_IGN);
8559 }
8560#endif
8561
thsaa26bb22007-03-25 21:33:06 +00008562 if (pid_file && qemu_create_pidfile(pid_file) != 0) {
ths93815bc2007-03-19 15:58:31 +00008563 if (daemonize) {
8564 uint8_t status = 1;
8565 write(fds[1], &status, 1);
8566 } else
8567 fprintf(stderr, "Could not acquire pid file\n");
8568 exit(1);
8569 }
8570
bellardff3fbb32006-01-08 10:53:14 +00008571#ifdef USE_KQEMU
8572 if (smp_cpus > 1)
8573 kqemu_allowed = 0;
8574#endif
bellarda20dd502003-09-30 21:07:02 +00008575 linux_boot = (kernel_filename != NULL);
balrog7317b8c2007-11-18 02:09:36 +00008576 net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
balrog6c41b272007-11-17 12:12:29 +00008577
j_mayer28c5af52007-11-11 01:50:45 +00008578 /* XXX: this should not be: some embedded targets just have flash */
8579 if (!linux_boot && net_boot == 0 &&
thse4bcb142007-12-02 04:51:10 +00008580 nb_drives_opt == 0)
ths15f82202007-06-29 23:26:08 +00008581 help(1);
bellard0824d6f2003-06-24 13:42:40 +00008582
thsf8d39c02008-07-03 10:01:15 +00008583 if (!linux_boot && *kernel_cmdline != '\0') {
8584 fprintf(stderr, "-append only allowed with -kernel option\n");
8585 exit(1);
8586 }
8587
8588 if (!linux_boot && initrd_filename != NULL) {
8589 fprintf(stderr, "-initrd only allowed with -kernel option\n");
8590 exit(1);
8591 }
8592
ths96d30e42007-01-07 20:42:14 +00008593 /* boot to floppy or the default cd if no hard disk defined yet */
j_mayer28c5af52007-11-11 01:50:45 +00008594 if (!boot_devices[0]) {
thse4bcb142007-12-02 04:51:10 +00008595 boot_devices = "cad";
ths96d30e42007-01-07 20:42:14 +00008596 }
bellardb118d612003-06-30 23:36:21 +00008597 setvbuf(stdout, NULL, _IOLBF, 0);
ths3b46e622007-09-17 08:09:54 +00008598
pbrook634fce92006-07-15 17:40:09 +00008599 init_timers();
8600 init_timer_alarm();
bellard83f64092006-08-01 16:21:11 +00008601 qemu_aio_init();
pbrook2e70f6e2008-06-29 01:03:05 +00008602 if (use_icount && icount_time_shift < 0) {
8603 use_icount = 2;
8604 /* 125MIPS seems a reasonable initial guess at the guest speed.
8605 It will be corrected fairly quickly anyway. */
8606 icount_time_shift = 3;
8607 init_icount_adjust();
8608 }
pbrook634fce92006-07-15 17:40:09 +00008609
bellardfd1dff42006-02-01 21:29:26 +00008610#ifdef _WIN32
8611 socket_init();
8612#endif
8613
bellard7c9d8e02005-11-15 22:16:05 +00008614 /* init network clients */
8615 if (nb_net_clients == 0) {
8616 /* if no clients, we use a default config */
pbrookfd5f3932008-03-26 20:55:43 +00008617 net_clients[0] = "nic";
8618 net_clients[1] = "user";
bellard7c9d8e02005-11-15 22:16:05 +00008619 nb_net_clients = 2;
bellardc20709a2004-04-21 23:27:19 +00008620 }
8621
bellard7c9d8e02005-11-15 22:16:05 +00008622 for(i = 0;i < nb_net_clients; i++) {
8623 if (net_client_init(net_clients[i]) < 0)
8624 exit(1);
bellard702c6512004-04-02 21:21:32 +00008625 }
blueswir1833c7172007-05-27 19:36:43 +00008626 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8627 if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8628 continue;
8629 if (vlan->nb_guest_devs == 0) {
8630 fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
8631 exit(1);
8632 }
8633 if (vlan->nb_host_devs == 0)
8634 fprintf(stderr,
8635 "Warning: vlan %d is not connected to host network\n",
8636 vlan->id);
8637 }
bellardf1510b22003-06-25 00:07:40 +00008638
thseec85c22007-01-05 17:41:07 +00008639#ifdef TARGET_I386
balroged494d82007-12-11 23:23:52 +00008640 /* XXX: this should be moved in the PC machine instantiation code */
j_mayer28c5af52007-11-11 01:50:45 +00008641 if (net_boot != 0) {
8642 int netroms = 0;
8643 for (i = 0; i < nb_nics && i < 4; i++) {
thseec85c22007-01-05 17:41:07 +00008644 const char *model = nd_table[i].model;
8645 char buf[1024];
j_mayer28c5af52007-11-11 01:50:45 +00008646 if (net_boot & (1 << i)) {
8647 if (model == NULL)
8648 model = "ne2k_pci";
8649 snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8650 if (get_image_size(buf) > 0) {
8651 if (nb_option_roms >= MAX_OPTION_ROMS) {
8652 fprintf(stderr, "Too many option ROMs\n");
8653 exit(1);
8654 }
8655 option_rom[nb_option_roms] = strdup(buf);
8656 nb_option_roms++;
8657 netroms++;
8658 }
8659 }
thseec85c22007-01-05 17:41:07 +00008660 }
j_mayer28c5af52007-11-11 01:50:45 +00008661 if (netroms == 0) {
thseec85c22007-01-05 17:41:07 +00008662 fprintf(stderr, "No valid PXE rom found for network device\n");
8663 exit(1);
8664 }
thseec85c22007-01-05 17:41:07 +00008665 }
8666#endif
8667
bellard0824d6f2003-06-24 13:42:40 +00008668 /* init the memory */
balrog7fb4fdc2008-04-24 17:59:27 +00008669 phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
8670
8671 if (machine->ram_require & RAMSIZE_FIXED) {
8672 if (ram_size > 0) {
8673 if (ram_size < phys_ram_size) {
aurel32cd940062008-04-28 20:26:54 +00008674 fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
8675 machine->name, (unsigned long long) phys_ram_size);
balrog7fb4fdc2008-04-24 17:59:27 +00008676 exit(-1);
8677 }
8678
8679 phys_ram_size = ram_size;
8680 } else
8681 ram_size = phys_ram_size;
8682 } else {
aurel324fc5d072008-04-27 21:39:40 +00008683 if (ram_size == 0)
balrog7fb4fdc2008-04-24 17:59:27 +00008684 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
8685
8686 phys_ram_size += ram_size;
8687 }
ths9ae02552007-01-05 17:39:04 +00008688
bellardd993e022005-02-10 22:00:06 +00008689 phys_ram_base = qemu_vmalloc(phys_ram_size);
bellard7f7f9872003-10-30 01:11:23 +00008690 if (!phys_ram_base) {
8691 fprintf(stderr, "Could not allocate physical memory\n");
bellard0824d6f2003-06-24 13:42:40 +00008692 exit(1);
8693 }
8694
bellard26a5f132008-05-28 12:30:31 +00008695 /* init the dynamic translator */
8696 cpu_exec_init_all(tb_size * 1024 * 1024);
8697
bellard5905b2e2004-08-01 21:53:26 +00008698 bdrv_init();
thse4bcb142007-12-02 04:51:10 +00008699
8700 /* we always create the cdrom drive, even if no disk is there */
8701
8702 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00008703 drive_add(NULL, CDROM_ALIAS);
thse4bcb142007-12-02 04:51:10 +00008704
balrog9d413d12007-12-04 00:10:34 +00008705 /* we always create at least one floppy */
thse4bcb142007-12-02 04:51:10 +00008706
8707 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00008708 drive_add(NULL, FD_ALIAS, 0);
bellardc4b1fcc2004-03-14 21:44:30 +00008709
balrog9d413d12007-12-04 00:10:34 +00008710 /* we always create one sd slot, even if no card is in it */
8711
8712 if (nb_drives_opt < MAX_DRIVES)
balrog609497a2008-01-14 02:56:53 +00008713 drive_add(NULL, SD_ALIAS);
balrog9d413d12007-12-04 00:10:34 +00008714
ths96d30e42007-01-07 20:42:14 +00008715 /* open the virtual block devices */
bellardc4b1fcc2004-03-14 21:44:30 +00008716
thse4bcb142007-12-02 04:51:10 +00008717 for(i = 0; i < nb_drives_opt; i++)
balrog609497a2008-01-14 02:56:53 +00008718 if (drive_init(&drives_opt[i], snapshot, machine) == -1)
thse4bcb142007-12-02 04:51:10 +00008719 exit(1);
balrog3e3d5812007-04-30 02:09:25 +00008720
bellardc88676f2006-08-06 13:36:11 +00008721 register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
8722 register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
bellard8a7ddc32004-03-31 19:00:16 +00008723
bellard330d0412003-07-26 18:11:40 +00008724 init_ioports();
bellard0824d6f2003-06-24 13:42:40 +00008725
bellard313aa562003-08-10 21:52:11 +00008726 /* terminal init */
ths740733b2007-06-08 01:57:56 +00008727 memset(&display_state, 0, sizeof(display_state));
bellarda20dd502003-09-30 21:07:02 +00008728 if (nographic) {
balrog4d3b6f62008-02-10 16:33:14 +00008729 if (curses) {
8730 fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
8731 exit(1);
8732 }
ths2ff89792007-06-21 23:34:19 +00008733 /* nearly nothing to do */
8734 dumb_display_init(ds);
ths73fc9742006-12-22 02:09:07 +00008735 } else if (vnc_display != NULL) {
ths71cab5c2007-08-25 01:35:38 +00008736 vnc_display_init(ds);
8737 if (vnc_display_open(ds, vnc_display) < 0)
8738 exit(1);
balrog4d3b6f62008-02-10 16:33:14 +00008739 } else
8740#if defined(CONFIG_CURSES)
8741 if (curses) {
8742 curses_display_init(ds, full_screen);
8743 } else
8744#endif
8745 {
bellard5b0753e2005-03-01 21:37:28 +00008746#if defined(CONFIG_SDL)
ths43523e92007-02-18 18:19:32 +00008747 sdl_display_init(ds, full_screen, no_frame);
bellard5b0753e2005-03-01 21:37:28 +00008748#elif defined(CONFIG_COCOA)
8749 cocoa_display_init(ds, full_screen);
pbrook67276f52007-11-15 19:04:08 +00008750#else
8751 dumb_display_init(ds);
bellard313aa562003-08-10 21:52:11 +00008752#endif
8753 }
bellard0824d6f2003-06-24 13:42:40 +00008754
ths20d8a3e2007-02-18 17:04:49 +00008755 /* Maintain compatibility with multiple stdio monitors */
8756 if (!strcmp(monitor_device,"stdio")) {
8757 for (i = 0; i < MAX_SERIAL_PORTS; i++) {
pbrookfd5f3932008-03-26 20:55:43 +00008758 const char *devname = serial_devices[i];
8759 if (devname && !strcmp(devname,"mon:stdio")) {
8760 monitor_device = NULL;
ths20d8a3e2007-02-18 17:04:49 +00008761 break;
pbrookfd5f3932008-03-26 20:55:43 +00008762 } else if (devname && !strcmp(devname,"stdio")) {
8763 monitor_device = NULL;
8764 serial_devices[i] = "mon:stdio";
ths20d8a3e2007-02-18 17:04:49 +00008765 break;
8766 }
8767 }
bellard82c643f2004-07-14 17:28:13 +00008768 }
pbrookfd5f3932008-03-26 20:55:43 +00008769 if (monitor_device) {
ths20d8a3e2007-02-18 17:04:49 +00008770 monitor_hd = qemu_chr_open(monitor_device);
8771 if (!monitor_hd) {
8772 fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
8773 exit(1);
8774 }
8775 monitor_init(monitor_hd, !nographic);
8776 }
bellard82c643f2004-07-14 17:28:13 +00008777
bellard8d11df92004-08-24 21:13:40 +00008778 for(i = 0; i < MAX_SERIAL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00008779 const char *devname = serial_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00008780 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00008781 serial_hds[i] = qemu_chr_open(devname);
bellard8d11df92004-08-24 21:13:40 +00008782 if (!serial_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00008783 fprintf(stderr, "qemu: could not open serial device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00008784 devname);
bellard8d11df92004-08-24 21:13:40 +00008785 exit(1);
8786 }
thsaf3a9032007-07-11 23:14:59 +00008787 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00008788 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
bellard8d11df92004-08-24 21:13:40 +00008789 }
bellard82c643f2004-07-14 17:28:13 +00008790 }
bellard82c643f2004-07-14 17:28:13 +00008791
bellard6508fe52005-01-15 12:02:56 +00008792 for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
bellardc03b0f02006-09-03 14:10:53 +00008793 const char *devname = parallel_devices[i];
pbrookfd5f3932008-03-26 20:55:43 +00008794 if (devname && strcmp(devname, "none")) {
bellardc03b0f02006-09-03 14:10:53 +00008795 parallel_hds[i] = qemu_chr_open(devname);
bellard6508fe52005-01-15 12:02:56 +00008796 if (!parallel_hds[i]) {
ths5fafdf22007-09-16 21:08:06 +00008797 fprintf(stderr, "qemu: could not open parallel device '%s'\n",
bellardc03b0f02006-09-03 14:10:53 +00008798 devname);
bellard6508fe52005-01-15 12:02:56 +00008799 exit(1);
8800 }
thsaf3a9032007-07-11 23:14:59 +00008801 if (strstart(devname, "vc", 0))
bellard7ba12602006-07-14 20:26:42 +00008802 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
bellard6508fe52005-01-15 12:02:56 +00008803 }
8804 }
8805
blueswir1b881c2c2007-11-18 08:46:58 +00008806 machine->init(ram_size, vga_ram_size, boot_devices, ds,
j_mayer94fc95c2007-03-05 19:44:02 +00008807 kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
bellard73332e52004-04-04 20:22:28 +00008808
pbrook0d92ed32006-05-21 16:30:15 +00008809 /* init USB devices */
8810 if (usb_enabled) {
8811 for(i = 0; i < usb_devices_index; i++) {
8812 if (usb_device_add(usb_devices[i]) < 0) {
8813 fprintf(stderr, "Warning: could not add USB device %s\n",
8814 usb_devices[i]);
8815 }
8816 }
8817 }
8818
ths740733b2007-06-08 01:57:56 +00008819 if (display_state.dpy_refresh) {
8820 display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
8821 qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
8822 }
bellard7f7f9872003-10-30 01:11:23 +00008823
bellard67b915a2004-03-31 23:37:16 +00008824#ifdef CONFIG_GDBSTUB
bellardb4608c02003-06-27 17:34:32 +00008825 if (use_gdbstub) {
bellardc636bb62007-02-05 20:46:05 +00008826 /* XXX: use standard host:port notation and modify options
8827 accordingly. */
pbrookcfc34752007-02-22 01:48:01 +00008828 if (gdbserver_start(gdbstub_port) < 0) {
8829 fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
bellardc636bb62007-02-05 20:46:05 +00008830 gdbstub_port);
bellard8a7ddc32004-03-31 19:00:16 +00008831 exit(1);
bellard8a7ddc32004-03-31 19:00:16 +00008832 }
balrog45669e02007-07-02 13:20:17 +00008833 }
bellard67b915a2004-03-31 23:37:16 +00008834#endif
balrog45669e02007-07-02 13:20:17 +00008835
bellardd63d3072004-10-03 13:29:03 +00008836 if (loadvm)
bellardfaea38e2006-08-05 21:31:00 +00008837 do_loadvm(loadvm);
bellardd63d3072004-10-03 13:29:03 +00008838
bellard67b915a2004-03-31 23:37:16 +00008839 {
bellard5905b2e2004-08-01 21:53:26 +00008840 /* XXX: simplify init */
8841 read_passwords();
pbrook3c07f8e2007-01-21 16:47:01 +00008842 if (autostart) {
bellard5905b2e2004-08-01 21:53:26 +00008843 vm_start();
8844 }
bellard0824d6f2003-06-24 13:42:40 +00008845 }
thsffd843b2006-12-21 19:46:43 +00008846
ths71e3ceb2006-12-22 02:11:31 +00008847 if (daemonize) {
8848 uint8_t status = 0;
8849 ssize_t len;
8850 int fd;
8851
8852 again1:
8853 len = write(fds[1], &status, 1);
8854 if (len == -1 && (errno == EINTR))
8855 goto again1;
8856
8857 if (len != 1)
8858 exit(1);
8859
balrogaeb30be2007-07-02 15:03:13 +00008860 TFR(fd = open("/dev/null", O_RDWR));
ths71e3ceb2006-12-22 02:11:31 +00008861 if (fd == -1)
8862 exit(1);
8863
8864 dup2(fd, 0);
8865 dup2(fd, 1);
8866 dup2(fd, 2);
8867
8868 close(fd);
8869 }
8870
bellard8a7ddc32004-03-31 19:00:16 +00008871 main_loop();
bellard40c3bac2004-04-04 12:56:28 +00008872 quit_timers();
thsb46a8902007-10-21 23:20:45 +00008873
ths7d294b62007-10-26 17:21:58 +00008874#if !defined(_WIN32)
thsb46a8902007-10-21 23:20:45 +00008875 /* close network clients */
8876 for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8877 VLANClientState *vc;
8878
ths7d294b62007-10-26 17:21:58 +00008879 for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
thsb46a8902007-10-21 23:20:45 +00008880 if (vc->fd_read == tap_receive) {
8881 char ifname[64];
8882 TAPState *s = vc->opaque;
8883
8884 if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
8885 s->down_script[0])
8886 launch_script(s->down_script, ifname, s->fd);
8887 }
ths4fddf622007-12-17 04:42:29 +00008888 }
ths7d294b62007-10-26 17:21:58 +00008889 }
8890#endif
bellard0824d6f2003-06-24 13:42:40 +00008891 return 0;
8892}