Statistics
| Branch: | Revision:

root / vl.c @ 3f47aa8c

History | View | Annotate | Download (236 kB)

1 0824d6fc bellard
/*
2 80cabfad bellard
 * QEMU System Emulator
3 5fafdf24 ths
 *
4 68d0f70e bellard
 * Copyright (c) 2003-2008 Fabrice Bellard
5 5fafdf24 ths
 *
6 1df912cf bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1df912cf bellard
 * of this software and associated documentation files (the "Software"), to deal
8 1df912cf bellard
 * in the Software without restriction, including without limitation the rights
9 1df912cf bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1df912cf bellard
 * copies of the Software, and to permit persons to whom the Software is
11 1df912cf bellard
 * furnished to do so, subject to the following conditions:
12 1df912cf bellard
 *
13 1df912cf bellard
 * The above copyright notice and this permission notice shall be included in
14 1df912cf bellard
 * all copies or substantial portions of the Software.
15 1df912cf bellard
 *
16 1df912cf bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1df912cf bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1df912cf bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1df912cf bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1df912cf bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1df912cf bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1df912cf bellard
 * THE SOFTWARE.
23 0824d6fc bellard
 */
24 87ecb68b pbrook
#include "hw/hw.h"
25 87ecb68b pbrook
#include "hw/boards.h"
26 87ecb68b pbrook
#include "hw/usb.h"
27 87ecb68b pbrook
#include "hw/pcmcia.h"
28 87ecb68b pbrook
#include "hw/pc.h"
29 87ecb68b pbrook
#include "hw/fdc.h"
30 87ecb68b pbrook
#include "hw/audiodev.h"
31 87ecb68b pbrook
#include "hw/isa.h"
32 87ecb68b pbrook
#include "net.h"
33 87ecb68b pbrook
#include "console.h"
34 87ecb68b pbrook
#include "sysemu.h"
35 87ecb68b pbrook
#include "gdbstub.h"
36 87ecb68b pbrook
#include "qemu-timer.h"
37 87ecb68b pbrook
#include "qemu-char.h"
38 87ecb68b pbrook
#include "block.h"
39 87ecb68b pbrook
#include "audio/audio.h"
40 67b915a5 bellard
41 0824d6fc bellard
#include <unistd.h>
42 0824d6fc bellard
#include <fcntl.h>
43 0824d6fc bellard
#include <signal.h>
44 0824d6fc bellard
#include <time.h>
45 0824d6fc bellard
#include <errno.h>
46 67b915a5 bellard
#include <sys/time.h>
47 c88676f8 bellard
#include <zlib.h>
48 67b915a5 bellard
49 67b915a5 bellard
#ifndef _WIN32
50 67b915a5 bellard
#include <sys/times.h>
51 f1510b2c bellard
#include <sys/wait.h>
52 67b915a5 bellard
#include <termios.h>
53 67b915a5 bellard
#include <sys/poll.h>
54 67b915a5 bellard
#include <sys/mman.h>
55 f1510b2c bellard
#include <sys/ioctl.h>
56 f1510b2c bellard
#include <sys/socket.h>
57 c94c8d64 bellard
#include <netinet/in.h>
58 9d728e8c bellard
#include <dirent.h>
59 7c9d8e07 bellard
#include <netdb.h>
60 cb4b976b ths
#include <sys/select.h>
61 cb4b976b ths
#include <arpa/inet.h>
62 7d3505c5 bellard
#ifdef _BSD
63 7d3505c5 bellard
#include <sys/stat.h>
64 83fb7adf bellard
#ifndef __APPLE__
65 7d3505c5 bellard
#include <libutil.h>
66 83fb7adf bellard
#endif
67 5c40d2bd ths
#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
68 5c40d2bd ths
#include <freebsd/stdlib.h>
69 7d3505c5 bellard
#else
70 ec530c81 bellard
#ifndef __sun__
71 f1510b2c bellard
#include <linux/if.h>
72 f1510b2c bellard
#include <linux/if_tun.h>
73 7d3505c5 bellard
#include <pty.h>
74 7d3505c5 bellard
#include <malloc.h>
75 fd872598 bellard
#include <linux/rtc.h>
76 bd494f4c ths
77 bd494f4c ths
/* For the benefit of older linux systems which don't supply it,
78 bd494f4c ths
   we use a local copy of hpet.h. */
79 bd494f4c ths
/* #include <linux/hpet.h> */
80 bd494f4c ths
#include "hpet.h"
81 bd494f4c ths
82 e57a8c0e bellard
#include <linux/ppdev.h>
83 5867c88a ths
#include <linux/parport.h>
84 d5d10bc3 ths
#else
85 d5d10bc3 ths
#include <sys/stat.h>
86 d5d10bc3 ths
#include <sys/ethernet.h>
87 d5d10bc3 ths
#include <sys/sockio.h>
88 d5d10bc3 ths
#include <netinet/arp.h>
89 d5d10bc3 ths
#include <netinet/in.h>
90 d5d10bc3 ths
#include <netinet/in_systm.h>
91 d5d10bc3 ths
#include <netinet/ip.h>
92 d5d10bc3 ths
#include <netinet/ip_icmp.h> // must come after ip.h
93 d5d10bc3 ths
#include <netinet/udp.h>
94 d5d10bc3 ths
#include <netinet/tcp.h>
95 d5d10bc3 ths
#include <net/if.h>
96 d5d10bc3 ths
#include <syslog.h>
97 d5d10bc3 ths
#include <stropts.h>
98 67b915a5 bellard
#endif
99 7d3505c5 bellard
#endif
100 cb4b976b ths
#else
101 cb4b976b ths
#include <winsock2.h>
102 cb4b976b ths
int inet_aton(const char *cp, struct in_addr *ia);
103 ec530c81 bellard
#endif
104 67b915a5 bellard
105 c20709aa bellard
#if defined(CONFIG_SLIRP)
106 c20709aa bellard
#include "libslirp.h"
107 c20709aa bellard
#endif
108 c20709aa bellard
109 67b915a5 bellard
#ifdef _WIN32
110 7d3505c5 bellard
#include <malloc.h>
111 67b915a5 bellard
#include <sys/timeb.h>
112 4fddf62a ths
#include <mmsystem.h>
113 67b915a5 bellard
#define getopt_long_only getopt_long
114 67b915a5 bellard
#define memalign(align, size) malloc(size)
115 67b915a5 bellard
#endif
116 67b915a5 bellard
117 6ca957f0 bellard
#include "qemu_socket.h"
118 6ca957f0 bellard
119 73332e5c bellard
#ifdef CONFIG_SDL
120 96bcd4f8 bellard
#ifdef __APPLE__
121 83fb7adf bellard
#include <SDL/SDL.h>
122 96bcd4f8 bellard
#endif
123 73332e5c bellard
#endif /* CONFIG_SDL */
124 0824d6fc bellard
125 5b0753e0 bellard
#ifdef CONFIG_COCOA
126 5b0753e0 bellard
#undef main
127 5b0753e0 bellard
#define main qemu_main
128 5b0753e0 bellard
#endif /* CONFIG_COCOA */
129 5b0753e0 bellard
130 0824d6fc bellard
#include "disas.h"
131 fc01f7e7 bellard
132 8a7ddc38 bellard
#include "exec-all.h"
133 0824d6fc bellard
134 5a67135a bellard
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
135 b46a8906 ths
#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
136 a14d6c8c pbrook
#ifdef __sun__
137 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
138 a14d6c8c pbrook
#else
139 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sbin/smbd"
140 a14d6c8c pbrook
#endif
141 f1510b2c bellard
142 0824d6fc bellard
//#define DEBUG_UNUSED_IOPORT
143 fd872598 bellard
//#define DEBUG_IOPORT
144 330d0414 bellard
145 bb551faa bellard
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
146 7916e224 bellard
147 77d4bc34 bellard
#ifdef TARGET_PPC
148 77d4bc34 bellard
#define DEFAULT_RAM_SIZE 144
149 77d4bc34 bellard
#else
150 1bfe856e bellard
#define DEFAULT_RAM_SIZE 128
151 77d4bc34 bellard
#endif
152 8a7ddc38 bellard
/* in ms */
153 8a7ddc38 bellard
#define GUI_REFRESH_INTERVAL 30
154 313aa567 bellard
155 0d92ed30 pbrook
/* Max number of USB devices that can be specified on the commandline.  */
156 0d92ed30 pbrook
#define MAX_USB_CMDLINE 8
157 0d92ed30 pbrook
158 7dea1da4 bellard
/* XXX: use a two level table to limit memory usage */
159 7dea1da4 bellard
#define MAX_IOPORTS 65536
160 0824d6fc bellard
161 80cabfad bellard
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
162 1192dad8 j_mayer
const char *bios_name = NULL;
163 c4b1fcc0 bellard
void *ioport_opaque[MAX_IOPORTS];
164 fc01f7e7 bellard
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
165 fc01f7e7 bellard
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
166 e4bcb14c ths
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
167 faea38e7 bellard
   to store the VM snapshots */
168 e4bcb14c ths
DriveInfo drives_table[MAX_DRIVES+1];
169 e4bcb14c ths
int nb_drives;
170 faea38e7 bellard
/* point to the block driver where the snapshots are managed */
171 faea38e7 bellard
BlockDriverState *bs_snapshots;
172 313aa567 bellard
int vga_ram_size;
173 313aa567 bellard
static DisplayState display_state;
174 a20dd508 bellard
int nographic;
175 4d3b6f6e balrog
int curses;
176 3d11d0eb bellard
const char* keyboard_layout = NULL;
177 313aa567 bellard
int64_t ticks_per_sec;
178 0ced6589 bellard
int ram_size;
179 80cabfad bellard
int pit_min_timer_count = 0;
180 c4b1fcc0 bellard
int nb_nics;
181 7c9d8e07 bellard
NICInfo nd_table[MAX_NICS];
182 8a7ddc38 bellard
int vm_running;
183 f6503059 balrog
static int rtc_utc = 1;
184 f6503059 balrog
static int rtc_date_offset = -1; /* -1 means no change */
185 1bfe856e bellard
int cirrus_vga_enabled = 1;
186 d34cab9f ths
int vmsvga_enabled = 0;
187 d827220b bellard
#ifdef TARGET_SPARC
188 d827220b bellard
int graphic_width = 1024;
189 d827220b bellard
int graphic_height = 768;
190 eee0b836 blueswir1
int graphic_depth = 8;
191 d827220b bellard
#else
192 1bfe856e bellard
int graphic_width = 800;
193 1bfe856e bellard
int graphic_height = 600;
194 e9b137c2 bellard
int graphic_depth = 15;
195 eee0b836 blueswir1
#endif
196 d63d307f bellard
int full_screen = 0;
197 43523e93 ths
int no_frame = 0;
198 667accab ths
int no_quit = 0;
199 8d11df9e bellard
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
200 6508fe59 bellard
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
201 a09db21f bellard
#ifdef TARGET_I386
202 a09db21f bellard
int win2k_install_hack = 0;
203 a09db21f bellard
#endif
204 bb36d470 bellard
int usb_enabled = 0;
205 7c9d8e07 bellard
static VLANState *first_vlan;
206 6a00d601 bellard
int smp_cpus = 1;
207 73fc9742 ths
const char *vnc_display;
208 d3e9db93 bellard
#if defined(TARGET_SPARC)
209 ba3c64fb bellard
#define MAX_CPUS 16
210 d3e9db93 bellard
#elif defined(TARGET_I386)
211 d3e9db93 bellard
#define MAX_CPUS 255
212 ba3c64fb bellard
#else
213 d3e9db93 bellard
#define MAX_CPUS 1
214 ba3c64fb bellard
#endif
215 6515b203 bellard
int acpi_enabled = 1;
216 52ca8d6a bellard
int fd_bootchk = 1;
217 d1beab82 bellard
int no_reboot = 0;
218 9467cd46 balrog
int cursor_hide = 1;
219 a171fe39 balrog
int graphic_rotate = 0;
220 71e3ceb8 ths
int daemonize = 0;
221 9ae02555 ths
const char *option_rom[MAX_OPTION_ROMS];
222 9ae02555 ths
int nb_option_roms;
223 8e71621f pbrook
int semihosting_enabled = 0;
224 3c07f8e8 pbrook
int autostart = 1;
225 2b8f2d41 balrog
#ifdef TARGET_ARM
226 2b8f2d41 balrog
int old_param = 0;
227 2b8f2d41 balrog
#endif
228 c35734b2 ths
const char *qemu_name;
229 3780e197 ths
int alt_grab = 0;
230 66508601 blueswir1
#ifdef TARGET_SPARC
231 66508601 blueswir1
unsigned int nb_prom_envs = 0;
232 66508601 blueswir1
const char *prom_envs[MAX_PROM_ENVS];
233 66508601 blueswir1
#endif
234 e4bcb14c ths
int nb_drives_opt;
235 609497ab balrog
struct drive_opt {
236 609497ab balrog
    const char *file;
237 609497ab balrog
    char opt[1024];
238 609497ab balrog
} drives_opt[MAX_DRIVES];
239 0824d6fc bellard
240 ee5605e5 balrog
static CPUState *cur_cpu;
241 ee5605e5 balrog
static CPUState *next_cpu;
242 76ea08f9 balrog
static int event_pending = 1;
243 ee5605e5 balrog
244 aeb30be6 balrog
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
245 aeb30be6 balrog
246 0824d6fc bellard
/***********************************************************/
247 26aa7d72 bellard
/* x86 ISA bus support */
248 26aa7d72 bellard
249 26aa7d72 bellard
target_phys_addr_t isa_mem_base = 0;
250 3de388f6 bellard
PicState2 *isa_pic;
251 0824d6fc bellard
252 9596ebb7 pbrook
static uint32_t default_ioport_readb(void *opaque, uint32_t address)
253 0824d6fc bellard
{
254 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
255 1196be37 ths
    fprintf(stderr, "unused inb: port=0x%04x\n", address);
256 0824d6fc bellard
#endif
257 fc01f7e7 bellard
    return 0xff;
258 0824d6fc bellard
}
259 0824d6fc bellard
260 9596ebb7 pbrook
static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
261 0824d6fc bellard
{
262 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
263 1196be37 ths
    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
264 0824d6fc bellard
#endif
265 0824d6fc bellard
}
266 0824d6fc bellard
267 0824d6fc bellard
/* default is to make two byte accesses */
268 9596ebb7 pbrook
static uint32_t default_ioport_readw(void *opaque, uint32_t address)
269 0824d6fc bellard
{
270 0824d6fc bellard
    uint32_t data;
271 db45c29a bellard
    data = ioport_read_table[0][address](ioport_opaque[address], address);
272 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
273 db45c29a bellard
    data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
274 0824d6fc bellard
    return data;
275 0824d6fc bellard
}
276 0824d6fc bellard
277 9596ebb7 pbrook
static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
278 0824d6fc bellard
{
279 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
280 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
281 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
282 0824d6fc bellard
}
283 0824d6fc bellard
284 9596ebb7 pbrook
static uint32_t default_ioport_readl(void *opaque, uint32_t address)
285 0824d6fc bellard
{
286 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
287 1196be37 ths
    fprintf(stderr, "unused inl: port=0x%04x\n", address);
288 fc01f7e7 bellard
#endif
289 fc01f7e7 bellard
    return 0xffffffff;
290 0824d6fc bellard
}
291 0824d6fc bellard
292 9596ebb7 pbrook
static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
293 0824d6fc bellard
{
294 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
295 1196be37 ths
    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
296 fc01f7e7 bellard
#endif
297 0824d6fc bellard
}
298 0824d6fc bellard
299 9596ebb7 pbrook
static void init_ioports(void)
300 0824d6fc bellard
{
301 0824d6fc bellard
    int i;
302 0824d6fc bellard
303 fc01f7e7 bellard
    for(i = 0; i < MAX_IOPORTS; i++) {
304 fc01f7e7 bellard
        ioport_read_table[0][i] = default_ioport_readb;
305 fc01f7e7 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
306 fc01f7e7 bellard
        ioport_read_table[1][i] = default_ioport_readw;
307 fc01f7e7 bellard
        ioport_write_table[1][i] = default_ioport_writew;
308 fc01f7e7 bellard
        ioport_read_table[2][i] = default_ioport_readl;
309 fc01f7e7 bellard
        ioport_write_table[2][i] = default_ioport_writel;
310 fc01f7e7 bellard
    }
311 0824d6fc bellard
}
312 0824d6fc bellard
313 fc01f7e7 bellard
/* size is the word size in byte */
314 5fafdf24 ths
int register_ioport_read(int start, int length, int size,
315 c4b1fcc0 bellard
                         IOPortReadFunc *func, void *opaque)
316 f1510b2c bellard
{
317 fc01f7e7 bellard
    int i, bsize;
318 f1510b2c bellard
319 c4b1fcc0 bellard
    if (size == 1) {
320 fc01f7e7 bellard
        bsize = 0;
321 c4b1fcc0 bellard
    } else if (size == 2) {
322 fc01f7e7 bellard
        bsize = 1;
323 c4b1fcc0 bellard
    } else if (size == 4) {
324 fc01f7e7 bellard
        bsize = 2;
325 c4b1fcc0 bellard
    } else {
326 c4b1fcc0 bellard
        hw_error("register_ioport_read: invalid size");
327 fc01f7e7 bellard
        return -1;
328 c4b1fcc0 bellard
    }
329 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
330 fc01f7e7 bellard
        ioport_read_table[bsize][i] = func;
331 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
332 c4b1fcc0 bellard
            hw_error("register_ioport_read: invalid opaque");
333 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
334 c4b1fcc0 bellard
    }
335 f1510b2c bellard
    return 0;
336 f1510b2c bellard
}
337 f1510b2c bellard
338 fc01f7e7 bellard
/* size is the word size in byte */
339 5fafdf24 ths
int register_ioport_write(int start, int length, int size,
340 c4b1fcc0 bellard
                          IOPortWriteFunc *func, void *opaque)
341 f1510b2c bellard
{
342 fc01f7e7 bellard
    int i, bsize;
343 f1510b2c bellard
344 c4b1fcc0 bellard
    if (size == 1) {
345 fc01f7e7 bellard
        bsize = 0;
346 c4b1fcc0 bellard
    } else if (size == 2) {
347 fc01f7e7 bellard
        bsize = 1;
348 c4b1fcc0 bellard
    } else if (size == 4) {
349 fc01f7e7 bellard
        bsize = 2;
350 c4b1fcc0 bellard
    } else {
351 c4b1fcc0 bellard
        hw_error("register_ioport_write: invalid size");
352 fc01f7e7 bellard
        return -1;
353 c4b1fcc0 bellard
    }
354 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
355 fc01f7e7 bellard
        ioport_write_table[bsize][i] = func;
356 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
357 52f61fde ths
            hw_error("register_ioport_write: invalid opaque");
358 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
359 c4b1fcc0 bellard
    }
360 f1510b2c bellard
    return 0;
361 f1510b2c bellard
}
362 f1510b2c bellard
363 69b91039 bellard
void isa_unassign_ioport(int start, int length)
364 69b91039 bellard
{
365 69b91039 bellard
    int i;
366 69b91039 bellard
367 69b91039 bellard
    for(i = start; i < start + length; i++) {
368 69b91039 bellard
        ioport_read_table[0][i] = default_ioport_readb;
369 69b91039 bellard
        ioport_read_table[1][i] = default_ioport_readw;
370 69b91039 bellard
        ioport_read_table[2][i] = default_ioport_readl;
371 69b91039 bellard
372 69b91039 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
373 69b91039 bellard
        ioport_write_table[1][i] = default_ioport_writew;
374 69b91039 bellard
        ioport_write_table[2][i] = default_ioport_writel;
375 69b91039 bellard
    }
376 69b91039 bellard
}
377 69b91039 bellard
378 20f32282 bellard
/***********************************************************/
379 20f32282 bellard
380 c45886db bellard
void cpu_outb(CPUState *env, int addr, int val)
381 0824d6fc bellard
{
382 fd872598 bellard
#ifdef DEBUG_IOPORT
383 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
384 fd872598 bellard
        fprintf(logfile, "outb: %04x %02x\n", addr, val);
385 3b46e624 ths
#endif
386 c4b1fcc0 bellard
    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
387 89bfc105 bellard
#ifdef USE_KQEMU
388 89bfc105 bellard
    if (env)
389 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
390 89bfc105 bellard
#endif
391 0824d6fc bellard
}
392 0824d6fc bellard
393 c45886db bellard
void cpu_outw(CPUState *env, int addr, int val)
394 0824d6fc bellard
{
395 fd872598 bellard
#ifdef DEBUG_IOPORT
396 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
397 fd872598 bellard
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
398 3b46e624 ths
#endif
399 c4b1fcc0 bellard
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
400 89bfc105 bellard
#ifdef USE_KQEMU
401 89bfc105 bellard
    if (env)
402 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
403 89bfc105 bellard
#endif
404 0824d6fc bellard
}
405 0824d6fc bellard
406 c45886db bellard
void cpu_outl(CPUState *env, int addr, int val)
407 0824d6fc bellard
{
408 fd872598 bellard
#ifdef DEBUG_IOPORT
409 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
410 fd872598 bellard
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
411 fd872598 bellard
#endif
412 c4b1fcc0 bellard
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
413 89bfc105 bellard
#ifdef USE_KQEMU
414 89bfc105 bellard
    if (env)
415 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
416 89bfc105 bellard
#endif
417 0824d6fc bellard
}
418 0824d6fc bellard
419 c45886db bellard
int cpu_inb(CPUState *env, int addr)
420 0824d6fc bellard
{
421 fd872598 bellard
    int val;
422 fd872598 bellard
    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
423 fd872598 bellard
#ifdef DEBUG_IOPORT
424 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
425 fd872598 bellard
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
426 fd872598 bellard
#endif
427 89bfc105 bellard
#ifdef USE_KQEMU
428 89bfc105 bellard
    if (env)
429 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
430 89bfc105 bellard
#endif
431 fd872598 bellard
    return val;
432 0824d6fc bellard
}
433 0824d6fc bellard
434 c45886db bellard
int cpu_inw(CPUState *env, int addr)
435 0824d6fc bellard
{
436 fd872598 bellard
    int val;
437 fd872598 bellard
    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
438 fd872598 bellard
#ifdef DEBUG_IOPORT
439 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
440 fd872598 bellard
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
441 fd872598 bellard
#endif
442 89bfc105 bellard
#ifdef USE_KQEMU
443 89bfc105 bellard
    if (env)
444 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
445 89bfc105 bellard
#endif
446 fd872598 bellard
    return val;
447 0824d6fc bellard
}
448 0824d6fc bellard
449 c45886db bellard
int cpu_inl(CPUState *env, int addr)
450 0824d6fc bellard
{
451 fd872598 bellard
    int val;
452 fd872598 bellard
    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
453 fd872598 bellard
#ifdef DEBUG_IOPORT
454 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
455 fd872598 bellard
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
456 fd872598 bellard
#endif
457 89bfc105 bellard
#ifdef USE_KQEMU
458 89bfc105 bellard
    if (env)
459 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
460 89bfc105 bellard
#endif
461 fd872598 bellard
    return val;
462 0824d6fc bellard
}
463 0824d6fc bellard
464 0824d6fc bellard
/***********************************************************/
465 0824d6fc bellard
void hw_error(const char *fmt, ...)
466 0824d6fc bellard
{
467 0824d6fc bellard
    va_list ap;
468 6a00d601 bellard
    CPUState *env;
469 0824d6fc bellard
470 0824d6fc bellard
    va_start(ap, fmt);
471 0824d6fc bellard
    fprintf(stderr, "qemu: hardware error: ");
472 0824d6fc bellard
    vfprintf(stderr, fmt, ap);
473 0824d6fc bellard
    fprintf(stderr, "\n");
474 6a00d601 bellard
    for(env = first_cpu; env != NULL; env = env->next_cpu) {
475 6a00d601 bellard
        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
476 0824d6fc bellard
#ifdef TARGET_I386
477 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
478 c45886db bellard
#else
479 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, 0);
480 0824d6fc bellard
#endif
481 6a00d601 bellard
    }
482 0824d6fc bellard
    va_end(ap);
483 0824d6fc bellard
    abort();
484 0824d6fc bellard
}
485 0824d6fc bellard
486 8a7ddc38 bellard
/***********************************************************/
487 63066f4f bellard
/* keyboard/mouse */
488 63066f4f bellard
489 63066f4f bellard
static QEMUPutKBDEvent *qemu_put_kbd_event;
490 63066f4f bellard
static void *qemu_put_kbd_event_opaque;
491 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_head;
492 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_current;
493 63066f4f bellard
494 63066f4f bellard
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
495 63066f4f bellard
{
496 63066f4f bellard
    qemu_put_kbd_event_opaque = opaque;
497 63066f4f bellard
    qemu_put_kbd_event = func;
498 63066f4f bellard
}
499 63066f4f bellard
500 455204eb ths
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
501 455204eb ths
                                                void *opaque, int absolute,
502 455204eb ths
                                                const char *name)
503 63066f4f bellard
{
504 455204eb ths
    QEMUPutMouseEntry *s, *cursor;
505 455204eb ths
506 455204eb ths
    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
507 455204eb ths
    if (!s)
508 455204eb ths
        return NULL;
509 455204eb ths
510 455204eb ths
    s->qemu_put_mouse_event = func;
511 455204eb ths
    s->qemu_put_mouse_event_opaque = opaque;
512 455204eb ths
    s->qemu_put_mouse_event_absolute = absolute;
513 455204eb ths
    s->qemu_put_mouse_event_name = qemu_strdup(name);
514 455204eb ths
    s->next = NULL;
515 455204eb ths
516 455204eb ths
    if (!qemu_put_mouse_event_head) {
517 455204eb ths
        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
518 455204eb ths
        return s;
519 455204eb ths
    }
520 455204eb ths
521 455204eb ths
    cursor = qemu_put_mouse_event_head;
522 455204eb ths
    while (cursor->next != NULL)
523 455204eb ths
        cursor = cursor->next;
524 455204eb ths
525 455204eb ths
    cursor->next = s;
526 455204eb ths
    qemu_put_mouse_event_current = s;
527 455204eb ths
528 455204eb ths
    return s;
529 455204eb ths
}
530 455204eb ths
531 455204eb ths
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
532 455204eb ths
{
533 455204eb ths
    QEMUPutMouseEntry *prev = NULL, *cursor;
534 455204eb ths
535 455204eb ths
    if (!qemu_put_mouse_event_head || entry == NULL)
536 455204eb ths
        return;
537 455204eb ths
538 455204eb ths
    cursor = qemu_put_mouse_event_head;
539 455204eb ths
    while (cursor != NULL && cursor != entry) {
540 455204eb ths
        prev = cursor;
541 455204eb ths
        cursor = cursor->next;
542 455204eb ths
    }
543 455204eb ths
544 455204eb ths
    if (cursor == NULL) // does not exist or list empty
545 455204eb ths
        return;
546 455204eb ths
    else if (prev == NULL) { // entry is head
547 455204eb ths
        qemu_put_mouse_event_head = cursor->next;
548 455204eb ths
        if (qemu_put_mouse_event_current == entry)
549 455204eb ths
            qemu_put_mouse_event_current = cursor->next;
550 455204eb ths
        qemu_free(entry->qemu_put_mouse_event_name);
551 455204eb ths
        qemu_free(entry);
552 455204eb ths
        return;
553 455204eb ths
    }
554 455204eb ths
555 455204eb ths
    prev->next = entry->next;
556 455204eb ths
557 455204eb ths
    if (qemu_put_mouse_event_current == entry)
558 455204eb ths
        qemu_put_mouse_event_current = prev;
559 455204eb ths
560 455204eb ths
    qemu_free(entry->qemu_put_mouse_event_name);
561 455204eb ths
    qemu_free(entry);
562 63066f4f bellard
}
563 63066f4f bellard
564 63066f4f bellard
void kbd_put_keycode(int keycode)
565 63066f4f bellard
{
566 63066f4f bellard
    if (qemu_put_kbd_event) {
567 63066f4f bellard
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
568 63066f4f bellard
    }
569 63066f4f bellard
}
570 63066f4f bellard
571 63066f4f bellard
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
572 63066f4f bellard
{
573 455204eb ths
    QEMUPutMouseEvent *mouse_event;
574 455204eb ths
    void *mouse_event_opaque;
575 a171fe39 balrog
    int width;
576 455204eb ths
577 455204eb ths
    if (!qemu_put_mouse_event_current) {
578 455204eb ths
        return;
579 455204eb ths
    }
580 455204eb ths
581 455204eb ths
    mouse_event =
582 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event;
583 455204eb ths
    mouse_event_opaque =
584 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
585 455204eb ths
586 455204eb ths
    if (mouse_event) {
587 a171fe39 balrog
        if (graphic_rotate) {
588 a171fe39 balrog
            if (qemu_put_mouse_event_current->qemu_put_mouse_event_absolute)
589 a171fe39 balrog
                width = 0x7fff;
590 a171fe39 balrog
            else
591 a171fe39 balrog
                width = graphic_width;
592 a171fe39 balrog
            mouse_event(mouse_event_opaque,
593 a171fe39 balrog
                                 width - dy, dx, dz, buttons_state);
594 a171fe39 balrog
        } else
595 a171fe39 balrog
            mouse_event(mouse_event_opaque,
596 a171fe39 balrog
                                 dx, dy, dz, buttons_state);
597 63066f4f bellard
    }
598 63066f4f bellard
}
599 63066f4f bellard
600 09b26c5e bellard
int kbd_mouse_is_absolute(void)
601 09b26c5e bellard
{
602 455204eb ths
    if (!qemu_put_mouse_event_current)
603 455204eb ths
        return 0;
604 455204eb ths
605 455204eb ths
    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
606 455204eb ths
}
607 455204eb ths
608 455204eb ths
void do_info_mice(void)
609 455204eb ths
{
610 455204eb ths
    QEMUPutMouseEntry *cursor;
611 455204eb ths
    int index = 0;
612 455204eb ths
613 455204eb ths
    if (!qemu_put_mouse_event_head) {
614 455204eb ths
        term_printf("No mouse devices connected\n");
615 455204eb ths
        return;
616 455204eb ths
    }
617 455204eb ths
618 455204eb ths
    term_printf("Mouse devices available:\n");
619 455204eb ths
    cursor = qemu_put_mouse_event_head;
620 455204eb ths
    while (cursor != NULL) {
621 455204eb ths
        term_printf("%c Mouse #%d: %s\n",
622 455204eb ths
                    (cursor == qemu_put_mouse_event_current ? '*' : ' '),
623 455204eb ths
                    index, cursor->qemu_put_mouse_event_name);
624 455204eb ths
        index++;
625 455204eb ths
        cursor = cursor->next;
626 455204eb ths
    }
627 455204eb ths
}
628 455204eb ths
629 455204eb ths
void do_mouse_set(int index)
630 455204eb ths
{
631 455204eb ths
    QEMUPutMouseEntry *cursor;
632 455204eb ths
    int i = 0;
633 455204eb ths
634 455204eb ths
    if (!qemu_put_mouse_event_head) {
635 455204eb ths
        term_printf("No mouse devices connected\n");
636 455204eb ths
        return;
637 455204eb ths
    }
638 455204eb ths
639 455204eb ths
    cursor = qemu_put_mouse_event_head;
640 455204eb ths
    while (cursor != NULL && index != i) {
641 455204eb ths
        i++;
642 455204eb ths
        cursor = cursor->next;
643 455204eb ths
    }
644 455204eb ths
645 455204eb ths
    if (cursor != NULL)
646 455204eb ths
        qemu_put_mouse_event_current = cursor;
647 455204eb ths
    else
648 455204eb ths
        term_printf("Mouse at given index not found\n");
649 09b26c5e bellard
}
650 09b26c5e bellard
651 1dce7c3c bellard
/* compute with 96 bit intermediate result: (a*b)/c */
652 1dce7c3c bellard
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
653 0824d6fc bellard
{
654 1dce7c3c bellard
    union {
655 1dce7c3c bellard
        uint64_t ll;
656 1dce7c3c bellard
        struct {
657 1dce7c3c bellard
#ifdef WORDS_BIGENDIAN
658 1dce7c3c bellard
            uint32_t high, low;
659 1dce7c3c bellard
#else
660 1dce7c3c bellard
            uint32_t low, high;
661 3b46e624 ths
#endif
662 1dce7c3c bellard
        } l;
663 1dce7c3c bellard
    } u, res;
664 1dce7c3c bellard
    uint64_t rl, rh;
665 0824d6fc bellard
666 1dce7c3c bellard
    u.ll = a;
667 1dce7c3c bellard
    rl = (uint64_t)u.l.low * (uint64_t)b;
668 1dce7c3c bellard
    rh = (uint64_t)u.l.high * (uint64_t)b;
669 1dce7c3c bellard
    rh += (rl >> 32);
670 1dce7c3c bellard
    res.l.high = rh / c;
671 1dce7c3c bellard
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
672 1dce7c3c bellard
    return res.ll;
673 34865134 bellard
}
674 34865134 bellard
675 1dce7c3c bellard
/***********************************************************/
676 1dce7c3c bellard
/* real time host monotonic timer */
677 34865134 bellard
678 1dce7c3c bellard
#define QEMU_TIMER_BASE 1000000000LL
679 34865134 bellard
680 1dce7c3c bellard
#ifdef WIN32
681 0824d6fc bellard
682 1dce7c3c bellard
static int64_t clock_freq;
683 1115dde7 bellard
684 1dce7c3c bellard
static void init_get_clock(void)
685 1115dde7 bellard
{
686 a8e5ac33 bellard
    LARGE_INTEGER freq;
687 a8e5ac33 bellard
    int ret;
688 1dce7c3c bellard
    ret = QueryPerformanceFrequency(&freq);
689 1dce7c3c bellard
    if (ret == 0) {
690 1dce7c3c bellard
        fprintf(stderr, "Could not calibrate ticks\n");
691 1dce7c3c bellard
        exit(1);
692 1dce7c3c bellard
    }
693 1dce7c3c bellard
    clock_freq = freq.QuadPart;
694 1115dde7 bellard
}
695 1115dde7 bellard
696 1dce7c3c bellard
static int64_t get_clock(void)
697 b8076a74 bellard
{
698 1dce7c3c bellard
    LARGE_INTEGER ti;
699 1dce7c3c bellard
    QueryPerformanceCounter(&ti);
700 1dce7c3c bellard
    return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
701 b8076a74 bellard
}
702 b8076a74 bellard
703 1dce7c3c bellard
#else
704 90cb9493 bellard
705 1dce7c3c bellard
static int use_rt_clock;
706 1dce7c3c bellard
707 1dce7c3c bellard
static void init_get_clock(void)
708 90cb9493 bellard
{
709 1dce7c3c bellard
    use_rt_clock = 0;
710 1dce7c3c bellard
#if defined(__linux__)
711 1dce7c3c bellard
    {
712 1dce7c3c bellard
        struct timespec ts;
713 1dce7c3c bellard
        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
714 1dce7c3c bellard
            use_rt_clock = 1;
715 1dce7c3c bellard
        }
716 1dce7c3c bellard
    }
717 1dce7c3c bellard
#endif
718 90cb9493 bellard
}
719 90cb9493 bellard
720 1dce7c3c bellard
static int64_t get_clock(void)
721 fdbb4691 bellard
{
722 1dce7c3c bellard
#if defined(__linux__)
723 1dce7c3c bellard
    if (use_rt_clock) {
724 1dce7c3c bellard
        struct timespec ts;
725 1dce7c3c bellard
        clock_gettime(CLOCK_MONOTONIC, &ts);
726 1dce7c3c bellard
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
727 5fafdf24 ths
    } else
728 fdbb4691 bellard
#endif
729 1dce7c3c bellard
    {
730 1dce7c3c bellard
        /* XXX: using gettimeofday leads to problems if the date
731 1dce7c3c bellard
           changes, so it should be avoided. */
732 1dce7c3c bellard
        struct timeval tv;
733 1dce7c3c bellard
        gettimeofday(&tv, NULL);
734 1dce7c3c bellard
        return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
735 1dce7c3c bellard
    }
736 fdbb4691 bellard
}
737 fdbb4691 bellard
738 34865134 bellard
#endif
739 34865134 bellard
740 1dce7c3c bellard
/***********************************************************/
741 1dce7c3c bellard
/* guest cycle counter */
742 1dce7c3c bellard
743 eade0f19 bellard
static int64_t cpu_ticks_prev;
744 34865134 bellard
static int64_t cpu_ticks_offset;
745 1dce7c3c bellard
static int64_t cpu_clock_offset;
746 8a7ddc38 bellard
static int cpu_ticks_enabled;
747 34865134 bellard
748 1dce7c3c bellard
/* return the host CPU cycle counter and handle stop/restart */
749 1dce7c3c bellard
int64_t cpu_get_ticks(void)
750 34865134 bellard
{
751 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
752 8a7ddc38 bellard
        return cpu_ticks_offset;
753 8a7ddc38 bellard
    } else {
754 eade0f19 bellard
        int64_t ticks;
755 eade0f19 bellard
        ticks = cpu_get_real_ticks();
756 eade0f19 bellard
        if (cpu_ticks_prev > ticks) {
757 eade0f19 bellard
            /* Note: non increasing ticks may happen if the host uses
758 eade0f19 bellard
               software suspend */
759 eade0f19 bellard
            cpu_ticks_offset += cpu_ticks_prev - ticks;
760 eade0f19 bellard
        }
761 eade0f19 bellard
        cpu_ticks_prev = ticks;
762 eade0f19 bellard
        return ticks + cpu_ticks_offset;
763 8a7ddc38 bellard
    }
764 34865134 bellard
}
765 34865134 bellard
766 1dce7c3c bellard
/* return the host CPU monotonic timer and handle stop/restart */
767 1dce7c3c bellard
static int64_t cpu_get_clock(void)
768 1dce7c3c bellard
{
769 1dce7c3c bellard
    int64_t ti;
770 1dce7c3c bellard
    if (!cpu_ticks_enabled) {
771 1dce7c3c bellard
        return cpu_clock_offset;
772 1dce7c3c bellard
    } else {
773 1dce7c3c bellard
        ti = get_clock();
774 1dce7c3c bellard
        return ti + cpu_clock_offset;
775 1dce7c3c bellard
    }
776 1dce7c3c bellard
}
777 1dce7c3c bellard
778 34865134 bellard
/* enable cpu_get_ticks() */
779 34865134 bellard
void cpu_enable_ticks(void)
780 34865134 bellard
{
781 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
782 8a7ddc38 bellard
        cpu_ticks_offset -= cpu_get_real_ticks();
783 1dce7c3c bellard
        cpu_clock_offset -= get_clock();
784 8a7ddc38 bellard
        cpu_ticks_enabled = 1;
785 8a7ddc38 bellard
    }
786 34865134 bellard
}
787 34865134 bellard
788 34865134 bellard
/* disable cpu_get_ticks() : the clock is stopped. You must not call
789 34865134 bellard
   cpu_get_ticks() after that.  */
790 34865134 bellard
void cpu_disable_ticks(void)
791 34865134 bellard
{
792 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
793 8a7ddc38 bellard
        cpu_ticks_offset = cpu_get_ticks();
794 1dce7c3c bellard
        cpu_clock_offset = cpu_get_clock();
795 8a7ddc38 bellard
        cpu_ticks_enabled = 0;
796 8a7ddc38 bellard
    }
797 34865134 bellard
}
798 34865134 bellard
799 1dce7c3c bellard
/***********************************************************/
800 1dce7c3c bellard
/* timers */
801 5fafdf24 ths
802 8a7ddc38 bellard
#define QEMU_TIMER_REALTIME 0
803 8a7ddc38 bellard
#define QEMU_TIMER_VIRTUAL  1
804 8a7ddc38 bellard
805 8a7ddc38 bellard
struct QEMUClock {
806 8a7ddc38 bellard
    int type;
807 8a7ddc38 bellard
    /* XXX: add frequency */
808 8a7ddc38 bellard
};
809 8a7ddc38 bellard
810 8a7ddc38 bellard
struct QEMUTimer {
811 8a7ddc38 bellard
    QEMUClock *clock;
812 8a7ddc38 bellard
    int64_t expire_time;
813 8a7ddc38 bellard
    QEMUTimerCB *cb;
814 8a7ddc38 bellard
    void *opaque;
815 8a7ddc38 bellard
    struct QEMUTimer *next;
816 8a7ddc38 bellard
};
817 8a7ddc38 bellard
818 c8994013 ths
struct qemu_alarm_timer {
819 c8994013 ths
    char const *name;
820 efe75411 ths
    unsigned int flags;
821 c8994013 ths
822 c8994013 ths
    int (*start)(struct qemu_alarm_timer *t);
823 c8994013 ths
    void (*stop)(struct qemu_alarm_timer *t);
824 efe75411 ths
    void (*rearm)(struct qemu_alarm_timer *t);
825 c8994013 ths
    void *priv;
826 c8994013 ths
};
827 c8994013 ths
828 efe75411 ths
#define ALARM_FLAG_DYNTICKS  0x1
829 d5d08334 balrog
#define ALARM_FLAG_EXPIRED   0x2
830 efe75411 ths
831 efe75411 ths
static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
832 efe75411 ths
{
833 efe75411 ths
    return t->flags & ALARM_FLAG_DYNTICKS;
834 efe75411 ths
}
835 efe75411 ths
836 efe75411 ths
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
837 efe75411 ths
{
838 efe75411 ths
    if (!alarm_has_dynticks(t))
839 efe75411 ths
        return;
840 efe75411 ths
841 efe75411 ths
    t->rearm(t);
842 efe75411 ths
}
843 efe75411 ths
844 efe75411 ths
/* TODO: MIN_TIMER_REARM_US should be optimized */
845 efe75411 ths
#define MIN_TIMER_REARM_US 250
846 efe75411 ths
847 c8994013 ths
static struct qemu_alarm_timer *alarm_timer;
848 8a7ddc38 bellard
849 40c3bac3 bellard
#ifdef _WIN32
850 c8994013 ths
851 c8994013 ths
struct qemu_alarm_win32 {
852 c8994013 ths
    MMRESULT timerId;
853 c8994013 ths
    HANDLE host_alarm;
854 c8994013 ths
    unsigned int period;
855 c8994013 ths
} alarm_win32_data = {0, NULL, -1};
856 c8994013 ths
857 c8994013 ths
static int win32_start_timer(struct qemu_alarm_timer *t);
858 c8994013 ths
static void win32_stop_timer(struct qemu_alarm_timer *t);
859 efe75411 ths
static void win32_rearm_timer(struct qemu_alarm_timer *t);
860 c8994013 ths
861 40c3bac3 bellard
#else
862 c8994013 ths
863 c8994013 ths
static int unix_start_timer(struct qemu_alarm_timer *t);
864 c8994013 ths
static void unix_stop_timer(struct qemu_alarm_timer *t);
865 c8994013 ths
866 231c6586 ths
#ifdef __linux__
867 231c6586 ths
868 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t);
869 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
870 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
871 efe75411 ths
872 c40ec5a9 ths
static int hpet_start_timer(struct qemu_alarm_timer *t);
873 c40ec5a9 ths
static void hpet_stop_timer(struct qemu_alarm_timer *t);
874 c40ec5a9 ths
875 c8994013 ths
static int rtc_start_timer(struct qemu_alarm_timer *t);
876 c8994013 ths
static void rtc_stop_timer(struct qemu_alarm_timer *t);
877 c8994013 ths
878 efe75411 ths
#endif /* __linux__ */
879 8a7ddc38 bellard
880 c8994013 ths
#endif /* _WIN32 */
881 c8994013 ths
882 c8994013 ths
static struct qemu_alarm_timer alarm_timers[] = {
883 efe75411 ths
#ifndef _WIN32
884 231c6586 ths
#ifdef __linux__
885 efe75411 ths
    {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
886 efe75411 ths
     dynticks_stop_timer, dynticks_rearm_timer, NULL},
887 c40ec5a9 ths
    /* HPET - if available - is preferred */
888 efe75411 ths
    {"hpet", 0, hpet_start_timer, hpet_stop_timer, NULL, NULL},
889 c40ec5a9 ths
    /* ...otherwise try RTC */
890 efe75411 ths
    {"rtc", 0, rtc_start_timer, rtc_stop_timer, NULL, NULL},
891 c8994013 ths
#endif
892 efe75411 ths
    {"unix", 0, unix_start_timer, unix_stop_timer, NULL, NULL},
893 c8994013 ths
#else
894 efe75411 ths
    {"dynticks", ALARM_FLAG_DYNTICKS, win32_start_timer,
895 efe75411 ths
     win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
896 efe75411 ths
    {"win32", 0, win32_start_timer,
897 efe75411 ths
     win32_stop_timer, NULL, &alarm_win32_data},
898 c8994013 ths
#endif
899 c8994013 ths
    {NULL, }
900 c8994013 ths
};
901 c8994013 ths
902 3f47aa8c blueswir1
static void show_available_alarms(void)
903 f3dcfada ths
{
904 f3dcfada ths
    int i;
905 f3dcfada ths
906 f3dcfada ths
    printf("Available alarm timers, in order of precedence:\n");
907 f3dcfada ths
    for (i = 0; alarm_timers[i].name; i++)
908 f3dcfada ths
        printf("%s\n", alarm_timers[i].name);
909 f3dcfada ths
}
910 f3dcfada ths
911 f3dcfada ths
static void configure_alarms(char const *opt)
912 f3dcfada ths
{
913 f3dcfada ths
    int i;
914 f3dcfada ths
    int cur = 0;
915 f3dcfada ths
    int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
916 f3dcfada ths
    char *arg;
917 f3dcfada ths
    char *name;
918 f3dcfada ths
919 f3dcfada ths
    if (!strcmp(opt, "help")) {
920 f3dcfada ths
        show_available_alarms();
921 f3dcfada ths
        exit(0);
922 f3dcfada ths
    }
923 f3dcfada ths
924 f3dcfada ths
    arg = strdup(opt);
925 f3dcfada ths
926 f3dcfada ths
    /* Reorder the array */
927 f3dcfada ths
    name = strtok(arg, ",");
928 f3dcfada ths
    while (name) {
929 f3dcfada ths
        struct qemu_alarm_timer tmp;
930 f3dcfada ths
931 e2b577e5 balrog
        for (i = 0; i < count && alarm_timers[i].name; i++) {
932 f3dcfada ths
            if (!strcmp(alarm_timers[i].name, name))
933 f3dcfada ths
                break;
934 f3dcfada ths
        }
935 f3dcfada ths
936 f3dcfada ths
        if (i == count) {
937 f3dcfada ths
            fprintf(stderr, "Unknown clock %s\n", name);
938 f3dcfada ths
            goto next;
939 f3dcfada ths
        }
940 f3dcfada ths
941 f3dcfada ths
        if (i < cur)
942 f3dcfada ths
            /* Ignore */
943 f3dcfada ths
            goto next;
944 f3dcfada ths
945 f3dcfada ths
        /* Swap */
946 f3dcfada ths
        tmp = alarm_timers[i];
947 f3dcfada ths
        alarm_timers[i] = alarm_timers[cur];
948 f3dcfada ths
        alarm_timers[cur] = tmp;
949 f3dcfada ths
950 f3dcfada ths
        cur++;
951 f3dcfada ths
next:
952 f3dcfada ths
        name = strtok(NULL, ",");
953 f3dcfada ths
    }
954 f3dcfada ths
955 f3dcfada ths
    free(arg);
956 f3dcfada ths
957 f3dcfada ths
    if (cur) {
958 f3dcfada ths
        /* Disable remaining timers */
959 f3dcfada ths
        for (i = cur; i < count; i++)
960 f3dcfada ths
            alarm_timers[i].name = NULL;
961 f3dcfada ths
    }
962 f3dcfada ths
963 f3dcfada ths
    /* debug */
964 f3dcfada ths
    show_available_alarms();
965 f3dcfada ths
}
966 f3dcfada ths
967 c8994013 ths
QEMUClock *rt_clock;
968 c8994013 ths
QEMUClock *vm_clock;
969 c8994013 ths
970 c8994013 ths
static QEMUTimer *active_timers[2];
971 c8994013 ths
972 9596ebb7 pbrook
static QEMUClock *qemu_new_clock(int type)
973 8a7ddc38 bellard
{
974 8a7ddc38 bellard
    QEMUClock *clock;
975 8a7ddc38 bellard
    clock = qemu_mallocz(sizeof(QEMUClock));
976 8a7ddc38 bellard
    if (!clock)
977 8a7ddc38 bellard
        return NULL;
978 8a7ddc38 bellard
    clock->type = type;
979 8a7ddc38 bellard
    return clock;
980 8a7ddc38 bellard
}
981 8a7ddc38 bellard
982 8a7ddc38 bellard
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
983 8a7ddc38 bellard
{
984 8a7ddc38 bellard
    QEMUTimer *ts;
985 8a7ddc38 bellard
986 8a7ddc38 bellard
    ts = qemu_mallocz(sizeof(QEMUTimer));
987 8a7ddc38 bellard
    ts->clock = clock;
988 8a7ddc38 bellard
    ts->cb = cb;
989 8a7ddc38 bellard
    ts->opaque = opaque;
990 8a7ddc38 bellard
    return ts;
991 8a7ddc38 bellard
}
992 8a7ddc38 bellard
993 8a7ddc38 bellard
void qemu_free_timer(QEMUTimer *ts)
994 8a7ddc38 bellard
{
995 8a7ddc38 bellard
    qemu_free(ts);
996 8a7ddc38 bellard
}
997 8a7ddc38 bellard
998 8a7ddc38 bellard
/* stop a timer, but do not dealloc it */
999 8a7ddc38 bellard
void qemu_del_timer(QEMUTimer *ts)
1000 8a7ddc38 bellard
{
1001 8a7ddc38 bellard
    QEMUTimer **pt, *t;
1002 8a7ddc38 bellard
1003 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
1004 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
1005 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
1006 8a7ddc38 bellard
    for(;;) {
1007 8a7ddc38 bellard
        t = *pt;
1008 8a7ddc38 bellard
        if (!t)
1009 8a7ddc38 bellard
            break;
1010 8a7ddc38 bellard
        if (t == ts) {
1011 8a7ddc38 bellard
            *pt = t->next;
1012 8a7ddc38 bellard
            break;
1013 8a7ddc38 bellard
        }
1014 8a7ddc38 bellard
        pt = &t->next;
1015 8a7ddc38 bellard
    }
1016 8a7ddc38 bellard
}
1017 8a7ddc38 bellard
1018 8a7ddc38 bellard
/* modify the current timer so that it will be fired when current_time
1019 8a7ddc38 bellard
   >= expire_time. The corresponding callback will be called. */
1020 8a7ddc38 bellard
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
1021 8a7ddc38 bellard
{
1022 8a7ddc38 bellard
    QEMUTimer **pt, *t;
1023 8a7ddc38 bellard
1024 8a7ddc38 bellard
    qemu_del_timer(ts);
1025 8a7ddc38 bellard
1026 8a7ddc38 bellard
    /* add the timer in the sorted list */
1027 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
1028 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
1029 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
1030 8a7ddc38 bellard
    for(;;) {
1031 8a7ddc38 bellard
        t = *pt;
1032 8a7ddc38 bellard
        if (!t)
1033 8a7ddc38 bellard
            break;
1034 5fafdf24 ths
        if (t->expire_time > expire_time)
1035 8a7ddc38 bellard
            break;
1036 8a7ddc38 bellard
        pt = &t->next;
1037 8a7ddc38 bellard
    }
1038 8a7ddc38 bellard
    ts->expire_time = expire_time;
1039 8a7ddc38 bellard
    ts->next = *pt;
1040 8a7ddc38 bellard
    *pt = ts;
1041 d5d08334 balrog
1042 d5d08334 balrog
    /* Rearm if necessary  */
1043 d5d08334 balrog
    if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0 &&
1044 d5d08334 balrog
        pt == &active_timers[ts->clock->type])
1045 d5d08334 balrog
        qemu_rearm_alarm_timer(alarm_timer);
1046 8a7ddc38 bellard
}
1047 8a7ddc38 bellard
1048 8a7ddc38 bellard
int qemu_timer_pending(QEMUTimer *ts)
1049 8a7ddc38 bellard
{
1050 8a7ddc38 bellard
    QEMUTimer *t;
1051 8a7ddc38 bellard
    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
1052 8a7ddc38 bellard
        if (t == ts)
1053 8a7ddc38 bellard
            return 1;
1054 8a7ddc38 bellard
    }
1055 8a7ddc38 bellard
    return 0;
1056 8a7ddc38 bellard
}
1057 8a7ddc38 bellard
1058 8a7ddc38 bellard
static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
1059 8a7ddc38 bellard
{
1060 8a7ddc38 bellard
    if (!timer_head)
1061 8a7ddc38 bellard
        return 0;
1062 8a7ddc38 bellard
    return (timer_head->expire_time <= current_time);
1063 8a7ddc38 bellard
}
1064 8a7ddc38 bellard
1065 8a7ddc38 bellard
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
1066 8a7ddc38 bellard
{
1067 8a7ddc38 bellard
    QEMUTimer *ts;
1068 3b46e624 ths
1069 8a7ddc38 bellard
    for(;;) {
1070 8a7ddc38 bellard
        ts = *ptimer_head;
1071 e95c8d51 bellard
        if (!ts || ts->expire_time > current_time)
1072 8a7ddc38 bellard
            break;
1073 8a7ddc38 bellard
        /* remove timer from the list before calling the callback */
1074 8a7ddc38 bellard
        *ptimer_head = ts->next;
1075 8a7ddc38 bellard
        ts->next = NULL;
1076 3b46e624 ths
1077 8a7ddc38 bellard
        /* run the callback (the timer list can be modified) */
1078 8a7ddc38 bellard
        ts->cb(ts->opaque);
1079 8a7ddc38 bellard
    }
1080 8a7ddc38 bellard
}
1081 8a7ddc38 bellard
1082 8a7ddc38 bellard
int64_t qemu_get_clock(QEMUClock *clock)
1083 8a7ddc38 bellard
{
1084 8a7ddc38 bellard
    switch(clock->type) {
1085 8a7ddc38 bellard
    case QEMU_TIMER_REALTIME:
1086 1dce7c3c bellard
        return get_clock() / 1000000;
1087 8a7ddc38 bellard
    default:
1088 8a7ddc38 bellard
    case QEMU_TIMER_VIRTUAL:
1089 1dce7c3c bellard
        return cpu_get_clock();
1090 8a7ddc38 bellard
    }
1091 8a7ddc38 bellard
}
1092 8a7ddc38 bellard
1093 1dce7c3c bellard
static void init_timers(void)
1094 1dce7c3c bellard
{
1095 1dce7c3c bellard
    init_get_clock();
1096 1dce7c3c bellard
    ticks_per_sec = QEMU_TIMER_BASE;
1097 1dce7c3c bellard
    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
1098 1dce7c3c bellard
    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
1099 1dce7c3c bellard
}
1100 1dce7c3c bellard
1101 8a7ddc38 bellard
/* save a timer */
1102 8a7ddc38 bellard
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
1103 8a7ddc38 bellard
{
1104 8a7ddc38 bellard
    uint64_t expire_time;
1105 8a7ddc38 bellard
1106 8a7ddc38 bellard
    if (qemu_timer_pending(ts)) {
1107 8a7ddc38 bellard
        expire_time = ts->expire_time;
1108 8a7ddc38 bellard
    } else {
1109 8a7ddc38 bellard
        expire_time = -1;
1110 8a7ddc38 bellard
    }
1111 8a7ddc38 bellard
    qemu_put_be64(f, expire_time);
1112 8a7ddc38 bellard
}
1113 8a7ddc38 bellard
1114 8a7ddc38 bellard
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
1115 8a7ddc38 bellard
{
1116 8a7ddc38 bellard
    uint64_t expire_time;
1117 8a7ddc38 bellard
1118 8a7ddc38 bellard
    expire_time = qemu_get_be64(f);
1119 8a7ddc38 bellard
    if (expire_time != -1) {
1120 8a7ddc38 bellard
        qemu_mod_timer(ts, expire_time);
1121 8a7ddc38 bellard
    } else {
1122 8a7ddc38 bellard
        qemu_del_timer(ts);
1123 8a7ddc38 bellard
    }
1124 8a7ddc38 bellard
}
1125 8a7ddc38 bellard
1126 8a7ddc38 bellard
static void timer_save(QEMUFile *f, void *opaque)
1127 8a7ddc38 bellard
{
1128 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
1129 8a7ddc38 bellard
        hw_error("cannot save state if virtual timers are running");
1130 8a7ddc38 bellard
    }
1131 bee8d684 ths
    qemu_put_be64(f, cpu_ticks_offset);
1132 bee8d684 ths
    qemu_put_be64(f, ticks_per_sec);
1133 bee8d684 ths
    qemu_put_be64(f, cpu_clock_offset);
1134 8a7ddc38 bellard
}
1135 8a7ddc38 bellard
1136 8a7ddc38 bellard
static int timer_load(QEMUFile *f, void *opaque, int version_id)
1137 8a7ddc38 bellard
{
1138 c88676f8 bellard
    if (version_id != 1 && version_id != 2)
1139 8a7ddc38 bellard
        return -EINVAL;
1140 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
1141 8a7ddc38 bellard
        return -EINVAL;
1142 8a7ddc38 bellard
    }
1143 bee8d684 ths
    cpu_ticks_offset=qemu_get_be64(f);
1144 bee8d684 ths
    ticks_per_sec=qemu_get_be64(f);
1145 c88676f8 bellard
    if (version_id == 2) {
1146 bee8d684 ths
        cpu_clock_offset=qemu_get_be64(f);
1147 c88676f8 bellard
    }
1148 8a7ddc38 bellard
    return 0;
1149 8a7ddc38 bellard
}
1150 8a7ddc38 bellard
1151 67b915a5 bellard
#ifdef _WIN32
1152 5fafdf24 ths
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1153 67b915a5 bellard
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
1154 67b915a5 bellard
#else
1155 8a7ddc38 bellard
static void host_alarm_handler(int host_signum)
1156 67b915a5 bellard
#endif
1157 8a7ddc38 bellard
{
1158 02ba45c5 bellard
#if 0
1159 02ba45c5 bellard
#define DISP_FREQ 1000
1160 02ba45c5 bellard
    {
1161 02ba45c5 bellard
        static int64_t delta_min = INT64_MAX;
1162 02ba45c5 bellard
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
1163 02ba45c5 bellard
        static int count;
1164 02ba45c5 bellard
        ti = qemu_get_clock(vm_clock);
1165 02ba45c5 bellard
        if (last_clock != 0) {
1166 02ba45c5 bellard
            delta = ti - last_clock;
1167 02ba45c5 bellard
            if (delta < delta_min)
1168 02ba45c5 bellard
                delta_min = delta;
1169 02ba45c5 bellard
            if (delta > delta_max)
1170 02ba45c5 bellard
                delta_max = delta;
1171 02ba45c5 bellard
            delta_cum += delta;
1172 02ba45c5 bellard
            if (++count == DISP_FREQ) {
1173 26a76461 bellard
                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
1174 02ba45c5 bellard
                       muldiv64(delta_min, 1000000, ticks_per_sec),
1175 02ba45c5 bellard
                       muldiv64(delta_max, 1000000, ticks_per_sec),
1176 02ba45c5 bellard
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
1177 02ba45c5 bellard
                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
1178 02ba45c5 bellard
                count = 0;
1179 02ba45c5 bellard
                delta_min = INT64_MAX;
1180 02ba45c5 bellard
                delta_max = 0;
1181 02ba45c5 bellard
                delta_cum = 0;
1182 02ba45c5 bellard
            }
1183 02ba45c5 bellard
        }
1184 02ba45c5 bellard
        last_clock = ti;
1185 02ba45c5 bellard
    }
1186 02ba45c5 bellard
#endif
1187 efe75411 ths
    if (alarm_has_dynticks(alarm_timer) ||
1188 efe75411 ths
        qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
1189 8a7ddc38 bellard
                           qemu_get_clock(vm_clock)) ||
1190 8a7ddc38 bellard
        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
1191 8a7ddc38 bellard
                           qemu_get_clock(rt_clock))) {
1192 06d9f2f7 bellard
#ifdef _WIN32
1193 c8994013 ths
        struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1194 c8994013 ths
        SetEvent(data->host_alarm);
1195 06d9f2f7 bellard
#endif
1196 ee5605e5 balrog
        CPUState *env = next_cpu;
1197 ee5605e5 balrog
1198 d5d08334 balrog
        alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1199 d5d08334 balrog
1200 4f8eb8da balrog
        if (env) {
1201 4f8eb8da balrog
            /* stop the currently executing cpu because a timer occured */
1202 4f8eb8da balrog
            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
1203 a332e112 bellard
#ifdef USE_KQEMU
1204 4f8eb8da balrog
            if (env->kqemu_enabled) {
1205 4f8eb8da balrog
                kqemu_cpu_interrupt(env);
1206 4f8eb8da balrog
            }
1207 ee5605e5 balrog
#endif
1208 4f8eb8da balrog
        }
1209 ee5605e5 balrog
        event_pending = 1;
1210 8a7ddc38 bellard
    }
1211 8a7ddc38 bellard
}
1212 8a7ddc38 bellard
1213 efe75411 ths
static uint64_t qemu_next_deadline(void)
1214 efe75411 ths
{
1215 49a9b725 balrog
    int64_t nearest_delta_us = INT64_MAX;
1216 efe75411 ths
    int64_t vmdelta_us;
1217 efe75411 ths
1218 efe75411 ths
    if (active_timers[QEMU_TIMER_REALTIME])
1219 efe75411 ths
        nearest_delta_us = (active_timers[QEMU_TIMER_REALTIME]->expire_time -
1220 efe75411 ths
                            qemu_get_clock(rt_clock))*1000;
1221 efe75411 ths
1222 efe75411 ths
    if (active_timers[QEMU_TIMER_VIRTUAL]) {
1223 efe75411 ths
        /* round up */
1224 efe75411 ths
        vmdelta_us = (active_timers[QEMU_TIMER_VIRTUAL]->expire_time -
1225 efe75411 ths
                      qemu_get_clock(vm_clock)+999)/1000;
1226 efe75411 ths
        if (vmdelta_us < nearest_delta_us)
1227 efe75411 ths
            nearest_delta_us = vmdelta_us;
1228 efe75411 ths
    }
1229 efe75411 ths
1230 efe75411 ths
    /* Avoid arming the timer to negative, zero, or too low values */
1231 efe75411 ths
    if (nearest_delta_us <= MIN_TIMER_REARM_US)
1232 efe75411 ths
        nearest_delta_us = MIN_TIMER_REARM_US;
1233 efe75411 ths
1234 efe75411 ths
    return nearest_delta_us;
1235 efe75411 ths
}
1236 efe75411 ths
1237 fd872598 bellard
#ifndef _WIN32
1238 fd872598 bellard
1239 829309c7 bellard
#if defined(__linux__)
1240 829309c7 bellard
1241 fd872598 bellard
#define RTC_FREQ 1024
1242 fd872598 bellard
1243 c8994013 ths
static void enable_sigio_timer(int fd)
1244 c8994013 ths
{
1245 c8994013 ths
    struct sigaction act;
1246 c8994013 ths
1247 c8994013 ths
    /* timer signal */
1248 c8994013 ths
    sigfillset(&act.sa_mask);
1249 c8994013 ths
    act.sa_flags = 0;
1250 c8994013 ths
    act.sa_handler = host_alarm_handler;
1251 c8994013 ths
1252 c8994013 ths
    sigaction(SIGIO, &act, NULL);
1253 c8994013 ths
    fcntl(fd, F_SETFL, O_ASYNC);
1254 c8994013 ths
    fcntl(fd, F_SETOWN, getpid());
1255 c8994013 ths
}
1256 829309c7 bellard
1257 c40ec5a9 ths
static int hpet_start_timer(struct qemu_alarm_timer *t)
1258 c40ec5a9 ths
{
1259 c40ec5a9 ths
    struct hpet_info info;
1260 c40ec5a9 ths
    int r, fd;
1261 c40ec5a9 ths
1262 c40ec5a9 ths
    fd = open("/dev/hpet", O_RDONLY);
1263 c40ec5a9 ths
    if (fd < 0)
1264 c40ec5a9 ths
        return -1;
1265 c40ec5a9 ths
1266 c40ec5a9 ths
    /* Set frequency */
1267 c40ec5a9 ths
    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
1268 c40ec5a9 ths
    if (r < 0) {
1269 c40ec5a9 ths
        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
1270 c40ec5a9 ths
                "error, but for better emulation accuracy type:\n"
1271 c40ec5a9 ths
                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
1272 c40ec5a9 ths
        goto fail;
1273 c40ec5a9 ths
    }
1274 c40ec5a9 ths
1275 c40ec5a9 ths
    /* Check capabilities */
1276 c40ec5a9 ths
    r = ioctl(fd, HPET_INFO, &info);
1277 c40ec5a9 ths
    if (r < 0)
1278 c40ec5a9 ths
        goto fail;
1279 c40ec5a9 ths
1280 c40ec5a9 ths
    /* Enable periodic mode */
1281 c40ec5a9 ths
    r = ioctl(fd, HPET_EPI, 0);
1282 c40ec5a9 ths
    if (info.hi_flags && (r < 0))
1283 c40ec5a9 ths
        goto fail;
1284 c40ec5a9 ths
1285 c40ec5a9 ths
    /* Enable interrupt */
1286 c40ec5a9 ths
    r = ioctl(fd, HPET_IE_ON, 0);
1287 c40ec5a9 ths
    if (r < 0)
1288 c40ec5a9 ths
        goto fail;
1289 c40ec5a9 ths
1290 c40ec5a9 ths
    enable_sigio_timer(fd);
1291 fcdc2129 pbrook
    t->priv = (void *)(long)fd;
1292 c40ec5a9 ths
1293 c40ec5a9 ths
    return 0;
1294 c40ec5a9 ths
fail:
1295 c40ec5a9 ths
    close(fd);
1296 c40ec5a9 ths
    return -1;
1297 c40ec5a9 ths
}
1298 c40ec5a9 ths
1299 c40ec5a9 ths
static void hpet_stop_timer(struct qemu_alarm_timer *t)
1300 c40ec5a9 ths
{
1301 fcdc2129 pbrook
    int fd = (long)t->priv;
1302 c40ec5a9 ths
1303 c40ec5a9 ths
    close(fd);
1304 c40ec5a9 ths
}
1305 c40ec5a9 ths
1306 c8994013 ths
static int rtc_start_timer(struct qemu_alarm_timer *t)
1307 fd872598 bellard
{
1308 c8994013 ths
    int rtc_fd;
1309 b5a23ad4 balrog
    unsigned long current_rtc_freq = 0;
1310 c8994013 ths
1311 aeb30be6 balrog
    TFR(rtc_fd = open("/dev/rtc", O_RDONLY));
1312 fd872598 bellard
    if (rtc_fd < 0)
1313 fd872598 bellard
        return -1;
1314 b5a23ad4 balrog
    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
1315 b5a23ad4 balrog
    if (current_rtc_freq != RTC_FREQ &&
1316 b5a23ad4 balrog
        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
1317 fd872598 bellard
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1318 fd872598 bellard
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1319 fd872598 bellard
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1320 fd872598 bellard
        goto fail;
1321 fd872598 bellard
    }
1322 fd872598 bellard
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1323 fd872598 bellard
    fail:
1324 fd872598 bellard
        close(rtc_fd);
1325 fd872598 bellard
        return -1;
1326 fd872598 bellard
    }
1327 c8994013 ths
1328 c8994013 ths
    enable_sigio_timer(rtc_fd);
1329 c8994013 ths
1330 fcdc2129 pbrook
    t->priv = (void *)(long)rtc_fd;
1331 c8994013 ths
1332 fd872598 bellard
    return 0;
1333 fd872598 bellard
}
1334 fd872598 bellard
1335 c8994013 ths
static void rtc_stop_timer(struct qemu_alarm_timer *t)
1336 829309c7 bellard
{
1337 fcdc2129 pbrook
    int rtc_fd = (long)t->priv;
1338 c8994013 ths
1339 c8994013 ths
    close(rtc_fd);
1340 829309c7 bellard
}
1341 829309c7 bellard
1342 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t)
1343 efe75411 ths
{
1344 efe75411 ths
    struct sigevent ev;
1345 efe75411 ths
    timer_t host_timer;
1346 efe75411 ths
    struct sigaction act;
1347 efe75411 ths
1348 efe75411 ths
    sigfillset(&act.sa_mask);
1349 efe75411 ths
    act.sa_flags = 0;
1350 efe75411 ths
    act.sa_handler = host_alarm_handler;
1351 efe75411 ths
1352 efe75411 ths
    sigaction(SIGALRM, &act, NULL);
1353 efe75411 ths
1354 efe75411 ths
    ev.sigev_value.sival_int = 0;
1355 efe75411 ths
    ev.sigev_notify = SIGEV_SIGNAL;
1356 efe75411 ths
    ev.sigev_signo = SIGALRM;
1357 efe75411 ths
1358 efe75411 ths
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1359 efe75411 ths
        perror("timer_create");
1360 efe75411 ths
1361 efe75411 ths
        /* disable dynticks */
1362 efe75411 ths
        fprintf(stderr, "Dynamic Ticks disabled\n");
1363 efe75411 ths
1364 efe75411 ths
        return -1;
1365 efe75411 ths
    }
1366 efe75411 ths
1367 efe75411 ths
    t->priv = (void *)host_timer;
1368 efe75411 ths
1369 efe75411 ths
    return 0;
1370 efe75411 ths
}
1371 efe75411 ths
1372 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1373 efe75411 ths
{
1374 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1375 efe75411 ths
1376 efe75411 ths
    timer_delete(host_timer);
1377 efe75411 ths
}
1378 efe75411 ths
1379 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1380 efe75411 ths
{
1381 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1382 efe75411 ths
    struct itimerspec timeout;
1383 efe75411 ths
    int64_t nearest_delta_us = INT64_MAX;
1384 efe75411 ths
    int64_t current_us;
1385 efe75411 ths
1386 efe75411 ths
    if (!active_timers[QEMU_TIMER_REALTIME] &&
1387 efe75411 ths
                !active_timers[QEMU_TIMER_VIRTUAL])
1388 d5d08334 balrog
        return;
1389 efe75411 ths
1390 efe75411 ths
    nearest_delta_us = qemu_next_deadline();
1391 efe75411 ths
1392 efe75411 ths
    /* check whether a timer is already running */
1393 efe75411 ths
    if (timer_gettime(host_timer, &timeout)) {
1394 efe75411 ths
        perror("gettime");
1395 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1396 efe75411 ths
        exit(1);
1397 efe75411 ths
    }
1398 efe75411 ths
    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1399 efe75411 ths
    if (current_us && current_us <= nearest_delta_us)
1400 efe75411 ths
        return;
1401 efe75411 ths
1402 efe75411 ths
    timeout.it_interval.tv_sec = 0;
1403 efe75411 ths
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1404 efe75411 ths
    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;
1405 efe75411 ths
    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1406 efe75411 ths
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1407 efe75411 ths
        perror("settime");
1408 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1409 efe75411 ths
        exit(1);
1410 efe75411 ths
    }
1411 efe75411 ths
}
1412 efe75411 ths
1413 70744b3a ths
#endif /* defined(__linux__) */
1414 231c6586 ths
1415 c8994013 ths
static int unix_start_timer(struct qemu_alarm_timer *t)
1416 c8994013 ths
{
1417 c8994013 ths
    struct sigaction act;
1418 c8994013 ths
    struct itimerval itv;
1419 c8994013 ths
    int err;
1420 c8994013 ths
1421 c8994013 ths
    /* timer signal */
1422 c8994013 ths
    sigfillset(&act.sa_mask);
1423 c8994013 ths
    act.sa_flags = 0;
1424 c8994013 ths
    act.sa_handler = host_alarm_handler;
1425 c8994013 ths
1426 c8994013 ths
    sigaction(SIGALRM, &act, NULL);
1427 c8994013 ths
1428 c8994013 ths
    itv.it_interval.tv_sec = 0;
1429 c8994013 ths
    /* for i386 kernel 2.6 to get 1 ms */
1430 c8994013 ths
    itv.it_interval.tv_usec = 999;
1431 c8994013 ths
    itv.it_value.tv_sec = 0;
1432 c8994013 ths
    itv.it_value.tv_usec = 10 * 1000;
1433 c8994013 ths
1434 c8994013 ths
    err = setitimer(ITIMER_REAL, &itv, NULL);
1435 c8994013 ths
    if (err)
1436 c8994013 ths
        return -1;
1437 c8994013 ths
1438 c8994013 ths
    return 0;
1439 c8994013 ths
}
1440 c8994013 ths
1441 c8994013 ths
static void unix_stop_timer(struct qemu_alarm_timer *t)
1442 c8994013 ths
{
1443 c8994013 ths
    struct itimerval itv;
1444 c8994013 ths
1445 c8994013 ths
    memset(&itv, 0, sizeof(itv));
1446 c8994013 ths
    setitimer(ITIMER_REAL, &itv, NULL);
1447 c8994013 ths
}
1448 c8994013 ths
1449 829309c7 bellard
#endif /* !defined(_WIN32) */
1450 fd872598 bellard
1451 c8994013 ths
#ifdef _WIN32
1452 c8994013 ths
1453 c8994013 ths
static int win32_start_timer(struct qemu_alarm_timer *t)
1454 c8994013 ths
{
1455 c8994013 ths
    TIMECAPS tc;
1456 c8994013 ths
    struct qemu_alarm_win32 *data = t->priv;
1457 efe75411 ths
    UINT flags;
1458 c8994013 ths
1459 c8994013 ths
    data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1460 c8994013 ths
    if (!data->host_alarm) {
1461 c8994013 ths
        perror("Failed CreateEvent");
1462 c396a7f0 ths
        return -1;
1463 c8994013 ths
    }
1464 c8994013 ths
1465 c8994013 ths
    memset(&tc, 0, sizeof(tc));
1466 c8994013 ths
    timeGetDevCaps(&tc, sizeof(tc));
1467 c8994013 ths
1468 c8994013 ths
    if (data->period < tc.wPeriodMin)
1469 c8994013 ths
        data->period = tc.wPeriodMin;
1470 c8994013 ths
1471 c8994013 ths
    timeBeginPeriod(data->period);
1472 c8994013 ths
1473 efe75411 ths
    flags = TIME_CALLBACK_FUNCTION;
1474 efe75411 ths
    if (alarm_has_dynticks(t))
1475 efe75411 ths
        flags |= TIME_ONESHOT;
1476 efe75411 ths
    else
1477 efe75411 ths
        flags |= TIME_PERIODIC;
1478 efe75411 ths
1479 c8994013 ths
    data->timerId = timeSetEvent(1,         // interval (ms)
1480 c8994013 ths
                        data->period,       // resolution
1481 c8994013 ths
                        host_alarm_handler, // function
1482 c8994013 ths
                        (DWORD)t,           // parameter
1483 efe75411 ths
                        flags);
1484 c8994013 ths
1485 c8994013 ths
    if (!data->timerId) {
1486 c8994013 ths
        perror("Failed to initialize win32 alarm timer");
1487 c8994013 ths
1488 c8994013 ths
        timeEndPeriod(data->period);
1489 c8994013 ths
        CloseHandle(data->host_alarm);
1490 c8994013 ths
        return -1;
1491 c8994013 ths
    }
1492 c8994013 ths
1493 c8994013 ths
    qemu_add_wait_object(data->host_alarm, NULL, NULL);
1494 c8994013 ths
1495 c8994013 ths
    return 0;
1496 c8994013 ths
}
1497 c8994013 ths
1498 c8994013 ths
static void win32_stop_timer(struct qemu_alarm_timer *t)
1499 c8994013 ths
{
1500 c8994013 ths
    struct qemu_alarm_win32 *data = t->priv;
1501 c8994013 ths
1502 c8994013 ths
    timeKillEvent(data->timerId);
1503 c8994013 ths
    timeEndPeriod(data->period);
1504 c8994013 ths
1505 c8994013 ths
    CloseHandle(data->host_alarm);
1506 c8994013 ths
}
1507 c8994013 ths
1508 efe75411 ths
static void win32_rearm_timer(struct qemu_alarm_timer *t)
1509 efe75411 ths
{
1510 efe75411 ths
    struct qemu_alarm_win32 *data = t->priv;
1511 efe75411 ths
    uint64_t nearest_delta_us;
1512 efe75411 ths
1513 efe75411 ths
    if (!active_timers[QEMU_TIMER_REALTIME] &&
1514 efe75411 ths
                !active_timers[QEMU_TIMER_VIRTUAL])
1515 d5d08334 balrog
        return;
1516 efe75411 ths
1517 efe75411 ths
    nearest_delta_us = qemu_next_deadline();
1518 efe75411 ths
    nearest_delta_us /= 1000;
1519 efe75411 ths
1520 efe75411 ths
    timeKillEvent(data->timerId);
1521 efe75411 ths
1522 efe75411 ths
    data->timerId = timeSetEvent(1,
1523 efe75411 ths
                        data->period,
1524 efe75411 ths
                        host_alarm_handler,
1525 efe75411 ths
                        (DWORD)t,
1526 efe75411 ths
                        TIME_ONESHOT | TIME_PERIODIC);
1527 efe75411 ths
1528 efe75411 ths
    if (!data->timerId) {
1529 efe75411 ths
        perror("Failed to re-arm win32 alarm timer");
1530 efe75411 ths
1531 efe75411 ths
        timeEndPeriod(data->period);
1532 efe75411 ths
        CloseHandle(data->host_alarm);
1533 efe75411 ths
        exit(1);
1534 efe75411 ths
    }
1535 efe75411 ths
}
1536 efe75411 ths
1537 c8994013 ths
#endif /* _WIN32 */
1538 c8994013 ths
1539 1dce7c3c bellard
static void init_timer_alarm(void)
1540 8a7ddc38 bellard
{
1541 c8994013 ths
    struct qemu_alarm_timer *t;
1542 c8994013 ths
    int i, err = -1;
1543 c8994013 ths
1544 c8994013 ths
    for (i = 0; alarm_timers[i].name; i++) {
1545 c8994013 ths
        t = &alarm_timers[i];
1546 c8994013 ths
1547 c8994013 ths
        err = t->start(t);
1548 c8994013 ths
        if (!err)
1549 c8994013 ths
            break;
1550 67b915a5 bellard
    }
1551 fd872598 bellard
1552 c8994013 ths
    if (err) {
1553 c8994013 ths
        fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1554 c8994013 ths
        fprintf(stderr, "Terminating\n");
1555 c8994013 ths
        exit(1);
1556 67b915a5 bellard
    }
1557 c8994013 ths
1558 c8994013 ths
    alarm_timer = t;
1559 8a7ddc38 bellard
}
1560 8a7ddc38 bellard
1561 9596ebb7 pbrook
static void quit_timers(void)
1562 40c3bac3 bellard
{
1563 c8994013 ths
    alarm_timer->stop(alarm_timer);
1564 c8994013 ths
    alarm_timer = NULL;
1565 40c3bac3 bellard
}
1566 40c3bac3 bellard
1567 c4b1fcc0 bellard
/***********************************************************/
1568 f6503059 balrog
/* host time/date access */
1569 f6503059 balrog
void qemu_get_timedate(struct tm *tm, int offset)
1570 f6503059 balrog
{
1571 f6503059 balrog
    time_t ti;
1572 f6503059 balrog
    struct tm *ret;
1573 f6503059 balrog
1574 f6503059 balrog
    time(&ti);
1575 f6503059 balrog
    ti += offset;
1576 f6503059 balrog
    if (rtc_date_offset == -1) {
1577 f6503059 balrog
        if (rtc_utc)
1578 f6503059 balrog
            ret = gmtime(&ti);
1579 f6503059 balrog
        else
1580 f6503059 balrog
            ret = localtime(&ti);
1581 f6503059 balrog
    } else {
1582 f6503059 balrog
        ti -= rtc_date_offset;
1583 f6503059 balrog
        ret = gmtime(&ti);
1584 f6503059 balrog
    }
1585 f6503059 balrog
1586 f6503059 balrog
    memcpy(tm, ret, sizeof(struct tm));
1587 f6503059 balrog
}
1588 f6503059 balrog
1589 f6503059 balrog
int qemu_timedate_diff(struct tm *tm)
1590 f6503059 balrog
{
1591 f6503059 balrog
    time_t seconds;
1592 f6503059 balrog
1593 f6503059 balrog
    if (rtc_date_offset == -1)
1594 f6503059 balrog
        if (rtc_utc)
1595 f6503059 balrog
            seconds = mktimegm(tm);
1596 f6503059 balrog
        else
1597 f6503059 balrog
            seconds = mktime(tm);
1598 f6503059 balrog
    else
1599 f6503059 balrog
        seconds = mktimegm(tm) + rtc_date_offset;
1600 f6503059 balrog
1601 f6503059 balrog
    return seconds - time(NULL);
1602 f6503059 balrog
}
1603 f6503059 balrog
1604 f6503059 balrog
/***********************************************************/
1605 82c643ff bellard
/* character device */
1606 313aa567 bellard
1607 e5b0bc44 pbrook
static void qemu_chr_event(CharDriverState *s, int event)
1608 e5b0bc44 pbrook
{
1609 e5b0bc44 pbrook
    if (!s->chr_event)
1610 e5b0bc44 pbrook
        return;
1611 e5b0bc44 pbrook
    s->chr_event(s->handler_opaque, event);
1612 e5b0bc44 pbrook
}
1613 e5b0bc44 pbrook
1614 86e94dea ths
static void qemu_chr_reset_bh(void *opaque)
1615 86e94dea ths
{
1616 86e94dea ths
    CharDriverState *s = opaque;
1617 e5b0bc44 pbrook
    qemu_chr_event(s, CHR_EVENT_RESET);
1618 86e94dea ths
    qemu_bh_delete(s->bh);
1619 86e94dea ths
    s->bh = NULL;
1620 86e94dea ths
}
1621 86e94dea ths
1622 86e94dea ths
void qemu_chr_reset(CharDriverState *s)
1623 86e94dea ths
{
1624 86e94dea ths
    if (s->bh == NULL) {
1625 86e94dea ths
        s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1626 86e94dea ths
        qemu_bh_schedule(s->bh);
1627 86e94dea ths
    }
1628 86e94dea ths
}
1629 86e94dea ths
1630 82c643ff bellard
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
1631 82c643ff bellard
{
1632 82c643ff bellard
    return s->chr_write(s, buf, len);
1633 82c643ff bellard
}
1634 67b915a5 bellard
1635 e57a8c0e bellard
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
1636 f8d179e3 bellard
{
1637 e57a8c0e bellard
    if (!s->chr_ioctl)
1638 e57a8c0e bellard
        return -ENOTSUP;
1639 e57a8c0e bellard
    return s->chr_ioctl(s, cmd, arg);
1640 f8d179e3 bellard
}
1641 f8d179e3 bellard
1642 e5b0bc44 pbrook
int qemu_chr_can_read(CharDriverState *s)
1643 e5b0bc44 pbrook
{
1644 e5b0bc44 pbrook
    if (!s->chr_can_read)
1645 e5b0bc44 pbrook
        return 0;
1646 e5b0bc44 pbrook
    return s->chr_can_read(s->handler_opaque);
1647 e5b0bc44 pbrook
}
1648 e5b0bc44 pbrook
1649 e5b0bc44 pbrook
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1650 e5b0bc44 pbrook
{
1651 e5b0bc44 pbrook
    s->chr_read(s->handler_opaque, buf, len);
1652 e5b0bc44 pbrook
}
1653 e5b0bc44 pbrook
1654 bd9bdce6 balrog
void qemu_chr_accept_input(CharDriverState *s)
1655 bd9bdce6 balrog
{
1656 bd9bdce6 balrog
    if (s->chr_accept_input)
1657 bd9bdce6 balrog
        s->chr_accept_input(s);
1658 bd9bdce6 balrog
}
1659 e5b0bc44 pbrook
1660 82c643ff bellard
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1661 67b915a5 bellard
{
1662 82c643ff bellard
    char buf[4096];
1663 82c643ff bellard
    va_list ap;
1664 82c643ff bellard
    va_start(ap, fmt);
1665 82c643ff bellard
    vsnprintf(buf, sizeof(buf), fmt, ap);
1666 ffe8ab83 ths
    qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
1667 82c643ff bellard
    va_end(ap);
1668 67b915a5 bellard
}
1669 67b915a5 bellard
1670 5905b2e5 bellard
void qemu_chr_send_event(CharDriverState *s, int event)
1671 5905b2e5 bellard
{
1672 5905b2e5 bellard
    if (s->chr_send_event)
1673 5905b2e5 bellard
        s->chr_send_event(s, event);
1674 5905b2e5 bellard
}
1675 5905b2e5 bellard
1676 5fafdf24 ths
void qemu_chr_add_handlers(CharDriverState *s,
1677 5fafdf24 ths
                           IOCanRWHandler *fd_can_read,
1678 e5b0bc44 pbrook
                           IOReadHandler *fd_read,
1679 e5b0bc44 pbrook
                           IOEventHandler *fd_event,
1680 e5b0bc44 pbrook
                           void *opaque)
1681 82c643ff bellard
{
1682 e5b0bc44 pbrook
    s->chr_can_read = fd_can_read;
1683 e5b0bc44 pbrook
    s->chr_read = fd_read;
1684 e5b0bc44 pbrook
    s->chr_event = fd_event;
1685 e5b0bc44 pbrook
    s->handler_opaque = opaque;
1686 e5b0bc44 pbrook
    if (s->chr_update_read_handler)
1687 e5b0bc44 pbrook
        s->chr_update_read_handler(s);
1688 82c643ff bellard
}
1689 3b46e624 ths
1690 82c643ff bellard
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1691 313aa567 bellard
{
1692 82c643ff bellard
    return len;
1693 82c643ff bellard
}
1694 82c643ff bellard
1695 52f61fde ths
static CharDriverState *qemu_chr_open_null(void)
1696 82c643ff bellard
{
1697 82c643ff bellard
    CharDriverState *chr;
1698 82c643ff bellard
1699 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1700 82c643ff bellard
    if (!chr)
1701 82c643ff bellard
        return NULL;
1702 82c643ff bellard
    chr->chr_write = null_chr_write;
1703 82c643ff bellard
    return chr;
1704 82c643ff bellard
}
1705 82c643ff bellard
1706 20d8a3ed ths
/* MUX driver for serial I/O splitting */
1707 20d8a3ed ths
static int term_timestamps;
1708 20d8a3ed ths
static int64_t term_timestamps_start;
1709 9c1de612 ths
#define MAX_MUX 4
1710 bd9bdce6 balrog
#define MUX_BUFFER_SIZE 32        /* Must be a power of 2.  */
1711 bd9bdce6 balrog
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
1712 20d8a3ed ths
typedef struct {
1713 20d8a3ed ths
    IOCanRWHandler *chr_can_read[MAX_MUX];
1714 20d8a3ed ths
    IOReadHandler *chr_read[MAX_MUX];
1715 20d8a3ed ths
    IOEventHandler *chr_event[MAX_MUX];
1716 20d8a3ed ths
    void *ext_opaque[MAX_MUX];
1717 20d8a3ed ths
    CharDriverState *drv;
1718 bd9bdce6 balrog
    unsigned char buffer[MUX_BUFFER_SIZE];
1719 bd9bdce6 balrog
    int prod;
1720 bd9bdce6 balrog
    int cons;
1721 20d8a3ed ths
    int mux_cnt;
1722 20d8a3ed ths
    int term_got_escape;
1723 20d8a3ed ths
    int max_size;
1724 20d8a3ed ths
} MuxDriver;
1725 20d8a3ed ths
1726 20d8a3ed ths
1727 20d8a3ed ths
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1728 20d8a3ed ths
{
1729 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1730 20d8a3ed ths
    int ret;
1731 20d8a3ed ths
    if (!term_timestamps) {
1732 20d8a3ed ths
        ret = d->drv->chr_write(d->drv, buf, len);
1733 20d8a3ed ths
    } else {
1734 20d8a3ed ths
        int i;
1735 20d8a3ed ths
1736 20d8a3ed ths
        ret = 0;
1737 20d8a3ed ths
        for(i = 0; i < len; i++) {
1738 20d8a3ed ths
            ret += d->drv->chr_write(d->drv, buf+i, 1);
1739 20d8a3ed ths
            if (buf[i] == '\n') {
1740 20d8a3ed ths
                char buf1[64];
1741 20d8a3ed ths
                int64_t ti;
1742 20d8a3ed ths
                int secs;
1743 20d8a3ed ths
1744 20d8a3ed ths
                ti = get_clock();
1745 20d8a3ed ths
                if (term_timestamps_start == -1)
1746 20d8a3ed ths
                    term_timestamps_start = ti;
1747 20d8a3ed ths
                ti -= term_timestamps_start;
1748 20d8a3ed ths
                secs = ti / 1000000000;
1749 20d8a3ed ths
                snprintf(buf1, sizeof(buf1),
1750 20d8a3ed ths
                         "[%02d:%02d:%02d.%03d] ",
1751 20d8a3ed ths
                         secs / 3600,
1752 20d8a3ed ths
                         (secs / 60) % 60,
1753 20d8a3ed ths
                         secs % 60,
1754 20d8a3ed ths
                         (int)((ti / 1000000) % 1000));
1755 ffe8ab83 ths
                d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));
1756 20d8a3ed ths
            }
1757 20d8a3ed ths
        }
1758 20d8a3ed ths
    }
1759 20d8a3ed ths
    return ret;
1760 20d8a3ed ths
}
1761 20d8a3ed ths
1762 20d8a3ed ths
static char *mux_help[] = {
1763 20d8a3ed ths
    "% h    print this help\n\r",
1764 20d8a3ed ths
    "% x    exit emulator\n\r",
1765 20d8a3ed ths
    "% s    save disk data back to file (if -snapshot)\n\r",
1766 20d8a3ed ths
    "% t    toggle console timestamps\n\r"
1767 20d8a3ed ths
    "% b    send break (magic sysrq)\n\r",
1768 20d8a3ed ths
    "% c    switch between console and monitor\n\r",
1769 20d8a3ed ths
    "% %  sends %\n\r",
1770 20d8a3ed ths
    NULL
1771 20d8a3ed ths
};
1772 20d8a3ed ths
1773 20d8a3ed ths
static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1774 20d8a3ed ths
static void mux_print_help(CharDriverState *chr)
1775 20d8a3ed ths
{
1776 20d8a3ed ths
    int i, j;
1777 20d8a3ed ths
    char ebuf[15] = "Escape-Char";
1778 20d8a3ed ths
    char cbuf[50] = "\n\r";
1779 20d8a3ed ths
1780 20d8a3ed ths
    if (term_escape_char > 0 && term_escape_char < 26) {
1781 20d8a3ed ths
        sprintf(cbuf,"\n\r");
1782 20d8a3ed ths
        sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
1783 20d8a3ed ths
    } else {
1784 ffe8ab83 ths
        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r",
1785 ffe8ab83 ths
            term_escape_char);
1786 20d8a3ed ths
    }
1787 ffe8ab83 ths
    chr->chr_write(chr, (uint8_t *)cbuf, strlen(cbuf));
1788 20d8a3ed ths
    for (i = 0; mux_help[i] != NULL; i++) {
1789 20d8a3ed ths
        for (j=0; mux_help[i][j] != '\0'; j++) {
1790 20d8a3ed ths
            if (mux_help[i][j] == '%')
1791 ffe8ab83 ths
                chr->chr_write(chr, (uint8_t *)ebuf, strlen(ebuf));
1792 20d8a3ed ths
            else
1793 ffe8ab83 ths
                chr->chr_write(chr, (uint8_t *)&mux_help[i][j], 1);
1794 20d8a3ed ths
        }
1795 20d8a3ed ths
    }
1796 20d8a3ed ths
}
1797 20d8a3ed ths
1798 20d8a3ed ths
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1799 20d8a3ed ths
{
1800 20d8a3ed ths
    if (d->term_got_escape) {
1801 20d8a3ed ths
        d->term_got_escape = 0;
1802 20d8a3ed ths
        if (ch == term_escape_char)
1803 20d8a3ed ths
            goto send_char;
1804 20d8a3ed ths
        switch(ch) {
1805 20d8a3ed ths
        case '?':
1806 20d8a3ed ths
        case 'h':
1807 20d8a3ed ths
            mux_print_help(chr);
1808 20d8a3ed ths
            break;
1809 20d8a3ed ths
        case 'x':
1810 20d8a3ed ths
            {
1811 20d8a3ed ths
                 char *term =  "QEMU: Terminated\n\r";
1812 ffe8ab83 ths
                 chr->chr_write(chr,(uint8_t *)term,strlen(term));
1813 20d8a3ed ths
                 exit(0);
1814 20d8a3ed ths
                 break;
1815 20d8a3ed ths
            }
1816 20d8a3ed ths
        case 's':
1817 20d8a3ed ths
            {
1818 20d8a3ed ths
                int i;
1819 e4bcb14c ths
                for (i = 0; i < nb_drives; i++) {
1820 e4bcb14c ths
                        bdrv_commit(drives_table[i].bdrv);
1821 20d8a3ed ths
                }
1822 20d8a3ed ths
            }
1823 20d8a3ed ths
            break;
1824 20d8a3ed ths
        case 'b':
1825 36ddb83b balrog
            qemu_chr_event(chr, CHR_EVENT_BREAK);
1826 20d8a3ed ths
            break;
1827 20d8a3ed ths
        case 'c':
1828 20d8a3ed ths
            /* Switch to the next registered device */
1829 20d8a3ed ths
            chr->focus++;
1830 20d8a3ed ths
            if (chr->focus >= d->mux_cnt)
1831 20d8a3ed ths
                chr->focus = 0;
1832 20d8a3ed ths
            break;
1833 20d8a3ed ths
       case 't':
1834 20d8a3ed ths
           term_timestamps = !term_timestamps;
1835 20d8a3ed ths
           term_timestamps_start = -1;
1836 20d8a3ed ths
           break;
1837 20d8a3ed ths
        }
1838 20d8a3ed ths
    } else if (ch == term_escape_char) {
1839 20d8a3ed ths
        d->term_got_escape = 1;
1840 20d8a3ed ths
    } else {
1841 20d8a3ed ths
    send_char:
1842 20d8a3ed ths
        return 1;
1843 20d8a3ed ths
    }
1844 20d8a3ed ths
    return 0;
1845 20d8a3ed ths
}
1846 20d8a3ed ths
1847 bd9bdce6 balrog
static void mux_chr_accept_input(CharDriverState *chr)
1848 bd9bdce6 balrog
{
1849 bd9bdce6 balrog
    int m = chr->focus;
1850 bd9bdce6 balrog
    MuxDriver *d = chr->opaque;
1851 bd9bdce6 balrog
1852 bd9bdce6 balrog
    while (d->prod != d->cons &&
1853 bd9bdce6 balrog
           d->chr_can_read[m] &&
1854 bd9bdce6 balrog
           d->chr_can_read[m](d->ext_opaque[m])) {
1855 bd9bdce6 balrog
        d->chr_read[m](d->ext_opaque[m],
1856 bd9bdce6 balrog
                       &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
1857 bd9bdce6 balrog
    }
1858 bd9bdce6 balrog
}
1859 bd9bdce6 balrog
1860 20d8a3ed ths
static int mux_chr_can_read(void *opaque)
1861 20d8a3ed ths
{
1862 20d8a3ed ths
    CharDriverState *chr = opaque;
1863 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1864 bd9bdce6 balrog
1865 bd9bdce6 balrog
    if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
1866 bd9bdce6 balrog
        return 1;
1867 20d8a3ed ths
    if (d->chr_can_read[chr->focus])
1868 bd9bdce6 balrog
        return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
1869 20d8a3ed ths
    return 0;
1870 20d8a3ed ths
}
1871 20d8a3ed ths
1872 20d8a3ed ths
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1873 20d8a3ed ths
{
1874 20d8a3ed ths
    CharDriverState *chr = opaque;
1875 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1876 bd9bdce6 balrog
    int m = chr->focus;
1877 20d8a3ed ths
    int i;
1878 bd9bdce6 balrog
1879 bd9bdce6 balrog
    mux_chr_accept_input (opaque);
1880 bd9bdce6 balrog
1881 20d8a3ed ths
    for(i = 0; i < size; i++)
1882 bd9bdce6 balrog
        if (mux_proc_byte(chr, d, buf[i])) {
1883 bd9bdce6 balrog
            if (d->prod == d->cons &&
1884 bd9bdce6 balrog
                d->chr_can_read[m] &&
1885 bd9bdce6 balrog
                d->chr_can_read[m](d->ext_opaque[m]))
1886 bd9bdce6 balrog
                d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
1887 bd9bdce6 balrog
            else
1888 bd9bdce6 balrog
                d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
1889 bd9bdce6 balrog
        }
1890 20d8a3ed ths
}
1891 20d8a3ed ths
1892 20d8a3ed ths
static void mux_chr_event(void *opaque, int event)
1893 20d8a3ed ths
{
1894 20d8a3ed ths
    CharDriverState *chr = opaque;
1895 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1896 20d8a3ed ths
    int i;
1897 20d8a3ed ths
1898 20d8a3ed ths
    /* Send the event to all registered listeners */
1899 20d8a3ed ths
    for (i = 0; i < d->mux_cnt; i++)
1900 20d8a3ed ths
        if (d->chr_event[i])
1901 20d8a3ed ths
            d->chr_event[i](d->ext_opaque[i], event);
1902 20d8a3ed ths
}
1903 20d8a3ed ths
1904 20d8a3ed ths
static void mux_chr_update_read_handler(CharDriverState *chr)
1905 20d8a3ed ths
{
1906 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1907 20d8a3ed ths
1908 20d8a3ed ths
    if (d->mux_cnt >= MAX_MUX) {
1909 20d8a3ed ths
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
1910 20d8a3ed ths
        return;
1911 20d8a3ed ths
    }
1912 20d8a3ed ths
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
1913 20d8a3ed ths
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
1914 20d8a3ed ths
    d->chr_read[d->mux_cnt] = chr->chr_read;
1915 20d8a3ed ths
    d->chr_event[d->mux_cnt] = chr->chr_event;
1916 20d8a3ed ths
    /* Fix up the real driver with mux routines */
1917 20d8a3ed ths
    if (d->mux_cnt == 0) {
1918 20d8a3ed ths
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
1919 20d8a3ed ths
                              mux_chr_event, chr);
1920 20d8a3ed ths
    }
1921 20d8a3ed ths
    chr->focus = d->mux_cnt;
1922 20d8a3ed ths
    d->mux_cnt++;
1923 20d8a3ed ths
}
1924 20d8a3ed ths
1925 9596ebb7 pbrook
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
1926 20d8a3ed ths
{
1927 20d8a3ed ths
    CharDriverState *chr;
1928 20d8a3ed ths
    MuxDriver *d;
1929 20d8a3ed ths
1930 20d8a3ed ths
    chr = qemu_mallocz(sizeof(CharDriverState));
1931 20d8a3ed ths
    if (!chr)
1932 20d8a3ed ths
        return NULL;
1933 20d8a3ed ths
    d = qemu_mallocz(sizeof(MuxDriver));
1934 20d8a3ed ths
    if (!d) {
1935 20d8a3ed ths
        free(chr);
1936 20d8a3ed ths
        return NULL;
1937 20d8a3ed ths
    }
1938 20d8a3ed ths
1939 20d8a3ed ths
    chr->opaque = d;
1940 20d8a3ed ths
    d->drv = drv;
1941 20d8a3ed ths
    chr->focus = -1;
1942 20d8a3ed ths
    chr->chr_write = mux_chr_write;
1943 20d8a3ed ths
    chr->chr_update_read_handler = mux_chr_update_read_handler;
1944 bd9bdce6 balrog
    chr->chr_accept_input = mux_chr_accept_input;
1945 20d8a3ed ths
    return chr;
1946 20d8a3ed ths
}
1947 20d8a3ed ths
1948 20d8a3ed ths
1949 fd1dff4b bellard
#ifdef _WIN32
1950 82c643ff bellard
1951 fd1dff4b bellard
static void socket_cleanup(void)
1952 fd1dff4b bellard
{
1953 fd1dff4b bellard
    WSACleanup();
1954 fd1dff4b bellard
}
1955 82c643ff bellard
1956 fd1dff4b bellard
static int socket_init(void)
1957 fd1dff4b bellard
{
1958 fd1dff4b bellard
    WSADATA Data;
1959 fd1dff4b bellard
    int ret, err;
1960 fd1dff4b bellard
1961 fd1dff4b bellard
    ret = WSAStartup(MAKEWORD(2,2), &Data);
1962 fd1dff4b bellard
    if (ret != 0) {
1963 fd1dff4b bellard
        err = WSAGetLastError();
1964 fd1dff4b bellard
        fprintf(stderr, "WSAStartup: %d\n", err);
1965 fd1dff4b bellard
        return -1;
1966 fd1dff4b bellard
    }
1967 fd1dff4b bellard
    atexit(socket_cleanup);
1968 fd1dff4b bellard
    return 0;
1969 fd1dff4b bellard
}
1970 fd1dff4b bellard
1971 fd1dff4b bellard
static int send_all(int fd, const uint8_t *buf, int len1)
1972 fd1dff4b bellard
{
1973 fd1dff4b bellard
    int ret, len;
1974 3b46e624 ths
1975 fd1dff4b bellard
    len = len1;
1976 fd1dff4b bellard
    while (len > 0) {
1977 fd1dff4b bellard
        ret = send(fd, buf, len, 0);
1978 fd1dff4b bellard
        if (ret < 0) {
1979 fd1dff4b bellard
            int errno;
1980 fd1dff4b bellard
            errno = WSAGetLastError();
1981 fd1dff4b bellard
            if (errno != WSAEWOULDBLOCK) {
1982 fd1dff4b bellard
                return -1;
1983 fd1dff4b bellard
            }
1984 fd1dff4b bellard
        } else if (ret == 0) {
1985 fd1dff4b bellard
            break;
1986 fd1dff4b bellard
        } else {
1987 fd1dff4b bellard
            buf += ret;
1988 fd1dff4b bellard
            len -= ret;
1989 fd1dff4b bellard
        }
1990 fd1dff4b bellard
    }
1991 fd1dff4b bellard
    return len1 - len;
1992 fd1dff4b bellard
}
1993 fd1dff4b bellard
1994 fd1dff4b bellard
void socket_set_nonblock(int fd)
1995 fd1dff4b bellard
{
1996 fd1dff4b bellard
    unsigned long opt = 1;
1997 fd1dff4b bellard
    ioctlsocket(fd, FIONBIO, &opt);
1998 fd1dff4b bellard
}
1999 fd1dff4b bellard
2000 fd1dff4b bellard
#else
2001 fd1dff4b bellard
2002 1d96905d bellard
static int unix_write(int fd, const uint8_t *buf, int len1)
2003 1d96905d bellard
{
2004 1d96905d bellard
    int ret, len;
2005 1d96905d bellard
2006 1d96905d bellard
    len = len1;
2007 1d96905d bellard
    while (len > 0) {
2008 1d96905d bellard
        ret = write(fd, buf, len);
2009 1d96905d bellard
        if (ret < 0) {
2010 1d96905d bellard
            if (errno != EINTR && errno != EAGAIN)
2011 1d96905d bellard
                return -1;
2012 1d96905d bellard
        } else if (ret == 0) {
2013 1d96905d bellard
            break;
2014 1d96905d bellard
        } else {
2015 1d96905d bellard
            buf += ret;
2016 1d96905d bellard
            len -= ret;
2017 1d96905d bellard
        }
2018 1d96905d bellard
    }
2019 1d96905d bellard
    return len1 - len;
2020 1d96905d bellard
}
2021 1d96905d bellard
2022 fd1dff4b bellard
static inline int send_all(int fd, const uint8_t *buf, int len1)
2023 fd1dff4b bellard
{
2024 fd1dff4b bellard
    return unix_write(fd, buf, len1);
2025 fd1dff4b bellard
}
2026 fd1dff4b bellard
2027 fd1dff4b bellard
void socket_set_nonblock(int fd)
2028 fd1dff4b bellard
{
2029 fd1dff4b bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
2030 fd1dff4b bellard
}
2031 fd1dff4b bellard
#endif /* !_WIN32 */
2032 fd1dff4b bellard
2033 fd1dff4b bellard
#ifndef _WIN32
2034 fd1dff4b bellard
2035 fd1dff4b bellard
typedef struct {
2036 fd1dff4b bellard
    int fd_in, fd_out;
2037 fd1dff4b bellard
    int max_size;
2038 fd1dff4b bellard
} FDCharDriver;
2039 fd1dff4b bellard
2040 20d8a3ed ths
#define STDIO_MAX_CLIENTS 1
2041 20d8a3ed ths
static int stdio_nb_clients = 0;
2042 fd1dff4b bellard
2043 82c643ff bellard
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2044 82c643ff bellard
{
2045 82c643ff bellard
    FDCharDriver *s = chr->opaque;
2046 1d96905d bellard
    return unix_write(s->fd_out, buf, len);
2047 82c643ff bellard
}
2048 82c643ff bellard
2049 7c9d8e07 bellard
static int fd_chr_read_poll(void *opaque)
2050 7c9d8e07 bellard
{
2051 7c9d8e07 bellard
    CharDriverState *chr = opaque;
2052 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
2053 7c9d8e07 bellard
2054 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2055 7c9d8e07 bellard
    return s->max_size;
2056 7c9d8e07 bellard
}
2057 7c9d8e07 bellard
2058 7c9d8e07 bellard
static void fd_chr_read(void *opaque)
2059 7c9d8e07 bellard
{
2060 7c9d8e07 bellard
    CharDriverState *chr = opaque;
2061 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
2062 7c9d8e07 bellard
    int size, len;
2063 7c9d8e07 bellard
    uint8_t buf[1024];
2064 3b46e624 ths
2065 7c9d8e07 bellard
    len = sizeof(buf);
2066 7c9d8e07 bellard
    if (len > s->max_size)
2067 7c9d8e07 bellard
        len = s->max_size;
2068 7c9d8e07 bellard
    if (len == 0)
2069 7c9d8e07 bellard
        return;
2070 7c9d8e07 bellard
    size = read(s->fd_in, buf, len);
2071 188157fe pbrook
    if (size == 0) {
2072 188157fe pbrook
        /* FD has been closed. Remove it from the active list.  */
2073 188157fe pbrook
        qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2074 188157fe pbrook
        return;
2075 188157fe pbrook
    }
2076 7c9d8e07 bellard
    if (size > 0) {
2077 e5b0bc44 pbrook
        qemu_chr_read(chr, buf, size);
2078 7c9d8e07 bellard
    }
2079 7c9d8e07 bellard
}
2080 7c9d8e07 bellard
2081 e5b0bc44 pbrook
static void fd_chr_update_read_handler(CharDriverState *chr)
2082 82c643ff bellard
{
2083 82c643ff bellard
    FDCharDriver *s = chr->opaque;
2084 82c643ff bellard
2085 f8d179e3 bellard
    if (s->fd_in >= 0) {
2086 f8d179e3 bellard
        if (nographic && s->fd_in == 0) {
2087 f8d179e3 bellard
        } else {
2088 5fafdf24 ths
            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll,
2089 7c9d8e07 bellard
                                 fd_chr_read, NULL, chr);
2090 f8d179e3 bellard
        }
2091 82c643ff bellard
    }
2092 82c643ff bellard
}
2093 82c643ff bellard
2094 a11d070e balrog
static void fd_chr_close(struct CharDriverState *chr)
2095 a11d070e balrog
{
2096 a11d070e balrog
    FDCharDriver *s = chr->opaque;
2097 a11d070e balrog
2098 a11d070e balrog
    if (s->fd_in >= 0) {
2099 a11d070e balrog
        if (nographic && s->fd_in == 0) {
2100 a11d070e balrog
        } else {
2101 a11d070e balrog
            qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
2102 a11d070e balrog
        }
2103 a11d070e balrog
    }
2104 a11d070e balrog
2105 a11d070e balrog
    qemu_free(s);
2106 a11d070e balrog
}
2107 a11d070e balrog
2108 82c643ff bellard
/* open a character device to a unix fd */
2109 52f61fde ths
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
2110 82c643ff bellard
{
2111 82c643ff bellard
    CharDriverState *chr;
2112 82c643ff bellard
    FDCharDriver *s;
2113 82c643ff bellard
2114 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2115 82c643ff bellard
    if (!chr)
2116 82c643ff bellard
        return NULL;
2117 82c643ff bellard
    s = qemu_mallocz(sizeof(FDCharDriver));
2118 82c643ff bellard
    if (!s) {
2119 82c643ff bellard
        free(chr);
2120 82c643ff bellard
        return NULL;
2121 82c643ff bellard
    }
2122 82c643ff bellard
    s->fd_in = fd_in;
2123 82c643ff bellard
    s->fd_out = fd_out;
2124 82c643ff bellard
    chr->opaque = s;
2125 82c643ff bellard
    chr->chr_write = fd_chr_write;
2126 e5b0bc44 pbrook
    chr->chr_update_read_handler = fd_chr_update_read_handler;
2127 a11d070e balrog
    chr->chr_close = fd_chr_close;
2128 86e94dea ths
2129 86e94dea ths
    qemu_chr_reset(chr);
2130 86e94dea ths
2131 82c643ff bellard
    return chr;
2132 82c643ff bellard
}
2133 82c643ff bellard
2134 52f61fde ths
static CharDriverState *qemu_chr_open_file_out(const char *file_out)
2135 f8d179e3 bellard
{
2136 f8d179e3 bellard
    int fd_out;
2137 f8d179e3 bellard
2138 aeb30be6 balrog
    TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
2139 f8d179e3 bellard
    if (fd_out < 0)
2140 f8d179e3 bellard
        return NULL;
2141 f8d179e3 bellard
    return qemu_chr_open_fd(-1, fd_out);
2142 f8d179e3 bellard
}
2143 f8d179e3 bellard
2144 52f61fde ths
static CharDriverState *qemu_chr_open_pipe(const char *filename)
2145 f8d179e3 bellard
{
2146 c26c1c4b ths
    int fd_in, fd_out;
2147 c26c1c4b ths
    char filename_in[256], filename_out[256];
2148 c26c1c4b ths
2149 c26c1c4b ths
    snprintf(filename_in, 256, "%s.in", filename);
2150 c26c1c4b ths
    snprintf(filename_out, 256, "%s.out", filename);
2151 aeb30be6 balrog
    TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2152 aeb30be6 balrog
    TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
2153 c26c1c4b ths
    if (fd_in < 0 || fd_out < 0) {
2154 c26c1c4b ths
        if (fd_in >= 0)
2155 c26c1c4b ths
            close(fd_in);
2156 c26c1c4b ths
        if (fd_out >= 0)
2157 c26c1c4b ths
            close(fd_out);
2158 aeb30be6 balrog
        TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
2159 c26c1c4b ths
        if (fd_in < 0)
2160 c26c1c4b ths
            return NULL;
2161 c26c1c4b ths
    }
2162 c26c1c4b ths
    return qemu_chr_open_fd(fd_in, fd_out);
2163 f8d179e3 bellard
}
2164 f8d179e3 bellard
2165 f8d179e3 bellard
2166 82c643ff bellard
/* for STDIO, we handle the case where several clients use it
2167 82c643ff bellard
   (nographic mode) */
2168 82c643ff bellard
2169 aa0bc6b6 bellard
#define TERM_FIFO_MAX_SIZE 1
2170 aa0bc6b6 bellard
2171 aa0bc6b6 bellard
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
2172 1dce7c3c bellard
static int term_fifo_size;
2173 330d0414 bellard
2174 7c9d8e07 bellard
static int stdio_read_poll(void *opaque)
2175 82c643ff bellard
{
2176 20d8a3ed ths
    CharDriverState *chr = opaque;
2177 aa0bc6b6 bellard
2178 20d8a3ed ths
    /* try to flush the queue if needed */
2179 20d8a3ed ths
    if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2180 20d8a3ed ths
        qemu_chr_read(chr, term_fifo, 1);
2181 20d8a3ed ths
        term_fifo_size = 0;
2182 aa0bc6b6 bellard
    }
2183 20d8a3ed ths
    /* see if we can absorb more chars */
2184 20d8a3ed ths
    if (term_fifo_size == 0)
2185 20d8a3ed ths
        return 1;
2186 20d8a3ed ths
    else
2187 20d8a3ed ths
        return 0;
2188 82c643ff bellard
}
2189 82c643ff bellard
2190 7c9d8e07 bellard
static void stdio_read(void *opaque)
2191 82c643ff bellard
{
2192 7c9d8e07 bellard
    int size;
2193 7c9d8e07 bellard
    uint8_t buf[1];
2194 20d8a3ed ths
    CharDriverState *chr = opaque;
2195 20d8a3ed ths
2196 7c9d8e07 bellard
    size = read(0, buf, 1);
2197 519945df pbrook
    if (size == 0) {
2198 519945df pbrook
        /* stdin has been closed. Remove it from the active list.  */
2199 519945df pbrook
        qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2200 519945df pbrook
        return;
2201 519945df pbrook
    }
2202 20d8a3ed ths
    if (size > 0) {
2203 20d8a3ed ths
        if (qemu_chr_can_read(chr) > 0) {
2204 20d8a3ed ths
            qemu_chr_read(chr, buf, 1);
2205 20d8a3ed ths
        } else if (term_fifo_size == 0) {
2206 20d8a3ed ths
            term_fifo[term_fifo_size++] = buf[0];
2207 1dce7c3c bellard
        }
2208 1dce7c3c bellard
    }
2209 1dce7c3c bellard
}
2210 1dce7c3c bellard
2211 8d11df9e bellard
/* init terminal so that we can grab keys */
2212 8d11df9e bellard
static struct termios oldtty;
2213 8d11df9e bellard
static int old_fd0_flags;
2214 a11d070e balrog
static int term_atexit_done;
2215 8d11df9e bellard
2216 8d11df9e bellard
static void term_exit(void)
2217 8d11df9e bellard
{
2218 8d11df9e bellard
    tcsetattr (0, TCSANOW, &oldtty);
2219 8d11df9e bellard
    fcntl(0, F_SETFL, old_fd0_flags);
2220 8d11df9e bellard
}
2221 8d11df9e bellard
2222 8d11df9e bellard
static void term_init(void)
2223 8d11df9e bellard
{
2224 8d11df9e bellard
    struct termios tty;
2225 8d11df9e bellard
2226 8d11df9e bellard
    tcgetattr (0, &tty);
2227 8d11df9e bellard
    oldtty = tty;
2228 8d11df9e bellard
    old_fd0_flags = fcntl(0, F_GETFL);
2229 8d11df9e bellard
2230 8d11df9e bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2231 8d11df9e bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2232 8d11df9e bellard
    tty.c_oflag |= OPOST;
2233 8d11df9e bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2234 8d11df9e bellard
    /* if graphical mode, we allow Ctrl-C handling */
2235 8d11df9e bellard
    if (nographic)
2236 8d11df9e bellard
        tty.c_lflag &= ~ISIG;
2237 8d11df9e bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
2238 8d11df9e bellard
    tty.c_cflag |= CS8;
2239 8d11df9e bellard
    tty.c_cc[VMIN] = 1;
2240 8d11df9e bellard
    tty.c_cc[VTIME] = 0;
2241 3b46e624 ths
2242 8d11df9e bellard
    tcsetattr (0, TCSANOW, &tty);
2243 8d11df9e bellard
2244 a11d070e balrog
    if (!term_atexit_done++)
2245 a11d070e balrog
        atexit(term_exit);
2246 8d11df9e bellard
2247 8d11df9e bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
2248 8d11df9e bellard
}
2249 8d11df9e bellard
2250 a11d070e balrog
static void qemu_chr_close_stdio(struct CharDriverState *chr)
2251 a11d070e balrog
{
2252 a11d070e balrog
    term_exit();
2253 a11d070e balrog
    stdio_nb_clients--;
2254 a11d070e balrog
    qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2255 a11d070e balrog
    fd_chr_close(chr);
2256 a11d070e balrog
}
2257 a11d070e balrog
2258 52f61fde ths
static CharDriverState *qemu_chr_open_stdio(void)
2259 82c643ff bellard
{
2260 82c643ff bellard
    CharDriverState *chr;
2261 82c643ff bellard
2262 20d8a3ed ths
    if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2263 20d8a3ed ths
        return NULL;
2264 20d8a3ed ths
    chr = qemu_chr_open_fd(0, 1);
2265 a11d070e balrog
    chr->chr_close = qemu_chr_close_stdio;
2266 20d8a3ed ths
    qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2267 20d8a3ed ths
    stdio_nb_clients++;
2268 20d8a3ed ths
    term_init();
2269 20d8a3ed ths
2270 82c643ff bellard
    return chr;
2271 82c643ff bellard
}
2272 82c643ff bellard
2273 aec62507 ths
#if defined(__linux__) || defined(__sun__)
2274 52f61fde ths
static CharDriverState *qemu_chr_open_pty(void)
2275 82c643ff bellard
{
2276 91fc2119 bellard
    struct termios tty;
2277 82c643ff bellard
    char slave_name[1024];
2278 82c643ff bellard
    int master_fd, slave_fd;
2279 3b46e624 ths
2280 aec62507 ths
#if defined(__linux__)
2281 82c643ff bellard
    /* Not satisfying */
2282 82c643ff bellard
    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
2283 82c643ff bellard
        return NULL;
2284 82c643ff bellard
    }
2285 aec62507 ths
#endif
2286 3b46e624 ths
2287 91fc2119 bellard
    /* Disabling local echo and line-buffered output */
2288 91fc2119 bellard
    tcgetattr (master_fd, &tty);
2289 91fc2119 bellard
    tty.c_lflag &= ~(ECHO|ICANON|ISIG);
2290 91fc2119 bellard
    tty.c_cc[VMIN] = 1;
2291 91fc2119 bellard
    tty.c_cc[VTIME] = 0;
2292 91fc2119 bellard
    tcsetattr (master_fd, TCSAFLUSH, &tty);
2293 91fc2119 bellard
2294 82c643ff bellard
    fprintf(stderr, "char device redirected to %s\n", slave_name);
2295 82c643ff bellard
    return qemu_chr_open_fd(master_fd, master_fd);
2296 82c643ff bellard
}
2297 f8d179e3 bellard
2298 5fafdf24 ths
static void tty_serial_init(int fd, int speed,
2299 f8d179e3 bellard
                            int parity, int data_bits, int stop_bits)
2300 f8d179e3 bellard
{
2301 f8d179e3 bellard
    struct termios tty;
2302 f8d179e3 bellard
    speed_t spd;
2303 f8d179e3 bellard
2304 e57a8c0e bellard
#if 0
2305 5fafdf24 ths
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n",
2306 e57a8c0e bellard
           speed, parity, data_bits, stop_bits);
2307 e57a8c0e bellard
#endif
2308 e57a8c0e bellard
    tcgetattr (fd, &tty);
2309 f8d179e3 bellard
2310 a7954218 balrog
#define MARGIN 1.1
2311 a7954218 balrog
    if (speed <= 50 * MARGIN)
2312 f8d179e3 bellard
        spd = B50;
2313 a7954218 balrog
    else if (speed <= 75 * MARGIN)
2314 f8d179e3 bellard
        spd = B75;
2315 a7954218 balrog
    else if (speed <= 300 * MARGIN)
2316 f8d179e3 bellard
        spd = B300;
2317 a7954218 balrog
    else if (speed <= 600 * MARGIN)
2318 f8d179e3 bellard
        spd = B600;
2319 a7954218 balrog
    else if (speed <= 1200 * MARGIN)
2320 f8d179e3 bellard
        spd = B1200;
2321 a7954218 balrog
    else if (speed <= 2400 * MARGIN)
2322 f8d179e3 bellard
        spd = B2400;
2323 a7954218 balrog
    else if (speed <= 4800 * MARGIN)
2324 f8d179e3 bellard
        spd = B4800;
2325 a7954218 balrog
    else if (speed <= 9600 * MARGIN)
2326 f8d179e3 bellard
        spd = B9600;
2327 a7954218 balrog
    else if (speed <= 19200 * MARGIN)
2328 f8d179e3 bellard
        spd = B19200;
2329 a7954218 balrog
    else if (speed <= 38400 * MARGIN)
2330 f8d179e3 bellard
        spd = B38400;
2331 a7954218 balrog
    else if (speed <= 57600 * MARGIN)
2332 f8d179e3 bellard
        spd = B57600;
2333 a7954218 balrog
    else if (speed <= 115200 * MARGIN)
2334 a7954218 balrog
        spd = B115200;
2335 a7954218 balrog
    else
2336 f8d179e3 bellard
        spd = B115200;
2337 f8d179e3 bellard
2338 f8d179e3 bellard
    cfsetispeed(&tty, spd);
2339 f8d179e3 bellard
    cfsetospeed(&tty, spd);
2340 f8d179e3 bellard
2341 f8d179e3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2342 f8d179e3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2343 f8d179e3 bellard
    tty.c_oflag |= OPOST;
2344 f8d179e3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
2345 094eed6c bellard
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
2346 f8d179e3 bellard
    switch(data_bits) {
2347 f8d179e3 bellard
    default:
2348 f8d179e3 bellard
    case 8:
2349 f8d179e3 bellard
        tty.c_cflag |= CS8;
2350 f8d179e3 bellard
        break;
2351 f8d179e3 bellard
    case 7:
2352 f8d179e3 bellard
        tty.c_cflag |= CS7;
2353 f8d179e3 bellard
        break;
2354 f8d179e3 bellard
    case 6:
2355 f8d179e3 bellard
        tty.c_cflag |= CS6;
2356 f8d179e3 bellard
        break;
2357 f8d179e3 bellard
    case 5:
2358 f8d179e3 bellard
        tty.c_cflag |= CS5;
2359 f8d179e3 bellard
        break;
2360 f8d179e3 bellard
    }
2361 f8d179e3 bellard
    switch(parity) {
2362 f8d179e3 bellard
    default:
2363 f8d179e3 bellard
    case 'N':
2364 f8d179e3 bellard
        break;
2365 f8d179e3 bellard
    case 'E':
2366 f8d179e3 bellard
        tty.c_cflag |= PARENB;
2367 f8d179e3 bellard
        break;
2368 f8d179e3 bellard
    case 'O':
2369 f8d179e3 bellard
        tty.c_cflag |= PARENB | PARODD;
2370 f8d179e3 bellard
        break;
2371 f8d179e3 bellard
    }
2372 094eed6c bellard
    if (stop_bits == 2)
2373 094eed6c bellard
        tty.c_cflag |= CSTOPB;
2374 3b46e624 ths
2375 f8d179e3 bellard
    tcsetattr (fd, TCSANOW, &tty);
2376 f8d179e3 bellard
}
2377 f8d179e3 bellard
2378 e57a8c0e bellard
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
2379 f8d179e3 bellard
{
2380 f8d179e3 bellard
    FDCharDriver *s = chr->opaque;
2381 3b46e624 ths
2382 e57a8c0e bellard
    switch(cmd) {
2383 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_PARAMS:
2384 e57a8c0e bellard
        {
2385 e57a8c0e bellard
            QEMUSerialSetParams *ssp = arg;
2386 5fafdf24 ths
            tty_serial_init(s->fd_in, ssp->speed, ssp->parity,
2387 e57a8c0e bellard
                            ssp->data_bits, ssp->stop_bits);
2388 e57a8c0e bellard
        }
2389 e57a8c0e bellard
        break;
2390 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_BREAK:
2391 e57a8c0e bellard
        {
2392 e57a8c0e bellard
            int enable = *(int *)arg;
2393 e57a8c0e bellard
            if (enable)
2394 e57a8c0e bellard
                tcsendbreak(s->fd_in, 1);
2395 e57a8c0e bellard
        }
2396 e57a8c0e bellard
        break;
2397 e57a8c0e bellard
    default:
2398 e57a8c0e bellard
        return -ENOTSUP;
2399 e57a8c0e bellard
    }
2400 e57a8c0e bellard
    return 0;
2401 f8d179e3 bellard
}
2402 f8d179e3 bellard
2403 52f61fde ths
static CharDriverState *qemu_chr_open_tty(const char *filename)
2404 f8d179e3 bellard
{
2405 f8d179e3 bellard
    CharDriverState *chr;
2406 f8d179e3 bellard
    int fd;
2407 f8d179e3 bellard
2408 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
2409 f8d179e3 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
2410 f8d179e3 bellard
    tty_serial_init(fd, 115200, 'N', 8, 1);
2411 f8d179e3 bellard
    chr = qemu_chr_open_fd(fd, fd);
2412 aeb30be6 balrog
    if (!chr) {
2413 aeb30be6 balrog
        close(fd);
2414 f8d179e3 bellard
        return NULL;
2415 aeb30be6 balrog
    }
2416 e57a8c0e bellard
    chr->chr_ioctl = tty_serial_ioctl;
2417 86e94dea ths
    qemu_chr_reset(chr);
2418 e57a8c0e bellard
    return chr;
2419 e57a8c0e bellard
}
2420 aec62507 ths
#else  /* ! __linux__ && ! __sun__ */
2421 aec62507 ths
static CharDriverState *qemu_chr_open_pty(void)
2422 aec62507 ths
{
2423 aec62507 ths
    return NULL;
2424 aec62507 ths
}
2425 aec62507 ths
#endif /* __linux__ || __sun__ */
2426 e57a8c0e bellard
2427 aec62507 ths
#if defined(__linux__)
2428 5867c88a ths
typedef struct {
2429 5867c88a ths
    int fd;
2430 5867c88a ths
    int mode;
2431 5867c88a ths
} ParallelCharDriver;
2432 5867c88a ths
2433 5867c88a ths
static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2434 5867c88a ths
{
2435 5867c88a ths
    if (s->mode != mode) {
2436 5867c88a ths
        int m = mode;
2437 5867c88a ths
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
2438 5867c88a ths
            return 0;
2439 5867c88a ths
        s->mode = mode;
2440 5867c88a ths
    }
2441 5867c88a ths
    return 1;
2442 5867c88a ths
}
2443 5867c88a ths
2444 e57a8c0e bellard
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2445 e57a8c0e bellard
{
2446 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2447 5867c88a ths
    int fd = drv->fd;
2448 e57a8c0e bellard
    uint8_t b;
2449 e57a8c0e bellard
2450 e57a8c0e bellard
    switch(cmd) {
2451 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_DATA:
2452 e57a8c0e bellard
        if (ioctl(fd, PPRDATA, &b) < 0)
2453 e57a8c0e bellard
            return -ENOTSUP;
2454 e57a8c0e bellard
        *(uint8_t *)arg = b;
2455 e57a8c0e bellard
        break;
2456 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_DATA:
2457 e57a8c0e bellard
        b = *(uint8_t *)arg;
2458 e57a8c0e bellard
        if (ioctl(fd, PPWDATA, &b) < 0)
2459 e57a8c0e bellard
            return -ENOTSUP;
2460 e57a8c0e bellard
        break;
2461 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_CONTROL:
2462 e57a8c0e bellard
        if (ioctl(fd, PPRCONTROL, &b) < 0)
2463 e57a8c0e bellard
            return -ENOTSUP;
2464 5867c88a ths
        /* Linux gives only the lowest bits, and no way to know data
2465 5867c88a ths
           direction! For better compatibility set the fixed upper
2466 5867c88a ths
           bits. */
2467 5867c88a ths
        *(uint8_t *)arg = b | 0xc0;
2468 e57a8c0e bellard
        break;
2469 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_CONTROL:
2470 e57a8c0e bellard
        b = *(uint8_t *)arg;
2471 e57a8c0e bellard
        if (ioctl(fd, PPWCONTROL, &b) < 0)
2472 e57a8c0e bellard
            return -ENOTSUP;
2473 e57a8c0e bellard
        break;
2474 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_STATUS:
2475 e57a8c0e bellard
        if (ioctl(fd, PPRSTATUS, &b) < 0)
2476 e57a8c0e bellard
            return -ENOTSUP;
2477 e57a8c0e bellard
        *(uint8_t *)arg = b;
2478 e57a8c0e bellard
        break;
2479 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ_ADDR:
2480 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2481 5867c88a ths
            struct ParallelIOArg *parg = arg;
2482 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2483 5867c88a ths
            if (n != parg->count) {
2484 5867c88a ths
                return -EIO;
2485 5867c88a ths
            }
2486 5867c88a ths
        }
2487 5867c88a ths
        break;
2488 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ:
2489 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2490 5867c88a ths
            struct ParallelIOArg *parg = arg;
2491 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2492 5867c88a ths
            if (n != parg->count) {
2493 5867c88a ths
                return -EIO;
2494 5867c88a ths
            }
2495 5867c88a ths
        }
2496 5867c88a ths
        break;
2497 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2498 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2499 5867c88a ths
            struct ParallelIOArg *parg = arg;
2500 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2501 5867c88a ths
            if (n != parg->count) {
2502 5867c88a ths
                return -EIO;
2503 5867c88a ths
            }
2504 5867c88a ths
        }
2505 5867c88a ths
        break;
2506 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE:
2507 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2508 5867c88a ths
            struct ParallelIOArg *parg = arg;
2509 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2510 5867c88a ths
            if (n != parg->count) {
2511 5867c88a ths
                return -EIO;
2512 5867c88a ths
            }
2513 5867c88a ths
        }
2514 5867c88a ths
        break;
2515 e57a8c0e bellard
    default:
2516 e57a8c0e bellard
        return -ENOTSUP;
2517 e57a8c0e bellard
    }
2518 e57a8c0e bellard
    return 0;
2519 e57a8c0e bellard
}
2520 e57a8c0e bellard
2521 5867c88a ths
static void pp_close(CharDriverState *chr)
2522 5867c88a ths
{
2523 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2524 5867c88a ths
    int fd = drv->fd;
2525 5867c88a ths
2526 5867c88a ths
    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2527 5867c88a ths
    ioctl(fd, PPRELEASE);
2528 5867c88a ths
    close(fd);
2529 5867c88a ths
    qemu_free(drv);
2530 5867c88a ths
}
2531 5867c88a ths
2532 52f61fde ths
static CharDriverState *qemu_chr_open_pp(const char *filename)
2533 e57a8c0e bellard
{
2534 e57a8c0e bellard
    CharDriverState *chr;
2535 5867c88a ths
    ParallelCharDriver *drv;
2536 e57a8c0e bellard
    int fd;
2537 e57a8c0e bellard
2538 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR));
2539 e57a8c0e bellard
    if (fd < 0)
2540 e57a8c0e bellard
        return NULL;
2541 e57a8c0e bellard
2542 e57a8c0e bellard
    if (ioctl(fd, PPCLAIM) < 0) {
2543 e57a8c0e bellard
        close(fd);
2544 e57a8c0e bellard
        return NULL;
2545 e57a8c0e bellard
    }
2546 e57a8c0e bellard
2547 5867c88a ths
    drv = qemu_mallocz(sizeof(ParallelCharDriver));
2548 5867c88a ths
    if (!drv) {
2549 5867c88a ths
        close(fd);
2550 5867c88a ths
        return NULL;
2551 5867c88a ths
    }
2552 5867c88a ths
    drv->fd = fd;
2553 5867c88a ths
    drv->mode = IEEE1284_MODE_COMPAT;
2554 5867c88a ths
2555 e57a8c0e bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2556 e57a8c0e bellard
    if (!chr) {
2557 5867c88a ths
        qemu_free(drv);
2558 e57a8c0e bellard
        close(fd);
2559 e57a8c0e bellard
        return NULL;
2560 e57a8c0e bellard
    }
2561 e57a8c0e bellard
    chr->chr_write = null_chr_write;
2562 e57a8c0e bellard
    chr->chr_ioctl = pp_ioctl;
2563 5867c88a ths
    chr->chr_close = pp_close;
2564 5867c88a ths
    chr->opaque = drv;
2565 86e94dea ths
2566 86e94dea ths
    qemu_chr_reset(chr);
2567 86e94dea ths
2568 f8d179e3 bellard
    return chr;
2569 f8d179e3 bellard
}
2570 aec62507 ths
#endif /* __linux__ */
2571 f8d179e3 bellard
2572 aec62507 ths
#else /* _WIN32 */
2573 82c643ff bellard
2574 f331110f bellard
typedef struct {
2575 f331110f bellard
    int max_size;
2576 f331110f bellard
    HANDLE hcom, hrecv, hsend;
2577 f331110f bellard
    OVERLAPPED orecv, osend;
2578 f331110f bellard
    BOOL fpipe;
2579 f331110f bellard
    DWORD len;
2580 f331110f bellard
} WinCharState;
2581 f331110f bellard
2582 f331110f bellard
#define NSENDBUF 2048
2583 f331110f bellard
#define NRECVBUF 2048
2584 f331110f bellard
#define MAXCONNECT 1
2585 f331110f bellard
#define NTIMEOUT 5000
2586 f331110f bellard
2587 f331110f bellard
static int win_chr_poll(void *opaque);
2588 f331110f bellard
static int win_chr_pipe_poll(void *opaque);
2589 f331110f bellard
2590 087f4ae0 ths
static void win_chr_close(CharDriverState *chr)
2591 f331110f bellard
{
2592 087f4ae0 ths
    WinCharState *s = chr->opaque;
2593 087f4ae0 ths
2594 f331110f bellard
    if (s->hsend) {
2595 f331110f bellard
        CloseHandle(s->hsend);
2596 f331110f bellard
        s->hsend = NULL;
2597 f331110f bellard
    }
2598 f331110f bellard
    if (s->hrecv) {
2599 f331110f bellard
        CloseHandle(s->hrecv);
2600 f331110f bellard
        s->hrecv = NULL;
2601 f331110f bellard
    }
2602 f331110f bellard
    if (s->hcom) {
2603 f331110f bellard
        CloseHandle(s->hcom);
2604 f331110f bellard
        s->hcom = NULL;
2605 f331110f bellard
    }
2606 f331110f bellard
    if (s->fpipe)
2607 087f4ae0 ths
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
2608 f331110f bellard
    else
2609 087f4ae0 ths
        qemu_del_polling_cb(win_chr_poll, chr);
2610 f331110f bellard
}
2611 f331110f bellard
2612 087f4ae0 ths
static int win_chr_init(CharDriverState *chr, const char *filename)
2613 f331110f bellard
{
2614 f331110f bellard
    WinCharState *s = chr->opaque;
2615 f331110f bellard
    COMMCONFIG comcfg;
2616 f331110f bellard
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2617 f331110f bellard
    COMSTAT comstat;
2618 f331110f bellard
    DWORD size;
2619 f331110f bellard
    DWORD err;
2620 3b46e624 ths
2621 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2622 f331110f bellard
    if (!s->hsend) {
2623 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2624 f331110f bellard
        goto fail;
2625 f331110f bellard
    }
2626 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2627 f331110f bellard
    if (!s->hrecv) {
2628 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2629 f331110f bellard
        goto fail;
2630 f331110f bellard
    }
2631 f331110f bellard
2632 f331110f bellard
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2633 f331110f bellard
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2634 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2635 f331110f bellard
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2636 f331110f bellard
        s->hcom = NULL;
2637 f331110f bellard
        goto fail;
2638 f331110f bellard
    }
2639 3b46e624 ths
2640 f331110f bellard
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
2641 f331110f bellard
        fprintf(stderr, "Failed SetupComm\n");
2642 f331110f bellard
        goto fail;
2643 f331110f bellard
    }
2644 3b46e624 ths
2645 f331110f bellard
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2646 f331110f bellard
    size = sizeof(COMMCONFIG);
2647 f331110f bellard
    GetDefaultCommConfig(filename, &comcfg, &size);
2648 f331110f bellard
    comcfg.dcb.DCBlength = sizeof(DCB);
2649 f331110f bellard
    CommConfigDialog(filename, NULL, &comcfg);
2650 f331110f bellard
2651 f331110f bellard
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
2652 f331110f bellard
        fprintf(stderr, "Failed SetCommState\n");
2653 f331110f bellard
        goto fail;
2654 f331110f bellard
    }
2655 f331110f bellard
2656 f331110f bellard
    if (!SetCommMask(s->hcom, EV_ERR)) {
2657 f331110f bellard
        fprintf(stderr, "Failed SetCommMask\n");
2658 f331110f bellard
        goto fail;
2659 f331110f bellard
    }
2660 f331110f bellard
2661 f331110f bellard
    cto.ReadIntervalTimeout = MAXDWORD;
2662 f331110f bellard
    if (!SetCommTimeouts(s->hcom, &cto)) {
2663 f331110f bellard
        fprintf(stderr, "Failed SetCommTimeouts\n");
2664 f331110f bellard
        goto fail;
2665 f331110f bellard
    }
2666 3b46e624 ths
2667 f331110f bellard
    if (!ClearCommError(s->hcom, &err, &comstat)) {
2668 f331110f bellard
        fprintf(stderr, "Failed ClearCommError\n");
2669 f331110f bellard
        goto fail;
2670 f331110f bellard
    }
2671 087f4ae0 ths
    qemu_add_polling_cb(win_chr_poll, chr);
2672 f331110f bellard
    return 0;
2673 f331110f bellard
2674 f331110f bellard
 fail:
2675 087f4ae0 ths
    win_chr_close(chr);
2676 f331110f bellard
    return -1;
2677 f331110f bellard
}
2678 f331110f bellard
2679 f331110f bellard
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
2680 f331110f bellard
{
2681 f331110f bellard
    WinCharState *s = chr->opaque;
2682 f331110f bellard
    DWORD len, ret, size, err;
2683 f331110f bellard
2684 f331110f bellard
    len = len1;
2685 f331110f bellard
    ZeroMemory(&s->osend, sizeof(s->osend));
2686 f331110f bellard
    s->osend.hEvent = s->hsend;
2687 f331110f bellard
    while (len > 0) {
2688 f331110f bellard
        if (s->hsend)
2689 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2690 f331110f bellard
        else
2691 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
2692 f331110f bellard
        if (!ret) {
2693 f331110f bellard
            err = GetLastError();
2694 f331110f bellard
            if (err == ERROR_IO_PENDING) {
2695 f331110f bellard
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2696 f331110f bellard
                if (ret) {
2697 f331110f bellard
                    buf += size;
2698 f331110f bellard
                    len -= size;
2699 f331110f bellard
                } else {
2700 f331110f bellard
                    break;
2701 f331110f bellard
                }
2702 f331110f bellard
            } else {
2703 f331110f bellard
                break;
2704 f331110f bellard
            }
2705 f331110f bellard
        } else {
2706 f331110f bellard
            buf += size;
2707 f331110f bellard
            len -= size;
2708 f331110f bellard
        }
2709 f331110f bellard
    }
2710 f331110f bellard
    return len1 - len;
2711 f331110f bellard
}
2712 f331110f bellard
2713 087f4ae0 ths
static int win_chr_read_poll(CharDriverState *chr)
2714 f331110f bellard
{
2715 087f4ae0 ths
    WinCharState *s = chr->opaque;
2716 087f4ae0 ths
2717 087f4ae0 ths
    s->max_size = qemu_chr_can_read(chr);
2718 f331110f bellard
    return s->max_size;
2719 f331110f bellard
}
2720 e5b0bc44 pbrook
2721 087f4ae0 ths
static void win_chr_readfile(CharDriverState *chr)
2722 f331110f bellard
{
2723 087f4ae0 ths
    WinCharState *s = chr->opaque;
2724 f331110f bellard
    int ret, err;
2725 f331110f bellard
    uint8_t buf[1024];
2726 f331110f bellard
    DWORD size;
2727 3b46e624 ths
2728 f331110f bellard
    ZeroMemory(&s->orecv, sizeof(s->orecv));
2729 f331110f bellard
    s->orecv.hEvent = s->hrecv;
2730 f331110f bellard
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2731 f331110f bellard
    if (!ret) {
2732 f331110f bellard
        err = GetLastError();
2733 f331110f bellard
        if (err == ERROR_IO_PENDING) {
2734 f331110f bellard
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2735 f331110f bellard
        }
2736 f331110f bellard
    }
2737 f331110f bellard
2738 f331110f bellard
    if (size > 0) {
2739 087f4ae0 ths
        qemu_chr_read(chr, buf, size);
2740 f331110f bellard
    }
2741 f331110f bellard
}
2742 f331110f bellard
2743 087f4ae0 ths
static void win_chr_read(CharDriverState *chr)
2744 f331110f bellard
{
2745 087f4ae0 ths
    WinCharState *s = chr->opaque;
2746 087f4ae0 ths
2747 f331110f bellard
    if (s->len > s->max_size)
2748 f331110f bellard
        s->len = s->max_size;
2749 f331110f bellard
    if (s->len == 0)
2750 f331110f bellard
        return;
2751 3b46e624 ths
2752 087f4ae0 ths
    win_chr_readfile(chr);
2753 f331110f bellard
}
2754 f331110f bellard
2755 f331110f bellard
static int win_chr_poll(void *opaque)
2756 f331110f bellard
{
2757 087f4ae0 ths
    CharDriverState *chr = opaque;
2758 087f4ae0 ths
    WinCharState *s = chr->opaque;
2759 f331110f bellard
    COMSTAT status;
2760 f331110f bellard
    DWORD comerr;
2761 3b46e624 ths
2762 f331110f bellard
    ClearCommError(s->hcom, &comerr, &status);
2763 f331110f bellard
    if (status.cbInQue > 0) {
2764 f331110f bellard
        s->len = status.cbInQue;
2765 087f4ae0 ths
        win_chr_read_poll(chr);
2766 087f4ae0 ths
        win_chr_read(chr);
2767 f331110f bellard
        return 1;
2768 f331110f bellard
    }
2769 f331110f bellard
    return 0;
2770 f331110f bellard
}
2771 f331110f bellard
2772 52f61fde ths
static CharDriverState *qemu_chr_open_win(const char *filename)
2773 f331110f bellard
{
2774 f331110f bellard
    CharDriverState *chr;
2775 f331110f bellard
    WinCharState *s;
2776 3b46e624 ths
2777 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2778 f331110f bellard
    if (!chr)
2779 f331110f bellard
        return NULL;
2780 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2781 f331110f bellard
    if (!s) {
2782 f331110f bellard
        free(chr);
2783 f331110f bellard
        return NULL;
2784 f331110f bellard
    }
2785 f331110f bellard
    chr->opaque = s;
2786 f331110f bellard
    chr->chr_write = win_chr_write;
2787 f331110f bellard
    chr->chr_close = win_chr_close;
2788 f331110f bellard
2789 087f4ae0 ths
    if (win_chr_init(chr, filename) < 0) {
2790 f331110f bellard
        free(s);
2791 f331110f bellard
        free(chr);
2792 f331110f bellard
        return NULL;
2793 f331110f bellard
    }
2794 86e94dea ths
    qemu_chr_reset(chr);
2795 f331110f bellard
    return chr;
2796 f331110f bellard
}
2797 f331110f bellard
2798 f331110f bellard
static int win_chr_pipe_poll(void *opaque)
2799 f331110f bellard
{
2800 087f4ae0 ths
    CharDriverState *chr = opaque;
2801 087f4ae0 ths
    WinCharState *s = chr->opaque;
2802 f331110f bellard
    DWORD size;
2803 f331110f bellard
2804 f331110f bellard
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2805 f331110f bellard
    if (size > 0) {
2806 f331110f bellard
        s->len = size;
2807 087f4ae0 ths
        win_chr_read_poll(chr);
2808 087f4ae0 ths
        win_chr_read(chr);
2809 f331110f bellard
        return 1;
2810 f331110f bellard
    }
2811 f331110f bellard
    return 0;
2812 f331110f bellard
}
2813 f331110f bellard
2814 087f4ae0 ths
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
2815 f331110f bellard
{
2816 087f4ae0 ths
    WinCharState *s = chr->opaque;
2817 f331110f bellard
    OVERLAPPED ov;
2818 f331110f bellard
    int ret;
2819 f331110f bellard
    DWORD size;
2820 f331110f bellard
    char openname[256];
2821 3b46e624 ths
2822 f331110f bellard
    s->fpipe = TRUE;
2823 f331110f bellard
2824 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2825 f331110f bellard
    if (!s->hsend) {
2826 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2827 f331110f bellard
        goto fail;
2828 f331110f bellard
    }
2829 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2830 f331110f bellard
    if (!s->hrecv) {
2831 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2832 f331110f bellard
        goto fail;
2833 f331110f bellard
    }
2834 3b46e624 ths
2835 f331110f bellard
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
2836 f331110f bellard
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2837 f331110f bellard
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2838 f331110f bellard
                              PIPE_WAIT,
2839 f331110f bellard
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2840 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2841 f331110f bellard
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
2842 f331110f bellard
        s->hcom = NULL;
2843 f331110f bellard
        goto fail;
2844 f331110f bellard
    }
2845 f331110f bellard
2846 f331110f bellard
    ZeroMemory(&ov, sizeof(ov));
2847 f331110f bellard
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2848 f331110f bellard
    ret = ConnectNamedPipe(s->hcom, &ov);
2849 f331110f bellard
    if (ret) {
2850 f331110f bellard
        fprintf(stderr, "Failed ConnectNamedPipe\n");
2851 f331110f bellard
        goto fail;
2852 f331110f bellard
    }
2853 f331110f bellard
2854 f331110f bellard
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2855 f331110f bellard
    if (!ret) {
2856 f331110f bellard
        fprintf(stderr, "Failed GetOverlappedResult\n");
2857 f331110f bellard
        if (ov.hEvent) {
2858 f331110f bellard
            CloseHandle(ov.hEvent);
2859 f331110f bellard
            ov.hEvent = NULL;
2860 f331110f bellard
        }
2861 f331110f bellard
        goto fail;
2862 f331110f bellard
    }
2863 f331110f bellard
2864 f331110f bellard
    if (ov.hEvent) {
2865 f331110f bellard
        CloseHandle(ov.hEvent);
2866 f331110f bellard
        ov.hEvent = NULL;
2867 f331110f bellard
    }
2868 087f4ae0 ths
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
2869 f331110f bellard
    return 0;
2870 f331110f bellard
2871 f331110f bellard
 fail:
2872 087f4ae0 ths
    win_chr_close(chr);
2873 f331110f bellard
    return -1;
2874 f331110f bellard
}
2875 f331110f bellard
2876 f331110f bellard
2877 52f61fde ths
static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
2878 f331110f bellard
{
2879 f331110f bellard
    CharDriverState *chr;
2880 f331110f bellard
    WinCharState *s;
2881 f331110f bellard
2882 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2883 f331110f bellard
    if (!chr)
2884 f331110f bellard
        return NULL;
2885 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2886 f331110f bellard
    if (!s) {
2887 f331110f bellard
        free(chr);
2888 f331110f bellard
        return NULL;
2889 f331110f bellard
    }
2890 f331110f bellard
    chr->opaque = s;
2891 f331110f bellard
    chr->chr_write = win_chr_write;
2892 f331110f bellard
    chr->chr_close = win_chr_close;
2893 3b46e624 ths
2894 087f4ae0 ths
    if (win_chr_pipe_init(chr, filename) < 0) {
2895 f331110f bellard
        free(s);
2896 f331110f bellard
        free(chr);
2897 f331110f bellard
        return NULL;
2898 f331110f bellard
    }
2899 86e94dea ths
    qemu_chr_reset(chr);
2900 f331110f bellard
    return chr;
2901 f331110f bellard
}
2902 f331110f bellard
2903 52f61fde ths
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
2904 f331110f bellard
{
2905 f331110f bellard
    CharDriverState *chr;
2906 f331110f bellard
    WinCharState *s;
2907 f331110f bellard
2908 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2909 f331110f bellard
    if (!chr)
2910 f331110f bellard
        return NULL;
2911 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2912 f331110f bellard
    if (!s) {
2913 f331110f bellard
        free(chr);
2914 f331110f bellard
        return NULL;
2915 f331110f bellard
    }
2916 f331110f bellard
    s->hcom = fd_out;
2917 f331110f bellard
    chr->opaque = s;
2918 f331110f bellard
    chr->chr_write = win_chr_write;
2919 86e94dea ths
    qemu_chr_reset(chr);
2920 f331110f bellard
    return chr;
2921 f331110f bellard
}
2922 72d46479 ths
2923 72d46479 ths
static CharDriverState *qemu_chr_open_win_con(const char *filename)
2924 72d46479 ths
{
2925 72d46479 ths
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
2926 72d46479 ths
}
2927 72d46479 ths
2928 52f61fde ths
static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
2929 f331110f bellard
{
2930 f331110f bellard
    HANDLE fd_out;
2931 3b46e624 ths
2932 f331110f bellard
    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
2933 f331110f bellard
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2934 f331110f bellard
    if (fd_out == INVALID_HANDLE_VALUE)
2935 f331110f bellard
        return NULL;
2936 f331110f bellard
2937 f331110f bellard
    return qemu_chr_open_win_file(fd_out);
2938 f331110f bellard
}
2939 aec62507 ths
#endif /* !_WIN32 */
2940 f331110f bellard
2941 0bab00f3 bellard
/***********************************************************/
2942 0bab00f3 bellard
/* UDP Net console */
2943 0bab00f3 bellard
2944 0bab00f3 bellard
typedef struct {
2945 0bab00f3 bellard
    int fd;
2946 0bab00f3 bellard
    struct sockaddr_in daddr;
2947 60fe76f3 ths
    uint8_t buf[1024];
2948 0bab00f3 bellard
    int bufcnt;
2949 0bab00f3 bellard
    int bufptr;
2950 0bab00f3 bellard
    int max_size;
2951 0bab00f3 bellard
} NetCharDriver;
2952 0bab00f3 bellard
2953 0bab00f3 bellard
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2954 0bab00f3 bellard
{
2955 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2956 0bab00f3 bellard
2957 0bab00f3 bellard
    return sendto(s->fd, buf, len, 0,
2958 0bab00f3 bellard
                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
2959 0bab00f3 bellard
}
2960 0bab00f3 bellard
2961 0bab00f3 bellard
static int udp_chr_read_poll(void *opaque)
2962 0bab00f3 bellard
{
2963 0bab00f3 bellard
    CharDriverState *chr = opaque;
2964 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2965 0bab00f3 bellard
2966 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2967 0bab00f3 bellard
2968 0bab00f3 bellard
    /* If there were any stray characters in the queue process them
2969 0bab00f3 bellard
     * first
2970 0bab00f3 bellard
     */
2971 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2972 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2973 0bab00f3 bellard
        s->bufptr++;
2974 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2975 0bab00f3 bellard
    }
2976 0bab00f3 bellard
    return s->max_size;
2977 0bab00f3 bellard
}
2978 0bab00f3 bellard
2979 0bab00f3 bellard
static void udp_chr_read(void *opaque)
2980 0bab00f3 bellard
{
2981 0bab00f3 bellard
    CharDriverState *chr = opaque;
2982 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2983 0bab00f3 bellard
2984 0bab00f3 bellard
    if (s->max_size == 0)
2985 0bab00f3 bellard
        return;
2986 0bab00f3 bellard
    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
2987 0bab00f3 bellard
    s->bufptr = s->bufcnt;
2988 0bab00f3 bellard
    if (s->bufcnt <= 0)
2989 0bab00f3 bellard
        return;
2990 0bab00f3 bellard
2991 0bab00f3 bellard
    s->bufptr = 0;
2992 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2993 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2994 0bab00f3 bellard
        s->bufptr++;
2995 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2996 0bab00f3 bellard
    }
2997 0bab00f3 bellard
}
2998 0bab00f3 bellard
2999 e5b0bc44 pbrook
static void udp_chr_update_read_handler(CharDriverState *chr)
3000 0bab00f3 bellard
{
3001 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
3002 0bab00f3 bellard
3003 0bab00f3 bellard
    if (s->fd >= 0) {
3004 0bab00f3 bellard
        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
3005 0bab00f3 bellard
                             udp_chr_read, NULL, chr);
3006 0bab00f3 bellard
    }
3007 0bab00f3 bellard
}
3008 0bab00f3 bellard
3009 0bab00f3 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str);
3010 52f61fde ths
#ifndef _WIN32
3011 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
3012 52f61fde ths
#endif
3013 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
3014 951f1351 bellard
                        struct sockaddr_in *saddr,
3015 951f1351 bellard
                        const char *str);
3016 0bab00f3 bellard
3017 52f61fde ths
static CharDriverState *qemu_chr_open_udp(const char *def)
3018 0bab00f3 bellard
{
3019 0bab00f3 bellard
    CharDriverState *chr = NULL;
3020 0bab00f3 bellard
    NetCharDriver *s = NULL;
3021 0bab00f3 bellard
    int fd = -1;
3022 951f1351 bellard
    struct sockaddr_in saddr;
3023 0bab00f3 bellard
3024 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
3025 0bab00f3 bellard
    if (!chr)
3026 0bab00f3 bellard
        goto return_err;
3027 0bab00f3 bellard
    s = qemu_mallocz(sizeof(NetCharDriver));
3028 0bab00f3 bellard
    if (!s)
3029 0bab00f3 bellard
        goto return_err;
3030 0bab00f3 bellard
3031 0bab00f3 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
3032 0bab00f3 bellard
    if (fd < 0) {
3033 0bab00f3 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
3034 0bab00f3 bellard
        goto return_err;
3035 0bab00f3 bellard
    }
3036 0bab00f3 bellard
3037 951f1351 bellard
    if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
3038 951f1351 bellard
        printf("Could not parse: %s\n", def);
3039 951f1351 bellard
        goto return_err;
3040 0bab00f3 bellard
    }
3041 0bab00f3 bellard
3042 951f1351 bellard
    if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
3043 0bab00f3 bellard
    {
3044 0bab00f3 bellard
        perror("bind");
3045 0bab00f3 bellard
        goto return_err;
3046 0bab00f3 bellard
    }
3047 0bab00f3 bellard
3048 0bab00f3 bellard
    s->fd = fd;
3049 0bab00f3 bellard
    s->bufcnt = 0;
3050 0bab00f3 bellard
    s->bufptr = 0;
3051 0bab00f3 bellard
    chr->opaque = s;
3052 0bab00f3 bellard
    chr->chr_write = udp_chr_write;
3053 e5b0bc44 pbrook
    chr->chr_update_read_handler = udp_chr_update_read_handler;
3054 0bab00f3 bellard
    return chr;
3055 0bab00f3 bellard
3056 0bab00f3 bellard
return_err:
3057 0bab00f3 bellard
    if (chr)
3058 0bab00f3 bellard
        free(chr);
3059 0bab00f3 bellard
    if (s)
3060 0bab00f3 bellard
        free(s);
3061 0bab00f3 bellard
    if (fd >= 0)
3062 0bab00f3 bellard
        closesocket(fd);
3063 0bab00f3 bellard
    return NULL;
3064 0bab00f3 bellard
}
3065 0bab00f3 bellard
3066 0bab00f3 bellard
/***********************************************************/
3067 0bab00f3 bellard
/* TCP Net console */
3068 0bab00f3 bellard
3069 0bab00f3 bellard
typedef struct {
3070 0bab00f3 bellard
    int fd, listen_fd;
3071 0bab00f3 bellard
    int connected;
3072 0bab00f3 bellard
    int max_size;
3073 951f1351 bellard
    int do_telnetopt;
3074 e5b0bc44 pbrook
    int do_nodelay;
3075 ffd843bc ths
    int is_unix;
3076 0bab00f3 bellard
} TCPCharDriver;
3077 0bab00f3 bellard
3078 0bab00f3 bellard
static void tcp_chr_accept(void *opaque);
3079 0bab00f3 bellard
3080 0bab00f3 bellard
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
3081 0bab00f3 bellard
{
3082 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3083 0bab00f3 bellard
    if (s->connected) {
3084 0bab00f3 bellard
        return send_all(s->fd, buf, len);
3085 0bab00f3 bellard
    } else {
3086 0bab00f3 bellard
        /* XXX: indicate an error ? */
3087 0bab00f3 bellard
        return len;
3088 0bab00f3 bellard
    }
3089 0bab00f3 bellard
}
3090 0bab00f3 bellard
3091 0bab00f3 bellard
static int tcp_chr_read_poll(void *opaque)
3092 0bab00f3 bellard
{
3093 0bab00f3 bellard
    CharDriverState *chr = opaque;
3094 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3095 0bab00f3 bellard
    if (!s->connected)
3096 0bab00f3 bellard
        return 0;
3097 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
3098 0bab00f3 bellard
    return s->max_size;
3099 0bab00f3 bellard
}
3100 0bab00f3 bellard
3101 951f1351 bellard
#define IAC 255
3102 951f1351 bellard
#define IAC_BREAK 243
3103 951f1351 bellard
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
3104 951f1351 bellard
                                      TCPCharDriver *s,
3105 60fe76f3 ths
                                      uint8_t *buf, int *size)
3106 951f1351 bellard
{
3107 951f1351 bellard
    /* Handle any telnet client's basic IAC options to satisfy char by
3108 951f1351 bellard
     * char mode with no echo.  All IAC options will be removed from
3109 951f1351 bellard
     * the buf and the do_telnetopt variable will be used to track the
3110 951f1351 bellard
     * state of the width of the IAC information.
3111 951f1351 bellard
     *
3112 951f1351 bellard
     * IAC commands come in sets of 3 bytes with the exception of the
3113 951f1351 bellard
     * "IAC BREAK" command and the double IAC.
3114 951f1351 bellard
     */
3115 951f1351 bellard
3116 951f1351 bellard
    int i;
3117 951f1351 bellard
    int j = 0;
3118 951f1351 bellard
3119 951f1351 bellard
    for (i = 0; i < *size; i++) {
3120 951f1351 bellard
        if (s->do_telnetopt > 1) {
3121 951f1351 bellard
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3122 951f1351 bellard
                /* Double IAC means send an IAC */
3123 951f1351 bellard
                if (j != i)
3124 951f1351 bellard
                    buf[j] = buf[i];
3125 951f1351 bellard
                j++;
3126 951f1351 bellard
                s->do_telnetopt = 1;
3127 951f1351 bellard
            } else {
3128 951f1351 bellard
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3129 951f1351 bellard
                    /* Handle IAC break commands by sending a serial break */
3130 e5b0bc44 pbrook
                    qemu_chr_event(chr, CHR_EVENT_BREAK);
3131 951f1351 bellard
                    s->do_telnetopt++;
3132 951f1351 bellard
                }
3133 951f1351 bellard
                s->do_telnetopt++;
3134 951f1351 bellard
            }
3135 951f1351 bellard
            if (s->do_telnetopt >= 4) {
3136 951f1351 bellard
                s->do_telnetopt = 1;
3137 951f1351 bellard
            }
3138 951f1351 bellard
        } else {
3139 951f1351 bellard
            if ((unsigned char)buf[i] == IAC) {
3140 951f1351 bellard
                s->do_telnetopt = 2;
3141 951f1351 bellard
            } else {
3142 951f1351 bellard
                if (j != i)
3143 951f1351 bellard
                    buf[j] = buf[i];
3144 951f1351 bellard
                j++;
3145 951f1351 bellard
            }
3146 951f1351 bellard
        }
3147 951f1351 bellard
    }
3148 951f1351 bellard
    *size = j;
3149 951f1351 bellard
}
3150 951f1351 bellard
3151 0bab00f3 bellard
static void tcp_chr_read(void *opaque)
3152 0bab00f3 bellard
{
3153 0bab00f3 bellard
    CharDriverState *chr = opaque;
3154 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3155 0bab00f3 bellard
    uint8_t buf[1024];
3156 0bab00f3 bellard
    int len, size;
3157 0bab00f3 bellard
3158 0bab00f3 bellard
    if (!s->connected || s->max_size <= 0)
3159 0bab00f3 bellard
        return;
3160 0bab00f3 bellard
    len = sizeof(buf);
3161 0bab00f3 bellard
    if (len > s->max_size)
3162 0bab00f3 bellard
        len = s->max_size;
3163 0bab00f3 bellard
    size = recv(s->fd, buf, len, 0);
3164 0bab00f3 bellard
    if (size == 0) {
3165 0bab00f3 bellard
        /* connection closed */
3166 0bab00f3 bellard
        s->connected = 0;
3167 0bab00f3 bellard
        if (s->listen_fd >= 0) {
3168 0bab00f3 bellard
            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3169 0bab00f3 bellard
        }
3170 0bab00f3 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3171 0bab00f3 bellard
        closesocket(s->fd);
3172 0bab00f3 bellard
        s->fd = -1;
3173 0bab00f3 bellard
    } else if (size > 0) {
3174 951f1351 bellard
        if (s->do_telnetopt)
3175 951f1351 bellard
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3176 951f1351 bellard
        if (size > 0)
3177 e5b0bc44 pbrook
            qemu_chr_read(chr, buf, size);
3178 0bab00f3 bellard
    }
3179 0bab00f3 bellard
}
3180 0bab00f3 bellard
3181 0bab00f3 bellard
static void tcp_chr_connect(void *opaque)
3182 0bab00f3 bellard
{
3183 0bab00f3 bellard
    CharDriverState *chr = opaque;
3184 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3185 0bab00f3 bellard
3186 0bab00f3 bellard
    s->connected = 1;
3187 0bab00f3 bellard
    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3188 0bab00f3 bellard
                         tcp_chr_read, NULL, chr);
3189 86e94dea ths
    qemu_chr_reset(chr);
3190 0bab00f3 bellard
}
3191 0bab00f3 bellard
3192 951f1351 bellard
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3193 951f1351 bellard
static void tcp_chr_telnet_init(int fd)
3194 951f1351 bellard
{
3195 951f1351 bellard
    char buf[3];
3196 951f1351 bellard
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3197 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
3198 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3199 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
3200 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3201 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
3202 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3203 951f1351 bellard
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
3204 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3205 951f1351 bellard
}
3206 951f1351 bellard
3207 f7499989 pbrook
static void socket_set_nodelay(int fd)
3208 f7499989 pbrook
{
3209 f7499989 pbrook
    int val = 1;
3210 f7499989 pbrook
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3211 f7499989 pbrook
}
3212 f7499989 pbrook
3213 0bab00f3 bellard
static void tcp_chr_accept(void *opaque)
3214 0bab00f3 bellard
{
3215 0bab00f3 bellard
    CharDriverState *chr = opaque;
3216 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3217 0bab00f3 bellard
    struct sockaddr_in saddr;
3218 ffd843bc ths
#ifndef _WIN32
3219 ffd843bc ths
    struct sockaddr_un uaddr;
3220 ffd843bc ths
#endif
3221 ffd843bc ths
    struct sockaddr *addr;
3222 0bab00f3 bellard
    socklen_t len;
3223 0bab00f3 bellard
    int fd;
3224 0bab00f3 bellard
3225 0bab00f3 bellard
    for(;;) {
3226 ffd843bc ths
#ifndef _WIN32
3227 ffd843bc ths
        if (s->is_unix) {
3228 ffd843bc ths
            len = sizeof(uaddr);
3229 ffd843bc ths
            addr = (struct sockaddr *)&uaddr;
3230 ffd843bc ths
        } else
3231 ffd843bc ths
#endif
3232 ffd843bc ths
        {
3233 ffd843bc ths
            len = sizeof(saddr);
3234 ffd843bc ths
            addr = (struct sockaddr *)&saddr;
3235 ffd843bc ths
        }
3236 ffd843bc ths
        fd = accept(s->listen_fd, addr, &len);
3237 0bab00f3 bellard
        if (fd < 0 && errno != EINTR) {
3238 0bab00f3 bellard
            return;
3239 0bab00f3 bellard
        } else if (fd >= 0) {
3240 951f1351 bellard
            if (s->do_telnetopt)
3241 951f1351 bellard
                tcp_chr_telnet_init(fd);
3242 0bab00f3 bellard
            break;
3243 0bab00f3 bellard
        }
3244 0bab00f3 bellard
    }
3245 0bab00f3 bellard
    socket_set_nonblock(fd);
3246 f7499989 pbrook
    if (s->do_nodelay)
3247 f7499989 pbrook
        socket_set_nodelay(fd);
3248 0bab00f3 bellard
    s->fd = fd;
3249 0bab00f3 bellard
    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3250 0bab00f3 bellard
    tcp_chr_connect(chr);
3251 0bab00f3 bellard
}
3252 0bab00f3 bellard
3253 0bab00f3 bellard
static void tcp_chr_close(CharDriverState *chr)
3254 0bab00f3 bellard
{
3255 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3256 0bab00f3 bellard
    if (s->fd >= 0)
3257 0bab00f3 bellard
        closesocket(s->fd);
3258 0bab00f3 bellard
    if (s->listen_fd >= 0)
3259 0bab00f3 bellard
        closesocket(s->listen_fd);
3260 0bab00f3 bellard
    qemu_free(s);
3261 0bab00f3 bellard
}
3262 0bab00f3 bellard
3263 5fafdf24 ths
static CharDriverState *qemu_chr_open_tcp(const char *host_str,
3264 ffd843bc ths
                                          int is_telnet,
3265 ffd843bc ths
                                          int is_unix)
3266 0bab00f3 bellard
{
3267 0bab00f3 bellard
    CharDriverState *chr = NULL;
3268 0bab00f3 bellard
    TCPCharDriver *s = NULL;
3269 0bab00f3 bellard
    int fd = -1, ret, err, val;
3270 951f1351 bellard
    int is_listen = 0;
3271 951f1351 bellard
    int is_waitconnect = 1;
3272 f7499989 pbrook
    int do_nodelay = 0;
3273 951f1351 bellard
    const char *ptr;
3274 0bab00f3 bellard
    struct sockaddr_in saddr;
3275 ffd843bc ths
#ifndef _WIN32
3276 ffd843bc ths
    struct sockaddr_un uaddr;
3277 ffd843bc ths
#endif
3278 ffd843bc ths
    struct sockaddr *addr;
3279 ffd843bc ths
    socklen_t addrlen;
3280 0bab00f3 bellard
3281 ffd843bc ths
#ifndef _WIN32
3282 ffd843bc ths
    if (is_unix) {
3283 ffd843bc ths
        addr = (struct sockaddr *)&uaddr;
3284 ffd843bc ths
        addrlen = sizeof(uaddr);
3285 ffd843bc ths
        if (parse_unix_path(&uaddr, host_str) < 0)
3286 ffd843bc ths
            goto fail;
3287 ffd843bc ths
    } else
3288 ffd843bc ths
#endif
3289 ffd843bc ths
    {
3290 ffd843bc ths
        addr = (struct sockaddr *)&saddr;
3291 ffd843bc ths
        addrlen = sizeof(saddr);
3292 ffd843bc ths
        if (parse_host_port(&saddr, host_str) < 0)
3293 ffd843bc ths
            goto fail;
3294 ffd843bc ths
    }
3295 0bab00f3 bellard
3296 951f1351 bellard
    ptr = host_str;
3297 951f1351 bellard
    while((ptr = strchr(ptr,','))) {
3298 951f1351 bellard
        ptr++;
3299 951f1351 bellard
        if (!strncmp(ptr,"server",6)) {
3300 951f1351 bellard
            is_listen = 1;
3301 951f1351 bellard
        } else if (!strncmp(ptr,"nowait",6)) {
3302 951f1351 bellard
            is_waitconnect = 0;
3303 f7499989 pbrook
        } else if (!strncmp(ptr,"nodelay",6)) {
3304 f7499989 pbrook
            do_nodelay = 1;
3305 951f1351 bellard
        } else {
3306 951f1351 bellard
            printf("Unknown option: %s\n", ptr);
3307 951f1351 bellard
            goto fail;
3308 951f1351 bellard
        }
3309 951f1351 bellard
    }
3310 951f1351 bellard
    if (!is_listen)
3311 951f1351 bellard
        is_waitconnect = 0;
3312 951f1351 bellard
3313 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
3314 0bab00f3 bellard
    if (!chr)
3315 0bab00f3 bellard
        goto fail;
3316 0bab00f3 bellard
    s = qemu_mallocz(sizeof(TCPCharDriver));
3317 0bab00f3 bellard
    if (!s)
3318 0bab00f3 bellard
        goto fail;
3319 ffd843bc ths
3320 ffd843bc ths
#ifndef _WIN32
3321 ffd843bc ths
    if (is_unix)
3322 ffd843bc ths
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
3323 ffd843bc ths
    else
3324 ffd843bc ths
#endif
3325 ffd843bc ths
        fd = socket(PF_INET, SOCK_STREAM, 0);
3326 5fafdf24 ths
3327 5fafdf24 ths
    if (fd < 0)
3328 0bab00f3 bellard
        goto fail;
3329 951f1351 bellard
3330 951f1351 bellard
    if (!is_waitconnect)
3331 951f1351 bellard
        socket_set_nonblock(fd);
3332 0bab00f3 bellard
3333 0bab00f3 bellard
    s->connected = 0;
3334 0bab00f3 bellard
    s->fd = -1;
3335 0bab00f3 bellard
    s->listen_fd = -1;
3336 ffd843bc ths
    s->is_unix = is_unix;
3337 f7499989 pbrook
    s->do_nodelay = do_nodelay && !is_unix;
3338 ffd843bc ths
3339 ffd843bc ths
    chr->opaque = s;
3340 ffd843bc ths
    chr->chr_write = tcp_chr_write;
3341 ffd843bc ths
    chr->chr_close = tcp_chr_close;
3342 ffd843bc ths
3343 0bab00f3 bellard
    if (is_listen) {
3344 0bab00f3 bellard
        /* allow fast reuse */
3345 ffd843bc ths
#ifndef _WIN32
3346 ffd843bc ths
        if (is_unix) {
3347 ffd843bc ths
            char path[109];
3348 ffd843bc ths
            strncpy(path, uaddr.sun_path, 108);
3349 ffd843bc ths
            path[108] = 0;
3350 ffd843bc ths
            unlink(path);
3351 ffd843bc ths
        } else
3352 ffd843bc ths
#endif
3353 ffd843bc ths
        {
3354 ffd843bc ths
            val = 1;
3355 ffd843bc ths
            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3356 ffd843bc ths
        }
3357 3b46e624 ths
3358 ffd843bc ths
        ret = bind(fd, addr, addrlen);
3359 ffd843bc ths
        if (ret < 0)
3360 0bab00f3 bellard
            goto fail;
3361 ffd843bc ths
3362 0bab00f3 bellard
        ret = listen(fd, 0);
3363 0bab00f3 bellard
        if (ret < 0)
3364 0bab00f3 bellard
            goto fail;
3365 ffd843bc ths
3366 0bab00f3 bellard
        s->listen_fd = fd;
3367 0bab00f3 bellard
        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3368 951f1351 bellard
        if (is_telnet)
3369 951f1351 bellard
            s->do_telnetopt = 1;
3370 0bab00f3 bellard
    } else {
3371 0bab00f3 bellard
        for(;;) {
3372 ffd843bc ths
            ret = connect(fd, addr, addrlen);
3373 0bab00f3 bellard
            if (ret < 0) {
3374 0bab00f3 bellard
                err = socket_error();
3375 0bab00f3 bellard
                if (err == EINTR || err == EWOULDBLOCK) {
3376 0bab00f3 bellard
                } else if (err == EINPROGRESS) {
3377 0bab00f3 bellard
                    break;
3378 f5b12268 ths
#ifdef _WIN32
3379 f5b12268 ths
                } else if (err == WSAEALREADY) {
3380 f5b12268 ths
                    break;
3381 f5b12268 ths
#endif
3382 0bab00f3 bellard
                } else {
3383 0bab00f3 bellard
                    goto fail;
3384 0bab00f3 bellard
                }
3385 0bab00f3 bellard
            } else {
3386 0bab00f3 bellard
                s->connected = 1;
3387 0bab00f3 bellard
                break;
3388 0bab00f3 bellard
            }
3389 0bab00f3 bellard
        }
3390 0bab00f3 bellard
        s->fd = fd;
3391 f7499989 pbrook
        socket_set_nodelay(fd);
3392 0bab00f3 bellard
        if (s->connected)
3393 0bab00f3 bellard
            tcp_chr_connect(chr);
3394 0bab00f3 bellard
        else
3395 0bab00f3 bellard
            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3396 0bab00f3 bellard
    }
3397 3b46e624 ths
3398 951f1351 bellard
    if (is_listen && is_waitconnect) {
3399 951f1351 bellard
        printf("QEMU waiting for connection on: %s\n", host_str);
3400 951f1351 bellard
        tcp_chr_accept(chr);
3401 951f1351 bellard
        socket_set_nonblock(s->listen_fd);
3402 951f1351 bellard
    }
3403 951f1351 bellard
3404 0bab00f3 bellard
    return chr;
3405 0bab00f3 bellard
 fail:
3406 0bab00f3 bellard
    if (fd >= 0)
3407 0bab00f3 bellard
        closesocket(fd);
3408 0bab00f3 bellard
    qemu_free(s);
3409 0bab00f3 bellard
    qemu_free(chr);
3410 0bab00f3 bellard
    return NULL;
3411 0bab00f3 bellard
}
3412 0bab00f3 bellard
3413 82c643ff bellard
CharDriverState *qemu_chr_open(const char *filename)
3414 82c643ff bellard
{
3415 f8d179e3 bellard
    const char *p;
3416 fd1dff4b bellard
3417 82c643ff bellard
    if (!strcmp(filename, "vc")) {
3418 af3a9031 ths
        return text_console_init(&display_state, 0);
3419 af3a9031 ths
    } else if (strstart(filename, "vc:", &p)) {
3420 af3a9031 ths
        return text_console_init(&display_state, p);
3421 82c643ff bellard
    } else if (!strcmp(filename, "null")) {
3422 82c643ff bellard
        return qemu_chr_open_null();
3423 5fafdf24 ths
    } else
3424 0bab00f3 bellard
    if (strstart(filename, "tcp:", &p)) {
3425 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 0);
3426 0bab00f3 bellard
    } else
3427 951f1351 bellard
    if (strstart(filename, "telnet:", &p)) {
3428 ffd843bc ths
        return qemu_chr_open_tcp(p, 1, 0);
3429 0bab00f3 bellard
    } else
3430 0bab00f3 bellard
    if (strstart(filename, "udp:", &p)) {
3431 0bab00f3 bellard
        return qemu_chr_open_udp(p);
3432 0bab00f3 bellard
    } else
3433 20d8a3ed ths
    if (strstart(filename, "mon:", &p)) {
3434 20d8a3ed ths
        CharDriverState *drv = qemu_chr_open(p);
3435 20d8a3ed ths
        if (drv) {
3436 20d8a3ed ths
            drv = qemu_chr_open_mux(drv);
3437 20d8a3ed ths
            monitor_init(drv, !nographic);
3438 20d8a3ed ths
            return drv;
3439 20d8a3ed ths
        }
3440 20d8a3ed ths
        printf("Unable to open driver: %s\n", p);
3441 20d8a3ed ths
        return 0;
3442 20d8a3ed ths
    } else
3443 7664728b bellard
#ifndef _WIN32
3444 ffd843bc ths
    if (strstart(filename, "unix:", &p)) {
3445 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 1);
3446 ffd843bc ths
    } else if (strstart(filename, "file:", &p)) {
3447 f8d179e3 bellard
        return qemu_chr_open_file_out(p);
3448 f8d179e3 bellard
    } else if (strstart(filename, "pipe:", &p)) {
3449 f8d179e3 bellard
        return qemu_chr_open_pipe(p);
3450 7664728b bellard
    } else if (!strcmp(filename, "pty")) {
3451 82c643ff bellard
        return qemu_chr_open_pty();
3452 82c643ff bellard
    } else if (!strcmp(filename, "stdio")) {
3453 82c643ff bellard
        return qemu_chr_open_stdio();
3454 5fafdf24 ths
    } else
3455 f8d179e3 bellard
#if defined(__linux__)
3456 e57a8c0e bellard
    if (strstart(filename, "/dev/parport", NULL)) {
3457 e57a8c0e bellard
        return qemu_chr_open_pp(filename);
3458 5fafdf24 ths
    } else
3459 aec62507 ths
#endif
3460 3fda388a ths
#if defined(__linux__) || defined(__sun__)
3461 f8d179e3 bellard
    if (strstart(filename, "/dev/", NULL)) {
3462 f8d179e3 bellard
        return qemu_chr_open_tty(filename);
3463 3fda388a ths
    } else
3464 3fda388a ths
#endif
3465 aec62507 ths
#else /* !_WIN32 */
3466 f331110f bellard
    if (strstart(filename, "COM", NULL)) {
3467 f331110f bellard
        return qemu_chr_open_win(filename);
3468 f331110f bellard
    } else
3469 f331110f bellard
    if (strstart(filename, "pipe:", &p)) {
3470 f331110f bellard
        return qemu_chr_open_win_pipe(p);
3471 f331110f bellard
    } else
3472 72d46479 ths
    if (strstart(filename, "con:", NULL)) {
3473 72d46479 ths
        return qemu_chr_open_win_con(filename);
3474 72d46479 ths
    } else
3475 f331110f bellard
    if (strstart(filename, "file:", &p)) {
3476 f331110f bellard
        return qemu_chr_open_win_file_out(p);
3477 f331110f bellard
    }
3478 f331110f bellard
#endif
3479 82c643ff bellard
    {
3480 82c643ff bellard
        return NULL;
3481 82c643ff bellard
    }
3482 82c643ff bellard
}
3483 82c643ff bellard
3484 f331110f bellard
void qemu_chr_close(CharDriverState *chr)
3485 f331110f bellard
{
3486 f331110f bellard
    if (chr->chr_close)
3487 f331110f bellard
        chr->chr_close(chr);
3488 a11d070e balrog
    qemu_free(chr);
3489 f331110f bellard
}
3490 f331110f bellard
3491 80cabfad bellard
/***********************************************************/
3492 7c9d8e07 bellard
/* network device redirectors */
3493 330d0414 bellard
3494 3f4afa14 j_mayer
__attribute__ (( unused ))
3495 9596ebb7 pbrook
static void hex_dump(FILE *f, const uint8_t *buf, int size)
3496 c20709aa bellard
{
3497 c20709aa bellard
    int len, i, j, c;
3498 c20709aa bellard
3499 c20709aa bellard
    for(i=0;i<size;i+=16) {
3500 c20709aa bellard
        len = size - i;
3501 c20709aa bellard
        if (len > 16)
3502 c20709aa bellard
            len = 16;
3503 c20709aa bellard
        fprintf(f, "%08x ", i);
3504 c20709aa bellard
        for(j=0;j<16;j++) {
3505 c20709aa bellard
            if (j < len)
3506 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
3507 c20709aa bellard
            else
3508 c20709aa bellard
                fprintf(f, "   ");
3509 c20709aa bellard
        }
3510 c20709aa bellard
        fprintf(f, " ");
3511 c20709aa bellard
        for(j=0;j<len;j++) {
3512 c20709aa bellard
            c = buf[i+j];
3513 c20709aa bellard
            if (c < ' ' || c > '~')
3514 c20709aa bellard
                c = '.';
3515 c20709aa bellard
            fprintf(f, "%c", c);
3516 c20709aa bellard
        }
3517 c20709aa bellard
        fprintf(f, "\n");
3518 c20709aa bellard
    }
3519 c20709aa bellard
}
3520 c20709aa bellard
3521 7c9d8e07 bellard
static int parse_macaddr(uint8_t *macaddr, const char *p)
3522 c20709aa bellard
{
3523 7c9d8e07 bellard
    int i;
3524 76ea08f9 balrog
    char *last_char;
3525 76ea08f9 balrog
    long int offset;
3526 76ea08f9 balrog
3527 76ea08f9 balrog
    errno = 0;
3528 76ea08f9 balrog
    offset = strtol(p, &last_char, 0);    
3529 76ea08f9 balrog
    if (0 == errno && '\0' == *last_char &&
3530 76ea08f9 balrog
            offset >= 0 && offset <= 0xFFFFFF) {
3531 76ea08f9 balrog
        macaddr[3] = (offset & 0xFF0000) >> 16;
3532 76ea08f9 balrog
        macaddr[4] = (offset & 0xFF00) >> 8;
3533 76ea08f9 balrog
        macaddr[5] = offset & 0xFF;
3534 76ea08f9 balrog
        return 0;
3535 76ea08f9 balrog
    } else {
3536 76ea08f9 balrog
        for(i = 0; i < 6; i++) {
3537 76ea08f9 balrog
            macaddr[i] = strtol(p, (char **)&p, 16);
3538 76ea08f9 balrog
            if (i == 5) {
3539 76ea08f9 balrog
                if (*p != '\0')
3540 76ea08f9 balrog
                    return -1;
3541 76ea08f9 balrog
            } else {
3542 76ea08f9 balrog
                if (*p != ':' && *p != '-')
3543 76ea08f9 balrog
                    return -1;
3544 76ea08f9 balrog
                p++;
3545 76ea08f9 balrog
            }
3546 7c9d8e07 bellard
        }
3547 76ea08f9 balrog
        return 0;    
3548 7c9d8e07 bellard
    }
3549 76ea08f9 balrog
3550 76ea08f9 balrog
    return -1;
3551 c20709aa bellard
}
3552 67b915a5 bellard
3553 7c9d8e07 bellard
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3554 67b915a5 bellard
{
3555 7c9d8e07 bellard
    const char *p, *p1;
3556 7c9d8e07 bellard
    int len;
3557 7c9d8e07 bellard
    p = *pp;
3558 7c9d8e07 bellard
    p1 = strchr(p, sep);
3559 7c9d8e07 bellard
    if (!p1)
3560 7c9d8e07 bellard
        return -1;
3561 7c9d8e07 bellard
    len = p1 - p;
3562 7c9d8e07 bellard
    p1++;
3563 7c9d8e07 bellard
    if (buf_size > 0) {
3564 7c9d8e07 bellard
        if (len > buf_size - 1)
3565 7c9d8e07 bellard
            len = buf_size - 1;
3566 7c9d8e07 bellard
        memcpy(buf, p, len);
3567 7c9d8e07 bellard
        buf[len] = '\0';
3568 7c9d8e07 bellard
    }
3569 7c9d8e07 bellard
    *pp = p1;
3570 7c9d8e07 bellard
    return 0;
3571 c20709aa bellard
}
3572 c20709aa bellard
3573 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
3574 951f1351 bellard
                        struct sockaddr_in *saddr,
3575 951f1351 bellard
                        const char *input_str)
3576 951f1351 bellard
{
3577 951f1351 bellard
    char *str = strdup(input_str);
3578 951f1351 bellard
    char *host_str = str;
3579 951f1351 bellard
    char *src_str;
3580 951f1351 bellard
    char *ptr;
3581 951f1351 bellard
3582 951f1351 bellard
    /*
3583 951f1351 bellard
     * Chop off any extra arguments at the end of the string which
3584 951f1351 bellard
     * would start with a comma, then fill in the src port information
3585 951f1351 bellard
     * if it was provided else use the "any address" and "any port".
3586 951f1351 bellard
     */
3587 951f1351 bellard
    if ((ptr = strchr(str,',')))
3588 951f1351 bellard
        *ptr = '\0';
3589 951f1351 bellard
3590 951f1351 bellard
    if ((src_str = strchr(input_str,'@'))) {
3591 951f1351 bellard
        *src_str = '\0';
3592 951f1351 bellard
        src_str++;
3593 951f1351 bellard
    }
3594 951f1351 bellard
3595 951f1351 bellard
    if (parse_host_port(haddr, host_str) < 0)
3596 951f1351 bellard
        goto fail;
3597 951f1351 bellard
3598 951f1351 bellard
    if (!src_str || *src_str == '\0')
3599 951f1351 bellard
        src_str = ":0";
3600 951f1351 bellard
3601 951f1351 bellard
    if (parse_host_port(saddr, src_str) < 0)
3602 951f1351 bellard
        goto fail;
3603 951f1351 bellard
3604 951f1351 bellard
    free(str);
3605 951f1351 bellard
    return(0);
3606 951f1351 bellard
3607 951f1351 bellard
fail:
3608 951f1351 bellard
    free(str);
3609 951f1351 bellard
    return -1;
3610 951f1351 bellard
}
3611 951f1351 bellard
3612 7c9d8e07 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str)
3613 7c9d8e07 bellard
{
3614 7c9d8e07 bellard
    char buf[512];
3615 7c9d8e07 bellard
    struct hostent *he;
3616 7c9d8e07 bellard
    const char *p, *r;
3617 7c9d8e07 bellard
    int port;
3618 7c9d8e07 bellard
3619 7c9d8e07 bellard
    p = str;
3620 7c9d8e07 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3621 7c9d8e07 bellard
        return -1;
3622 7c9d8e07 bellard
    saddr->sin_family = AF_INET;
3623 7c9d8e07 bellard
    if (buf[0] == '\0') {
3624 7c9d8e07 bellard
        saddr->sin_addr.s_addr = 0;
3625 7c9d8e07 bellard
    } else {
3626 7c9d8e07 bellard
        if (isdigit(buf[0])) {
3627 7c9d8e07 bellard
            if (!inet_aton(buf, &saddr->sin_addr))
3628 7c9d8e07 bellard
                return -1;
3629 7c9d8e07 bellard
        } else {
3630 7c9d8e07 bellard
            if ((he = gethostbyname(buf)) == NULL)
3631 7c9d8e07 bellard
                return - 1;
3632 7c9d8e07 bellard
            saddr->sin_addr = *(struct in_addr *)he->h_addr;
3633 7c9d8e07 bellard
        }
3634 7c9d8e07 bellard
    }
3635 7c9d8e07 bellard
    port = strtol(p, (char **)&r, 0);
3636 7c9d8e07 bellard
    if (r == p)
3637 7c9d8e07 bellard
        return -1;
3638 7c9d8e07 bellard
    saddr->sin_port = htons(port);
3639 7c9d8e07 bellard
    return 0;
3640 7c9d8e07 bellard
}
3641 c20709aa bellard
3642 52f61fde ths
#ifndef _WIN32
3643 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
3644 ffd843bc ths
{
3645 ffd843bc ths
    const char *p;
3646 ffd843bc ths
    int len;
3647 ffd843bc ths
3648 ffd843bc ths
    len = MIN(108, strlen(str));
3649 ffd843bc ths
    p = strchr(str, ',');
3650 ffd843bc ths
    if (p)
3651 ffd843bc ths
        len = MIN(len, p - str);
3652 ffd843bc ths
3653 ffd843bc ths
    memset(uaddr, 0, sizeof(*uaddr));
3654 ffd843bc ths
3655 ffd843bc ths
    uaddr->sun_family = AF_UNIX;
3656 ffd843bc ths
    memcpy(uaddr->sun_path, str, len);
3657 ffd843bc ths
3658 ffd843bc ths
    return 0;
3659 ffd843bc ths
}
3660 52f61fde ths
#endif
3661 ffd843bc ths
3662 7c9d8e07 bellard
/* find or alloc a new VLAN */
3663 7c9d8e07 bellard
VLANState *qemu_find_vlan(int id)
3664 c20709aa bellard
{
3665 7c9d8e07 bellard
    VLANState **pvlan, *vlan;
3666 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3667 7c9d8e07 bellard
        if (vlan->id == id)
3668 7c9d8e07 bellard
            return vlan;
3669 7c9d8e07 bellard
    }
3670 7c9d8e07 bellard
    vlan = qemu_mallocz(sizeof(VLANState));
3671 7c9d8e07 bellard
    if (!vlan)
3672 7c9d8e07 bellard
        return NULL;
3673 7c9d8e07 bellard
    vlan->id = id;
3674 7c9d8e07 bellard
    vlan->next = NULL;
3675 7c9d8e07 bellard
    pvlan = &first_vlan;
3676 7c9d8e07 bellard
    while (*pvlan != NULL)
3677 7c9d8e07 bellard
        pvlan = &(*pvlan)->next;
3678 7c9d8e07 bellard
    *pvlan = vlan;
3679 7c9d8e07 bellard
    return vlan;
3680 c20709aa bellard
}
3681 c20709aa bellard
3682 7c9d8e07 bellard
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
3683 d861b05e pbrook
                                      IOReadHandler *fd_read,
3684 d861b05e pbrook
                                      IOCanRWHandler *fd_can_read,
3685 d861b05e pbrook
                                      void *opaque)
3686 c20709aa bellard
{
3687 7c9d8e07 bellard
    VLANClientState *vc, **pvc;
3688 7c9d8e07 bellard
    vc = qemu_mallocz(sizeof(VLANClientState));
3689 7c9d8e07 bellard
    if (!vc)
3690 7c9d8e07 bellard
        return NULL;
3691 7c9d8e07 bellard
    vc->fd_read = fd_read;
3692 d861b05e pbrook
    vc->fd_can_read = fd_can_read;
3693 7c9d8e07 bellard
    vc->opaque = opaque;
3694 7c9d8e07 bellard
    vc->vlan = vlan;
3695 7c9d8e07 bellard
3696 7c9d8e07 bellard
    vc->next = NULL;
3697 7c9d8e07 bellard
    pvc = &vlan->first_client;
3698 7c9d8e07 bellard
    while (*pvc != NULL)
3699 7c9d8e07 bellard
        pvc = &(*pvc)->next;
3700 7c9d8e07 bellard
    *pvc = vc;
3701 7c9d8e07 bellard
    return vc;
3702 c20709aa bellard
}
3703 c20709aa bellard
3704 d861b05e pbrook
int qemu_can_send_packet(VLANClientState *vc1)
3705 d861b05e pbrook
{
3706 d861b05e pbrook
    VLANState *vlan = vc1->vlan;
3707 d861b05e pbrook
    VLANClientState *vc;
3708 d861b05e pbrook
3709 d861b05e pbrook
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3710 d861b05e pbrook
        if (vc != vc1) {
3711 fbd1711d balrog
            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
3712 fbd1711d balrog
                return 1;
3713 d861b05e pbrook
        }
3714 d861b05e pbrook
    }
3715 fbd1711d balrog
    return 0;
3716 d861b05e pbrook
}
3717 d861b05e pbrook
3718 7c9d8e07 bellard
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
3719 c20709aa bellard
{
3720 7c9d8e07 bellard
    VLANState *vlan = vc1->vlan;
3721 7c9d8e07 bellard
    VLANClientState *vc;
3722 7c9d8e07 bellard
3723 7c9d8e07 bellard
#if 0
3724 7c9d8e07 bellard
    printf("vlan %d send:\n", vlan->id);
3725 7c9d8e07 bellard
    hex_dump(stdout, buf, size);
3726 7c9d8e07 bellard
#endif
3727 7c9d8e07 bellard
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3728 7c9d8e07 bellard
        if (vc != vc1) {
3729 7c9d8e07 bellard
            vc->fd_read(vc->opaque, buf, size);
3730 7c9d8e07 bellard
        }
3731 7c9d8e07 bellard
    }
3732 67b915a5 bellard
}
3733 67b915a5 bellard
3734 c20709aa bellard
#if defined(CONFIG_SLIRP)
3735 c20709aa bellard
3736 c20709aa bellard
/* slirp network adapter */
3737 c20709aa bellard
3738 c20709aa bellard
static int slirp_inited;
3739 7c9d8e07 bellard
static VLANClientState *slirp_vc;
3740 c20709aa bellard
3741 c20709aa bellard
int slirp_can_output(void)
3742 c20709aa bellard
{
3743 3b7f5d47 pbrook
    return !slirp_vc || qemu_can_send_packet(slirp_vc);
3744 c20709aa bellard
}
3745 c20709aa bellard
3746 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
3747 67b915a5 bellard
{
3748 c20709aa bellard
#if 0
3749 7c9d8e07 bellard
    printf("slirp output:\n");
3750 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
3751 c20709aa bellard
#endif
3752 3b7f5d47 pbrook
    if (!slirp_vc)
3753 3b7f5d47 pbrook
        return;
3754 7c9d8e07 bellard
    qemu_send_packet(slirp_vc, pkt, pkt_len);
3755 67b915a5 bellard
}
3756 67b915a5 bellard
3757 7c9d8e07 bellard
static void slirp_receive(void *opaque, const uint8_t *buf, int size)
3758 c20709aa bellard
{
3759 c20709aa bellard
#if 0
3760 7c9d8e07 bellard
    printf("slirp input:\n");
3761 c20709aa bellard
    hex_dump(stdout, buf, size);
3762 c20709aa bellard
#endif
3763 c20709aa bellard
    slirp_input(buf, size);
3764 c20709aa bellard
}
3765 c20709aa bellard
3766 7c9d8e07 bellard
static int net_slirp_init(VLANState *vlan)
3767 c20709aa bellard
{
3768 c20709aa bellard
    if (!slirp_inited) {
3769 c20709aa bellard
        slirp_inited = 1;
3770 c20709aa bellard
        slirp_init();
3771 c20709aa bellard
    }
3772 5fafdf24 ths
    slirp_vc = qemu_new_vlan_client(vlan,
3773 d861b05e pbrook
                                    slirp_receive, NULL, NULL);
3774 7c9d8e07 bellard
    snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
3775 9bf05444 bellard
    return 0;
3776 9bf05444 bellard
}
3777 9bf05444 bellard
3778 9bf05444 bellard
static void net_slirp_redir(const char *redir_str)
3779 9bf05444 bellard
{
3780 9bf05444 bellard
    int is_udp;
3781 9bf05444 bellard
    char buf[256], *r;
3782 9bf05444 bellard
    const char *p;
3783 9bf05444 bellard
    struct in_addr guest_addr;
3784 9bf05444 bellard
    int host_port, guest_port;
3785 3b46e624 ths
3786 9bf05444 bellard
    if (!slirp_inited) {
3787 9bf05444 bellard
        slirp_inited = 1;
3788 9bf05444 bellard
        slirp_init();
3789 9bf05444 bellard
    }
3790 9bf05444 bellard
3791 9bf05444 bellard
    p = redir_str;
3792 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3793 9bf05444 bellard
        goto fail;
3794 9bf05444 bellard
    if (!strcmp(buf, "tcp")) {
3795 9bf05444 bellard
        is_udp = 0;
3796 9bf05444 bellard
    } else if (!strcmp(buf, "udp")) {
3797 9bf05444 bellard
        is_udp = 1;
3798 9bf05444 bellard
    } else {
3799 9bf05444 bellard
        goto fail;
3800 9bf05444 bellard
    }
3801 9bf05444 bellard
3802 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3803 9bf05444 bellard
        goto fail;
3804 9bf05444 bellard
    host_port = strtol(buf, &r, 0);
3805 9bf05444 bellard
    if (r == buf)
3806 9bf05444 bellard
        goto fail;
3807 9bf05444 bellard
3808 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3809 9bf05444 bellard
        goto fail;
3810 9bf05444 bellard
    if (buf[0] == '\0') {
3811 9bf05444 bellard
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
3812 9bf05444 bellard
    }
3813 9bf05444 bellard
    if (!inet_aton(buf, &guest_addr))
3814 9bf05444 bellard
        goto fail;
3815 3b46e624 ths
3816 9bf05444 bellard
    guest_port = strtol(p, &r, 0);
3817 9bf05444 bellard
    if (r == p)
3818 9bf05444 bellard
        goto fail;
3819 3b46e624 ths
3820 9bf05444 bellard
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
3821 9bf05444 bellard
        fprintf(stderr, "qemu: could not set up redirection\n");
3822 9bf05444 bellard
        exit(1);
3823 9bf05444 bellard
    }
3824 9bf05444 bellard
    return;
3825 9bf05444 bellard
 fail:
3826 9bf05444 bellard
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
3827 9bf05444 bellard
    exit(1);
3828 9bf05444 bellard
}
3829 3b46e624 ths
3830 c94c8d64 bellard
#ifndef _WIN32
3831 c94c8d64 bellard
3832 9d728e8c bellard
char smb_dir[1024];
3833 9d728e8c bellard
3834 044fae83 balrog
static void erase_dir(char *dir_name)
3835 9d728e8c bellard
{
3836 9d728e8c bellard
    DIR *d;
3837 9d728e8c bellard
    struct dirent *de;
3838 9d728e8c bellard
    char filename[1024];
3839 9d728e8c bellard
3840 9d728e8c bellard
    /* erase all the files in the directory */
3841 044fae83 balrog
    if ((d = opendir(dir_name)) != 0) {
3842 044fae83 balrog
        for(;;) {
3843 044fae83 balrog
            de = readdir(d);
3844 044fae83 balrog
            if (!de)
3845 044fae83 balrog
                break;
3846 044fae83 balrog
            if (strcmp(de->d_name, ".") != 0 &&
3847 044fae83 balrog
                strcmp(de->d_name, "..") != 0) {
3848 044fae83 balrog
                snprintf(filename, sizeof(filename), "%s/%s",
3849 044fae83 balrog
                         smb_dir, de->d_name);
3850 044fae83 balrog
                if (unlink(filename) != 0)  /* is it a directory? */
3851 044fae83 balrog
                    erase_dir(filename);
3852 044fae83 balrog
            }
3853 9d728e8c bellard
        }
3854 044fae83 balrog
        closedir(d);
3855 044fae83 balrog
        rmdir(dir_name);
3856 9d728e8c bellard
    }
3857 044fae83 balrog
}
3858 044fae83 balrog
3859 044fae83 balrog
/* automatic user mode samba server configuration */
3860 044fae83 balrog
static void smb_exit(void)
3861 044fae83 balrog
{
3862 044fae83 balrog
    erase_dir(smb_dir);
3863 9d728e8c bellard
}
3864 9d728e8c bellard
3865 9d728e8c bellard
/* automatic user mode samba server configuration */
3866 9596ebb7 pbrook
static void net_slirp_smb(const char *exported_dir)
3867 9d728e8c bellard
{
3868 9d728e8c bellard
    char smb_conf[1024];
3869 9d728e8c bellard
    char smb_cmdline[1024];
3870 9d728e8c bellard
    FILE *f;
3871 9d728e8c bellard
3872 9d728e8c bellard
    if (!slirp_inited) {
3873 9d728e8c bellard
        slirp_inited = 1;
3874 9d728e8c bellard
        slirp_init();
3875 9d728e8c bellard
    }
3876 9d728e8c bellard
3877 9d728e8c bellard
    /* XXX: better tmp dir construction */
3878 9d728e8c bellard
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
3879 9d728e8c bellard
    if (mkdir(smb_dir, 0700) < 0) {
3880 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
3881 9d728e8c bellard
        exit(1);
3882 9d728e8c bellard
    }
3883 9d728e8c bellard
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
3884 3b46e624 ths
3885 9d728e8c bellard
    f = fopen(smb_conf, "w");
3886 9d728e8c bellard
    if (!f) {
3887 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
3888 9d728e8c bellard
        exit(1);
3889 9d728e8c bellard
    }
3890 5fafdf24 ths
    fprintf(f,
3891 9d728e8c bellard
            "[global]\n"
3892 157777ef bellard
            "private dir=%s\n"
3893 157777ef bellard
            "smb ports=0\n"
3894 157777ef bellard
            "socket address=127.0.0.1\n"
3895 9d728e8c bellard
            "pid directory=%s\n"
3896 9d728e8c bellard
            "lock directory=%s\n"
3897 9d728e8c bellard
            "log file=%s/log.smbd\n"
3898 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
3899 03ffbb69 bellard
            "security = share\n"
3900 9d728e8c bellard
            "[qemu]\n"
3901 9d728e8c bellard
            "path=%s\n"
3902 9d728e8c bellard
            "read only=no\n"
3903 9d728e8c bellard
            "guest ok=yes\n",
3904 9d728e8c bellard
            smb_dir,
3905 157777ef bellard
            smb_dir,
3906 9d728e8c bellard
            smb_dir,
3907 9d728e8c bellard
            smb_dir,
3908 9d728e8c bellard
            smb_dir,
3909 9d728e8c bellard
            exported_dir
3910 9d728e8c bellard
            );
3911 9d728e8c bellard
    fclose(f);
3912 9d728e8c bellard
    atexit(smb_exit);
3913 9d728e8c bellard
3914 a14d6c8c pbrook
    snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
3915 a14d6c8c pbrook
             SMBD_COMMAND, smb_conf);
3916 3b46e624 ths
3917 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
3918 9d728e8c bellard
}
3919 9bf05444 bellard
3920 c94c8d64 bellard
#endif /* !defined(_WIN32) */
3921 31a60e22 blueswir1
void do_info_slirp(void)
3922 31a60e22 blueswir1
{
3923 31a60e22 blueswir1
    slirp_stats();
3924 31a60e22 blueswir1
}
3925 c94c8d64 bellard
3926 c20709aa bellard
#endif /* CONFIG_SLIRP */
3927 c20709aa bellard
3928 c20709aa bellard
#if !defined(_WIN32)
3929 7c9d8e07 bellard
3930 7c9d8e07 bellard
typedef struct TAPState {
3931 7c9d8e07 bellard
    VLANClientState *vc;
3932 7c9d8e07 bellard
    int fd;
3933 b46a8906 ths
    char down_script[1024];
3934 7c9d8e07 bellard
} TAPState;
3935 7c9d8e07 bellard
3936 7c9d8e07 bellard
static void tap_receive(void *opaque, const uint8_t *buf, int size)
3937 7c9d8e07 bellard
{
3938 7c9d8e07 bellard
    TAPState *s = opaque;
3939 7c9d8e07 bellard
    int ret;
3940 7c9d8e07 bellard
    for(;;) {
3941 7c9d8e07 bellard
        ret = write(s->fd, buf, size);
3942 7c9d8e07 bellard
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
3943 7c9d8e07 bellard
        } else {
3944 7c9d8e07 bellard
            break;
3945 7c9d8e07 bellard
        }
3946 7c9d8e07 bellard
    }
3947 7c9d8e07 bellard
}
3948 7c9d8e07 bellard
3949 7c9d8e07 bellard
static void tap_send(void *opaque)
3950 7c9d8e07 bellard
{
3951 7c9d8e07 bellard
    TAPState *s = opaque;
3952 7c9d8e07 bellard
    uint8_t buf[4096];
3953 7c9d8e07 bellard
    int size;
3954 7c9d8e07 bellard
3955 d5d10bc3 ths
#ifdef __sun__
3956 d5d10bc3 ths
    struct strbuf sbuf;
3957 d5d10bc3 ths
    int f = 0;
3958 d5d10bc3 ths
    sbuf.maxlen = sizeof(buf);
3959 d5d10bc3 ths
    sbuf.buf = buf;
3960 d5d10bc3 ths
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
3961 d5d10bc3 ths
#else
3962 7c9d8e07 bellard
    size = read(s->fd, buf, sizeof(buf));
3963 d5d10bc3 ths
#endif
3964 7c9d8e07 bellard
    if (size > 0) {
3965 7c9d8e07 bellard
        qemu_send_packet(s->vc, buf, size);
3966 7c9d8e07 bellard
    }
3967 7c9d8e07 bellard
}
3968 7c9d8e07 bellard
3969 7c9d8e07 bellard
/* fd support */
3970 7c9d8e07 bellard
3971 7c9d8e07 bellard
static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
3972 7c9d8e07 bellard
{
3973 7c9d8e07 bellard
    TAPState *s;
3974 7c9d8e07 bellard
3975 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(TAPState));
3976 7c9d8e07 bellard
    if (!s)
3977 7c9d8e07 bellard
        return NULL;
3978 7c9d8e07 bellard
    s->fd = fd;
3979 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
3980 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
3981 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
3982 7c9d8e07 bellard
    return s;
3983 7c9d8e07 bellard
}
3984 7c9d8e07 bellard
3985 5c40d2bd ths
#if defined (_BSD) || defined (__FreeBSD_kernel__)
3986 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3987 7d3505c5 bellard
{
3988 7d3505c5 bellard
    int fd;
3989 7d3505c5 bellard
    char *dev;
3990 7d3505c5 bellard
    struct stat s;
3991 67b915a5 bellard
3992 aeb30be6 balrog
    TFR(fd = open("/dev/tap", O_RDWR));
3993 7d3505c5 bellard
    if (fd < 0) {
3994 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
3995 7d3505c5 bellard
        return -1;
3996 7d3505c5 bellard
    }
3997 7d3505c5 bellard
3998 7d3505c5 bellard
    fstat(fd, &s);
3999 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
4000 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
4001 7d3505c5 bellard
4002 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
4003 7d3505c5 bellard
    return fd;
4004 7d3505c5 bellard
}
4005 ec530c81 bellard
#elif defined(__sun__)
4006 d5d10bc3 ths
#define TUNNEWPPA       (('T'<<16) | 0x0001)
4007 5fafdf24 ths
/*
4008 5fafdf24 ths
 * Allocate TAP device, returns opened fd.
4009 d5d10bc3 ths
 * Stores dev name in the first arg(must be large enough).
4010 3b46e624 ths
 */
4011 d5d10bc3 ths
int tap_alloc(char *dev)
4012 d5d10bc3 ths
{
4013 d5d10bc3 ths
    int tap_fd, if_fd, ppa = -1;
4014 d5d10bc3 ths
    static int ip_fd = 0;
4015 d5d10bc3 ths
    char *ptr;
4016 d5d10bc3 ths
4017 d5d10bc3 ths
    static int arp_fd = 0;
4018 d5d10bc3 ths
    int ip_muxid, arp_muxid;
4019 d5d10bc3 ths
    struct strioctl  strioc_if, strioc_ppa;
4020 d5d10bc3 ths
    int link_type = I_PLINK;;
4021 d5d10bc3 ths
    struct lifreq ifr;
4022 d5d10bc3 ths
    char actual_name[32] = "";
4023 d5d10bc3 ths
4024 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
4025 d5d10bc3 ths
4026 d5d10bc3 ths
    if( *dev ){
4027 5fafdf24 ths
       ptr = dev;
4028 5fafdf24 ths
       while( *ptr && !isdigit((int)*ptr) ) ptr++;
4029 d5d10bc3 ths
       ppa = atoi(ptr);
4030 d5d10bc3 ths
    }
4031 d5d10bc3 ths
4032 d5d10bc3 ths
    /* Check if IP device was opened */
4033 d5d10bc3 ths
    if( ip_fd )
4034 d5d10bc3 ths
       close(ip_fd);
4035 d5d10bc3 ths
4036 aeb30be6 balrog
    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
4037 aeb30be6 balrog
    if (ip_fd < 0) {
4038 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
4039 d5d10bc3 ths
       return -1;
4040 d5d10bc3 ths
    }
4041 d5d10bc3 ths
4042 aeb30be6 balrog
    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
4043 aeb30be6 balrog
    if (tap_fd < 0) {
4044 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap");
4045 d5d10bc3 ths
       return -1;
4046 d5d10bc3 ths
    }
4047 d5d10bc3 ths
4048 d5d10bc3 ths
    /* Assign a new PPA and get its unit number. */
4049 d5d10bc3 ths
    strioc_ppa.ic_cmd = TUNNEWPPA;
4050 d5d10bc3 ths
    strioc_ppa.ic_timout = 0;
4051 d5d10bc3 ths
    strioc_ppa.ic_len = sizeof(ppa);
4052 d5d10bc3 ths
    strioc_ppa.ic_dp = (char *)&ppa;
4053 d5d10bc3 ths
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
4054 d5d10bc3 ths
       syslog (LOG_ERR, "Can't assign new interface");
4055 d5d10bc3 ths
4056 aeb30be6 balrog
    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
4057 aeb30be6 balrog
    if (if_fd < 0) {
4058 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
4059 d5d10bc3 ths
       return -1;
4060 d5d10bc3 ths
    }
4061 d5d10bc3 ths
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
4062 d5d10bc3 ths
       syslog(LOG_ERR, "Can't push IP module");
4063 d5d10bc3 ths
       return -1;
4064 d5d10bc3 ths
    }
4065 d5d10bc3 ths
4066 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
4067 d5d10bc3 ths
        syslog(LOG_ERR, "Can't get flags\n");
4068 d5d10bc3 ths
4069 d5d10bc3 ths
    snprintf (actual_name, 32, "tap%d", ppa);
4070 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4071 d5d10bc3 ths
4072 d5d10bc3 ths
    ifr.lifr_ppa = ppa;
4073 d5d10bc3 ths
    /* Assign ppa according to the unit number returned by tun device */
4074 d5d10bc3 ths
4075 d5d10bc3 ths
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
4076 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
4077 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
4078 d5d10bc3 ths
        syslog (LOG_ERR, "Can't get flags\n");
4079 d5d10bc3 ths
    /* Push arp module to if_fd */
4080 d5d10bc3 ths
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
4081 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (2)");
4082 d5d10bc3 ths
4083 d5d10bc3 ths
    /* Push arp module to ip_fd */
4084 d5d10bc3 ths
    if (ioctl (ip_fd, I_POP, NULL) < 0)
4085 d5d10bc3 ths
        syslog (LOG_ERR, "I_POP failed\n");
4086 d5d10bc3 ths
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
4087 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
4088 d5d10bc3 ths
    /* Open arp_fd */
4089 aeb30be6 balrog
    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
4090 aeb30be6 balrog
    if (arp_fd < 0)
4091 d5d10bc3 ths
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
4092 d5d10bc3 ths
4093 d5d10bc3 ths
    /* Set ifname to arp */
4094 d5d10bc3 ths
    strioc_if.ic_cmd = SIOCSLIFNAME;
4095 d5d10bc3 ths
    strioc_if.ic_timout = 0;
4096 d5d10bc3 ths
    strioc_if.ic_len = sizeof(ifr);
4097 d5d10bc3 ths
    strioc_if.ic_dp = (char *)&ifr;
4098 d5d10bc3 ths
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
4099 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set ifname to arp\n");
4100 d5d10bc3 ths
    }
4101 d5d10bc3 ths
4102 d5d10bc3 ths
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
4103 d5d10bc3 ths
       syslog(LOG_ERR, "Can't link TAP device to IP");
4104 d5d10bc3 ths
       return -1;
4105 d5d10bc3 ths
    }
4106 d5d10bc3 ths
4107 d5d10bc3 ths
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
4108 d5d10bc3 ths
        syslog (LOG_ERR, "Can't link TAP device to ARP");
4109 d5d10bc3 ths
4110 d5d10bc3 ths
    close (if_fd);
4111 d5d10bc3 ths
4112 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
4113 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
4114 d5d10bc3 ths
    ifr.lifr_ip_muxid  = ip_muxid;
4115 d5d10bc3 ths
    ifr.lifr_arp_muxid = arp_muxid;
4116 d5d10bc3 ths
4117 d5d10bc3 ths
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
4118 d5d10bc3 ths
    {
4119 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
4120 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
4121 d5d10bc3 ths
      syslog (LOG_ERR, "Can't set multiplexor id");
4122 d5d10bc3 ths
    }
4123 d5d10bc3 ths
4124 d5d10bc3 ths
    sprintf(dev, "tap%d", ppa);
4125 d5d10bc3 ths
    return tap_fd;
4126 d5d10bc3 ths
}
4127 d5d10bc3 ths
4128 ec530c81 bellard
static int tap_open(char *ifname, int ifname_size)
4129 ec530c81 bellard
{
4130 d5d10bc3 ths
    char  dev[10]="";
4131 d5d10bc3 ths
    int fd;
4132 d5d10bc3 ths
    if( (fd = tap_alloc(dev)) < 0 ){
4133 d5d10bc3 ths
       fprintf(stderr, "Cannot allocate TAP device\n");
4134 d5d10bc3 ths
       return -1;
4135 d5d10bc3 ths
    }
4136 d5d10bc3 ths
    pstrcpy(ifname, ifname_size, dev);
4137 d5d10bc3 ths
    fcntl(fd, F_SETFL, O_NONBLOCK);
4138 d5d10bc3 ths
    return fd;
4139 ec530c81 bellard
}
4140 7d3505c5 bellard
#else
4141 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
4142 330d0414 bellard
{
4143 80cabfad bellard
    struct ifreq ifr;
4144 c4b1fcc0 bellard
    int fd, ret;
4145 3b46e624 ths
4146 aeb30be6 balrog
    TFR(fd = open("/dev/net/tun", O_RDWR));
4147 80cabfad bellard
    if (fd < 0) {
4148 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4149 80cabfad bellard
        return -1;
4150 330d0414 bellard
    }
4151 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
4152 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
4153 7c9d8e07 bellard
    if (ifname[0] != '\0')
4154 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4155 7c9d8e07 bellard
    else
4156 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
4157 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4158 80cabfad bellard
    if (ret != 0) {
4159 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4160 80cabfad bellard
        close(fd);
4161 80cabfad bellard
        return -1;
4162 80cabfad bellard
    }
4163 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
4164 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
4165 c4b1fcc0 bellard
    return fd;
4166 c4b1fcc0 bellard
}
4167 7d3505c5 bellard
#endif
4168 330d0414 bellard
4169 b46a8906 ths
static int launch_script(const char *setup_script, const char *ifname, int fd)
4170 7c9d8e07 bellard
{
4171 b46a8906 ths
    int pid, status;
4172 7c9d8e07 bellard
    char *args[3];
4173 7c9d8e07 bellard
    char **parg;
4174 7c9d8e07 bellard
4175 b46a8906 ths
        /* try to launch network script */
4176 7c9d8e07 bellard
        pid = fork();
4177 7c9d8e07 bellard
        if (pid >= 0) {
4178 7c9d8e07 bellard
            if (pid == 0) {
4179 50d3eeae ths
                int open_max = sysconf (_SC_OPEN_MAX), i;
4180 50d3eeae ths
                for (i = 0; i < open_max; i++)
4181 50d3eeae ths
                    if (i != STDIN_FILENO &&
4182 50d3eeae ths
                        i != STDOUT_FILENO &&
4183 50d3eeae ths
                        i != STDERR_FILENO &&
4184 50d3eeae ths
                        i != fd)
4185 50d3eeae ths
                        close(i);
4186 50d3eeae ths
4187 7c9d8e07 bellard
                parg = args;
4188 7c9d8e07 bellard
                *parg++ = (char *)setup_script;
4189 b46a8906 ths
                *parg++ = (char *)ifname;
4190 7c9d8e07 bellard
                *parg++ = NULL;
4191 7c9d8e07 bellard
                execv(setup_script, args);
4192 4a38940d bellard
                _exit(1);
4193 7c9d8e07 bellard
            }
4194 7c9d8e07 bellard
            while (waitpid(pid, &status, 0) != pid);
4195 7c9d8e07 bellard
            if (!WIFEXITED(status) ||
4196 7c9d8e07 bellard
                WEXITSTATUS(status) != 0) {
4197 7c9d8e07 bellard
                fprintf(stderr, "%s: could not launch network script\n",
4198 7c9d8e07 bellard
                        setup_script);
4199 7c9d8e07 bellard
                return -1;
4200 7c9d8e07 bellard
            }
4201 7c9d8e07 bellard
        }
4202 b46a8906 ths
    return 0;
4203 b46a8906 ths
}
4204 b46a8906 ths
4205 b46a8906 ths
static int net_tap_init(VLANState *vlan, const char *ifname1,
4206 b46a8906 ths
                        const char *setup_script, const char *down_script)
4207 b46a8906 ths
{
4208 b46a8906 ths
    TAPState *s;
4209 b46a8906 ths
    int fd;
4210 b46a8906 ths
    char ifname[128];
4211 b46a8906 ths
4212 b46a8906 ths
    if (ifname1 != NULL)
4213 b46a8906 ths
        pstrcpy(ifname, sizeof(ifname), ifname1);
4214 b46a8906 ths
    else
4215 b46a8906 ths
        ifname[0] = '\0';
4216 b46a8906 ths
    TFR(fd = tap_open(ifname, sizeof(ifname)));
4217 b46a8906 ths
    if (fd < 0)
4218 b46a8906 ths
        return -1;
4219 b46a8906 ths
4220 b46a8906 ths
    if (!setup_script || !strcmp(setup_script, "no"))
4221 b46a8906 ths
        setup_script = "";
4222 b46a8906 ths
    if (setup_script[0] != '\0') {
4223 b46a8906 ths
        if (launch_script(setup_script, ifname, fd))
4224 b46a8906 ths
            return -1;
4225 7c9d8e07 bellard
    }
4226 7c9d8e07 bellard
    s = net_tap_fd_init(vlan, fd);
4227 7c9d8e07 bellard
    if (!s)
4228 7c9d8e07 bellard
        return -1;
4229 5fafdf24 ths
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4230 7c9d8e07 bellard
             "tap: ifname=%s setup_script=%s", ifname, setup_script);
4231 b46a8906 ths
    if (down_script && strcmp(down_script, "no"))
4232 b46a8906 ths
        snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
4233 7c9d8e07 bellard
    return 0;
4234 7c9d8e07 bellard
}
4235 7c9d8e07 bellard
4236 fd1dff4b bellard
#endif /* !_WIN32 */
4237 fd1dff4b bellard
4238 7c9d8e07 bellard
/* network connection */
4239 7c9d8e07 bellard
typedef struct NetSocketState {
4240 7c9d8e07 bellard
    VLANClientState *vc;
4241 7c9d8e07 bellard
    int fd;
4242 7c9d8e07 bellard
    int state; /* 0 = getting length, 1 = getting data */
4243 7c9d8e07 bellard
    int index;
4244 7c9d8e07 bellard
    int packet_len;
4245 7c9d8e07 bellard
    uint8_t buf[4096];
4246 3d830459 bellard
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
4247 7c9d8e07 bellard
} NetSocketState;
4248 7c9d8e07 bellard
4249 7c9d8e07 bellard
typedef struct NetSocketListenState {
4250 7c9d8e07 bellard
    VLANState *vlan;
4251 7c9d8e07 bellard
    int fd;
4252 7c9d8e07 bellard
} NetSocketListenState;
4253 7c9d8e07 bellard
4254 7c9d8e07 bellard
/* XXX: we consider we can send the whole packet without blocking */
4255 7c9d8e07 bellard
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
4256 c20709aa bellard
{
4257 7c9d8e07 bellard
    NetSocketState *s = opaque;
4258 7c9d8e07 bellard
    uint32_t len;
4259 7c9d8e07 bellard
    len = htonl(size);
4260 7c9d8e07 bellard
4261 fd1dff4b bellard
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4262 fd1dff4b bellard
    send_all(s->fd, buf, size);
4263 c20709aa bellard
}
4264 c20709aa bellard
4265 3d830459 bellard
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4266 3d830459 bellard
{
4267 3d830459 bellard
    NetSocketState *s = opaque;
4268 5fafdf24 ths
    sendto(s->fd, buf, size, 0,
4269 3d830459 bellard
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4270 3d830459 bellard
}
4271 3d830459 bellard
4272 7c9d8e07 bellard
static void net_socket_send(void *opaque)
4273 c4b1fcc0 bellard
{
4274 7c9d8e07 bellard
    NetSocketState *s = opaque;
4275 fd1dff4b bellard
    int l, size, err;
4276 7c9d8e07 bellard
    uint8_t buf1[4096];
4277 7c9d8e07 bellard
    const uint8_t *buf;
4278 7c9d8e07 bellard
4279 fd1dff4b bellard
    size = recv(s->fd, buf1, sizeof(buf1), 0);
4280 fd1dff4b bellard
    if (size < 0) {
4281 fd1dff4b bellard
        err = socket_error();
4282 5fafdf24 ths
        if (err != EWOULDBLOCK)
4283 fd1dff4b bellard
            goto eoc;
4284 fd1dff4b bellard
    } else if (size == 0) {
4285 7c9d8e07 bellard
        /* end of connection */
4286 fd1dff4b bellard
    eoc:
4287 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4288 fd1dff4b bellard
        closesocket(s->fd);
4289 7c9d8e07 bellard
        return;
4290 7c9d8e07 bellard
    }
4291 7c9d8e07 bellard
    buf = buf1;
4292 7c9d8e07 bellard
    while (size > 0) {
4293 7c9d8e07 bellard
        /* reassemble a packet from the network */
4294 7c9d8e07 bellard
        switch(s->state) {
4295 7c9d8e07 bellard
        case 0:
4296 7c9d8e07 bellard
            l = 4 - s->index;
4297 7c9d8e07 bellard
            if (l > size)
4298 7c9d8e07 bellard
                l = size;
4299 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4300 7c9d8e07 bellard
            buf += l;
4301 7c9d8e07 bellard
            size -= l;
4302 7c9d8e07 bellard
            s->index += l;
4303 7c9d8e07 bellard
            if (s->index == 4) {
4304 7c9d8e07 bellard
                /* got length */
4305 7c9d8e07 bellard
                s->packet_len = ntohl(*(uint32_t *)s->buf);
4306 7c9d8e07 bellard
                s->index = 0;
4307 7c9d8e07 bellard
                s->state = 1;
4308 7c9d8e07 bellard
            }
4309 7c9d8e07 bellard
            break;
4310 7c9d8e07 bellard
        case 1:
4311 7c9d8e07 bellard
            l = s->packet_len - s->index;
4312 7c9d8e07 bellard
            if (l > size)
4313 7c9d8e07 bellard
                l = size;
4314 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4315 7c9d8e07 bellard
            s->index += l;
4316 7c9d8e07 bellard
            buf += l;
4317 7c9d8e07 bellard
            size -= l;
4318 7c9d8e07 bellard
            if (s->index >= s->packet_len) {
4319 7c9d8e07 bellard
                qemu_send_packet(s->vc, s->buf, s->packet_len);
4320 7c9d8e07 bellard
                s->index = 0;
4321 7c9d8e07 bellard
                s->state = 0;
4322 7c9d8e07 bellard
            }
4323 7c9d8e07 bellard
            break;
4324 7c9d8e07 bellard
        }
4325 7c9d8e07 bellard
    }
4326 c20709aa bellard
}
4327 c20709aa bellard
4328 3d830459 bellard
static void net_socket_send_dgram(void *opaque)
4329 3d830459 bellard
{
4330 3d830459 bellard
    NetSocketState *s = opaque;
4331 3d830459 bellard
    int size;
4332 3d830459 bellard
4333 3d830459 bellard
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
4334 5fafdf24 ths
    if (size < 0)
4335 3d830459 bellard
        return;
4336 3d830459 bellard
    if (size == 0) {
4337 3d830459 bellard
        /* end of connection */
4338 3d830459 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4339 3d830459 bellard
        return;
4340 3d830459 bellard
    }
4341 3d830459 bellard
    qemu_send_packet(s->vc, s->buf, size);
4342 3d830459 bellard
}
4343 3d830459 bellard
4344 3d830459 bellard
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4345 3d830459 bellard
{
4346 3d830459 bellard
    struct ip_mreq imr;
4347 3d830459 bellard
    int fd;
4348 3d830459 bellard
    int val, ret;
4349 3d830459 bellard
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4350 3d830459 bellard
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
4351 5fafdf24 ths
                inet_ntoa(mcastaddr->sin_addr),
4352 fd1dff4b bellard
                (int)ntohl(mcastaddr->sin_addr.s_addr));
4353 3d830459 bellard
        return -1;
4354 3d830459 bellard
4355 3d830459 bellard
    }
4356 3d830459 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
4357 3d830459 bellard
    if (fd < 0) {
4358 3d830459 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
4359 3d830459 bellard
        return -1;
4360 3d830459 bellard
    }
4361 3d830459 bellard
4362 fd1dff4b bellard
    val = 1;
4363 5fafdf24 ths
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
4364 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4365 fd1dff4b bellard
    if (ret < 0) {
4366 fd1dff4b bellard
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4367 fd1dff4b bellard
        goto fail;
4368 fd1dff4b bellard
    }
4369 fd1dff4b bellard
4370 fd1dff4b bellard
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4371 fd1dff4b bellard
    if (ret < 0) {
4372 fd1dff4b bellard
        perror("bind");
4373 fd1dff4b bellard
        goto fail;
4374 fd1dff4b bellard
    }
4375 3b46e624 ths
4376 3d830459 bellard
    /* Add host to multicast group */
4377 3d830459 bellard
    imr.imr_multiaddr = mcastaddr->sin_addr;
4378 3d830459 bellard
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
4379 3d830459 bellard
4380 5fafdf24 ths
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
4381 fd1dff4b bellard
                     (const char *)&imr, sizeof(struct ip_mreq));
4382 3d830459 bellard
    if (ret < 0) {
4383 3d830459 bellard
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
4384 3d830459 bellard
        goto fail;
4385 3d830459 bellard
    }
4386 3d830459 bellard
4387 3d830459 bellard
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4388 3d830459 bellard
    val = 1;
4389 5fafdf24 ths
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
4390 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4391 3d830459 bellard
    if (ret < 0) {
4392 3d830459 bellard
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4393 3d830459 bellard
        goto fail;
4394 3d830459 bellard
    }
4395 3d830459 bellard
4396 fd1dff4b bellard
    socket_set_nonblock(fd);
4397 3d830459 bellard
    return fd;
4398 3d830459 bellard
fail:
4399 5fafdf24 ths
    if (fd >= 0)
4400 0bab00f3 bellard
        closesocket(fd);
4401 3d830459 bellard
    return -1;
4402 3d830459 bellard
}
4403 3d830459 bellard
4404 5fafdf24 ths
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,
4405 3d830459 bellard
                                          int is_connected)
4406 3d830459 bellard
{
4407 3d830459 bellard
    struct sockaddr_in saddr;
4408 3d830459 bellard
    int newfd;
4409 3d830459 bellard
    socklen_t saddr_len;
4410 3d830459 bellard
    NetSocketState *s;
4411 3d830459 bellard
4412 3d830459 bellard
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
4413 5fafdf24 ths
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
4414 3d830459 bellard
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
4415 3d830459 bellard
     */
4416 3d830459 bellard
4417 3d830459 bellard
    if (is_connected) {
4418 3d830459 bellard
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4419 3d830459 bellard
            /* must be bound */
4420 3d830459 bellard
            if (saddr.sin_addr.s_addr==0) {
4421 3d830459 bellard
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4422 3d830459 bellard
                        fd);
4423 3d830459 bellard
                return NULL;
4424 3d830459 bellard
            }
4425 3d830459 bellard
            /* clone dgram socket */
4426 3d830459 bellard
            newfd = net_socket_mcast_create(&saddr);
4427 3d830459 bellard
            if (newfd < 0) {
4428 3d830459 bellard
                /* error already reported by net_socket_mcast_create() */
4429 3d830459 bellard
                close(fd);
4430 3d830459 bellard
                return NULL;
4431 3d830459 bellard
            }
4432 3d830459 bellard
            /* clone newfd to fd, close newfd */
4433 3d830459 bellard
            dup2(newfd, fd);
4434 3d830459 bellard
            close(newfd);
4435 5fafdf24 ths
4436 3d830459 bellard
        } else {
4437 3d830459 bellard
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4438 3d830459 bellard
                    fd, strerror(errno));
4439 3d830459 bellard
            return NULL;
4440 3d830459 bellard
        }
4441 3d830459 bellard
    }
4442 3d830459 bellard
4443 3d830459 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4444 3d830459 bellard
    if (!s)
4445 3d830459 bellard
        return NULL;
4446 3d830459 bellard
    s->fd = fd;
4447 3d830459 bellard
4448 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
4449 3d830459 bellard
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4450 3d830459 bellard
4451 3d830459 bellard
    /* mcast: save bound address as dst */
4452 3d830459 bellard
    if (is_connected) s->dgram_dst=saddr;
4453 3d830459 bellard
4454 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4455 5fafdf24 ths
            "socket: fd=%d (%s mcast=%s:%d)",
4456 3d830459 bellard
            fd, is_connected? "cloned" : "",
4457 3d830459 bellard
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4458 3d830459 bellard
    return s;
4459 3d830459 bellard
}
4460 3d830459 bellard
4461 7c9d8e07 bellard
static void net_socket_connect(void *opaque)
4462 c20709aa bellard
{
4463 7c9d8e07 bellard
    NetSocketState *s = opaque;
4464 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4465 7c9d8e07 bellard
}
4466 c4b1fcc0 bellard
4467 5fafdf24 ths
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd,
4468 7c9d8e07 bellard
                                          int is_connected)
4469 7c9d8e07 bellard
{
4470 7c9d8e07 bellard
    NetSocketState *s;
4471 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4472 7c9d8e07 bellard
    if (!s)
4473 7c9d8e07 bellard
        return NULL;
4474 7c9d8e07 bellard
    s->fd = fd;
4475 5fafdf24 ths
    s->vc = qemu_new_vlan_client(vlan,
4476 d861b05e pbrook
                                 net_socket_receive, NULL, s);
4477 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4478 7c9d8e07 bellard
             "socket: fd=%d", fd);
4479 7c9d8e07 bellard
    if (is_connected) {
4480 7c9d8e07 bellard
        net_socket_connect(s);
4481 7c9d8e07 bellard
    } else {
4482 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4483 7c9d8e07 bellard
    }
4484 7c9d8e07 bellard
    return s;
4485 7c9d8e07 bellard
}
4486 c4b1fcc0 bellard
4487 5fafdf24 ths
static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
4488 3d830459 bellard
                                          int is_connected)
4489 3d830459 bellard
{
4490 3d830459 bellard
    int so_type=-1, optlen=sizeof(so_type);
4491 3d830459 bellard
4492 69b34976 ths
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
4493 69b34976 ths
        (socklen_t *)&optlen)< 0) {
4494 931f03ee ths
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
4495 3d830459 bellard
        return NULL;
4496 3d830459 bellard
    }
4497 3d830459 bellard
    switch(so_type) {
4498 3d830459 bellard
    case SOCK_DGRAM:
4499 3d830459 bellard
        return net_socket_fd_init_dgram(vlan, fd, is_connected);
4500 3d830459 bellard
    case SOCK_STREAM:
4501 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4502 3d830459 bellard
    default:
4503 3d830459 bellard
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4504 3d830459 bellard
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4505 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4506 3d830459 bellard
    }
4507 3d830459 bellard
    return NULL;
4508 3d830459 bellard
}
4509 3d830459 bellard
4510 7c9d8e07 bellard
static void net_socket_accept(void *opaque)
4511 7c9d8e07 bellard
{
4512 3b46e624 ths
    NetSocketListenState *s = opaque;
4513 7c9d8e07 bellard
    NetSocketState *s1;
4514 7c9d8e07 bellard
    struct sockaddr_in saddr;
4515 7c9d8e07 bellard
    socklen_t len;
4516 7c9d8e07 bellard
    int fd;
4517 7c9d8e07 bellard
4518 7c9d8e07 bellard
    for(;;) {
4519 7c9d8e07 bellard
        len = sizeof(saddr);
4520 7c9d8e07 bellard
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4521 7c9d8e07 bellard
        if (fd < 0 && errno != EINTR) {
4522 7c9d8e07 bellard
            return;
4523 7c9d8e07 bellard
        } else if (fd >= 0) {
4524 7c9d8e07 bellard
            break;
4525 80cabfad bellard
        }
4526 330d0414 bellard
    }
4527 5fafdf24 ths
    s1 = net_socket_fd_init(s->vlan, fd, 1);
4528 7c9d8e07 bellard
    if (!s1) {
4529 0bab00f3 bellard
        closesocket(fd);
4530 7c9d8e07 bellard
    } else {
4531 7c9d8e07 bellard
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
4532 5fafdf24 ths
                 "socket: connection from %s:%d",
4533 7c9d8e07 bellard
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4534 7c9d8e07 bellard
    }
4535 7c9d8e07 bellard
}
4536 7c9d8e07 bellard
4537 7c9d8e07 bellard
static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4538 7c9d8e07 bellard
{
4539 7c9d8e07 bellard
    NetSocketListenState *s;
4540 7c9d8e07 bellard
    int fd, val, ret;
4541 7c9d8e07 bellard
    struct sockaddr_in saddr;
4542 7c9d8e07 bellard
4543 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4544 7c9d8e07 bellard
        return -1;
4545 3b46e624 ths
4546 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketListenState));
4547 7c9d8e07 bellard
    if (!s)
4548 7c9d8e07 bellard
        return -1;
4549 7c9d8e07 bellard
4550 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4551 7c9d8e07 bellard
    if (fd < 0) {
4552 7c9d8e07 bellard
        perror("socket");
4553 7c9d8e07 bellard
        return -1;
4554 7c9d8e07 bellard
    }
4555 fd1dff4b bellard
    socket_set_nonblock(fd);
4556 7c9d8e07 bellard
4557 7c9d8e07 bellard
    /* allow fast reuse */
4558 7c9d8e07 bellard
    val = 1;
4559 fd1dff4b bellard
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
4560 3b46e624 ths
4561 7c9d8e07 bellard
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4562 7c9d8e07 bellard
    if (ret < 0) {
4563 7c9d8e07 bellard
        perror("bind");
4564 7c9d8e07 bellard
        return -1;
4565 7c9d8e07 bellard
    }
4566 7c9d8e07 bellard
    ret = listen(fd, 0);
4567 7c9d8e07 bellard
    if (ret < 0) {
4568 7c9d8e07 bellard
        perror("listen");
4569 7c9d8e07 bellard
        return -1;
4570 7c9d8e07 bellard
    }
4571 7c9d8e07 bellard
    s->vlan = vlan;
4572 7c9d8e07 bellard
    s->fd = fd;
4573 7c9d8e07 bellard
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
4574 80cabfad bellard
    return 0;
4575 330d0414 bellard
}
4576 330d0414 bellard
4577 7c9d8e07 bellard
static int net_socket_connect_init(VLANState *vlan, const char *host_str)
4578 330d0414 bellard
{
4579 7c9d8e07 bellard
    NetSocketState *s;
4580 fd1dff4b bellard
    int fd, connected, ret, err;
4581 7c9d8e07 bellard
    struct sockaddr_in saddr;
4582 7c9d8e07 bellard
4583 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4584 7c9d8e07 bellard
        return -1;
4585 7c9d8e07 bellard
4586 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4587 7c9d8e07 bellard
    if (fd < 0) {
4588 7c9d8e07 bellard
        perror("socket");
4589 7c9d8e07 bellard
        return -1;
4590 7c9d8e07 bellard
    }
4591 fd1dff4b bellard
    socket_set_nonblock(fd);
4592 7c9d8e07 bellard
4593 7c9d8e07 bellard
    connected = 0;
4594 7c9d8e07 bellard
    for(;;) {
4595 7c9d8e07 bellard
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4596 7c9d8e07 bellard
        if (ret < 0) {
4597 fd1dff4b bellard
            err = socket_error();
4598 fd1dff4b bellard
            if (err == EINTR || err == EWOULDBLOCK) {
4599 fd1dff4b bellard
            } else if (err == EINPROGRESS) {
4600 7c9d8e07 bellard
                break;
4601 f5b12268 ths
#ifdef _WIN32
4602 f5b12268 ths
            } else if (err == WSAEALREADY) {
4603 f5b12268 ths
                break;
4604 f5b12268 ths
#endif
4605 7c9d8e07 bellard
            } else {
4606 7c9d8e07 bellard
                perror("connect");
4607 fd1dff4b bellard
                closesocket(fd);
4608 7c9d8e07 bellard
                return -1;
4609 7c9d8e07 bellard
            }
4610 7c9d8e07 bellard
        } else {
4611 7c9d8e07 bellard
            connected = 1;
4612 7c9d8e07 bellard
            break;
4613 7c9d8e07 bellard
        }
4614 7c9d8e07 bellard
    }
4615 7c9d8e07 bellard
    s = net_socket_fd_init(vlan, fd, connected);
4616 7c9d8e07 bellard
    if (!s)
4617 7c9d8e07 bellard
        return -1;
4618 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4619 5fafdf24 ths
             "socket: connect to %s:%d",
4620 7c9d8e07 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4621 c20709aa bellard
    return 0;
4622 80cabfad bellard
}
4623 330d0414 bellard
4624 3d830459 bellard
static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
4625 3d830459 bellard
{
4626 3d830459 bellard
    NetSocketState *s;
4627 3d830459 bellard
    int fd;
4628 3d830459 bellard
    struct sockaddr_in saddr;
4629 3d830459 bellard
4630 3d830459 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4631 3d830459 bellard
        return -1;
4632 3d830459 bellard
4633 3d830459 bellard
4634 3d830459 bellard
    fd = net_socket_mcast_create(&saddr);
4635 3d830459 bellard
    if (fd < 0)
4636 3d830459 bellard
        return -1;
4637 3d830459 bellard
4638 3d830459 bellard
    s = net_socket_fd_init(vlan, fd, 0);
4639 3d830459 bellard
    if (!s)
4640 3d830459 bellard
        return -1;
4641 3d830459 bellard
4642 3d830459 bellard
    s->dgram_dst = saddr;
4643 3b46e624 ths
4644 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4645 5fafdf24 ths
             "socket: mcast=%s:%d",
4646 3d830459 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4647 3d830459 bellard
    return 0;
4648 3d830459 bellard
4649 3d830459 bellard
}
4650 3d830459 bellard
4651 609497ab balrog
static const char *get_opt_name(char *buf, int buf_size, const char *p)
4652 609497ab balrog
{
4653 609497ab balrog
    char *q;
4654 609497ab balrog
4655 609497ab balrog
    q = buf;
4656 609497ab balrog
    while (*p != '\0' && *p != '=') {
4657 609497ab balrog
        if (q && (q - buf) < buf_size - 1)
4658 609497ab balrog
            *q++ = *p;
4659 609497ab balrog
        p++;
4660 609497ab balrog
    }
4661 609497ab balrog
    if (q)
4662 609497ab balrog
        *q = '\0';
4663 609497ab balrog
4664 609497ab balrog
    return p;
4665 609497ab balrog
}
4666 609497ab balrog
4667 609497ab balrog
static const char *get_opt_value(char *buf, int buf_size, const char *p)
4668 e4bcb14c ths
{
4669 e4bcb14c ths
    char *q;
4670 e4bcb14c ths
4671 e4bcb14c ths
    q = buf;
4672 e4bcb14c ths
    while (*p != '\0') {
4673 609497ab balrog
        if (*p == ',') {
4674 609497ab balrog
            if (*(p + 1) != ',')
4675 e4bcb14c ths
                break;
4676 e4bcb14c ths
            p++;
4677 609497ab balrog
        }
4678 e4bcb14c ths
        if (q && (q - buf) < buf_size - 1)
4679 e4bcb14c ths
            *q++ = *p;
4680 e4bcb14c ths
        p++;
4681 e4bcb14c ths
    }
4682 e4bcb14c ths
    if (q)
4683 e4bcb14c ths
        *q = '\0';
4684 e4bcb14c ths
4685 e4bcb14c ths
    return p;
4686 e4bcb14c ths
}
4687 e4bcb14c ths
4688 7c9d8e07 bellard
static int get_param_value(char *buf, int buf_size,
4689 7c9d8e07 bellard
                           const char *tag, const char *str)
4690 7c9d8e07 bellard
{
4691 7c9d8e07 bellard
    const char *p;
4692 7c9d8e07 bellard
    char option[128];
4693 7c9d8e07 bellard
4694 7c9d8e07 bellard
    p = str;
4695 7c9d8e07 bellard
    for(;;) {
4696 609497ab balrog
        p = get_opt_name(option, sizeof(option), p);
4697 7c9d8e07 bellard
        if (*p != '=')
4698 7c9d8e07 bellard
            break;
4699 7c9d8e07 bellard
        p++;
4700 7c9d8e07 bellard
        if (!strcmp(tag, option)) {
4701 609497ab balrog
            (void)get_opt_value(buf, buf_size, p);
4702 e4bcb14c ths
            return strlen(buf);
4703 7c9d8e07 bellard
        } else {
4704 609497ab balrog
            p = get_opt_value(NULL, 0, p);
4705 7c9d8e07 bellard
        }
4706 7c9d8e07 bellard
        if (*p != ',')
4707 7c9d8e07 bellard
            break;
4708 7c9d8e07 bellard
        p++;
4709 7c9d8e07 bellard
    }
4710 7c9d8e07 bellard
    return 0;
4711 7c9d8e07 bellard
}
4712 7c9d8e07 bellard
4713 e4bcb14c ths
static int check_params(char *buf, int buf_size,
4714 e4bcb14c ths
                        char **params, const char *str)
4715 e4bcb14c ths
{
4716 e4bcb14c ths
    const char *p;
4717 e4bcb14c ths
    int i;
4718 e4bcb14c ths
4719 e4bcb14c ths
    p = str;
4720 e4bcb14c ths
    for(;;) {
4721 609497ab balrog
        p = get_opt_name(buf, buf_size, p);
4722 e4bcb14c ths
        if (*p != '=')
4723 e4bcb14c ths
            return -1;
4724 e4bcb14c ths
        p++;
4725 e4bcb14c ths
        for(i = 0; params[i] != NULL; i++)
4726 e4bcb14c ths
            if (!strcmp(params[i], buf))
4727 e4bcb14c ths
                break;
4728 e4bcb14c ths
        if (params[i] == NULL)
4729 e4bcb14c ths
            return -1;
4730 609497ab balrog
        p = get_opt_value(NULL, 0, p);
4731 e4bcb14c ths
        if (*p != ',')
4732 e4bcb14c ths
            break;
4733 e4bcb14c ths
        p++;
4734 e4bcb14c ths
    }
4735 e4bcb14c ths
    return 0;
4736 e4bcb14c ths
}
4737 e4bcb14c ths
4738 e4bcb14c ths
4739 52f61fde ths
static int net_client_init(const char *str)
4740 7c9d8e07 bellard
{
4741 7c9d8e07 bellard
    const char *p;
4742 7c9d8e07 bellard
    char *q;
4743 7c9d8e07 bellard
    char device[64];
4744 7c9d8e07 bellard
    char buf[1024];
4745 7c9d8e07 bellard
    int vlan_id, ret;
4746 7c9d8e07 bellard
    VLANState *vlan;
4747 7c9d8e07 bellard
4748 7c9d8e07 bellard
    p = str;
4749 7c9d8e07 bellard
    q = device;
4750 7c9d8e07 bellard
    while (*p != '\0' && *p != ',') {
4751 7c9d8e07 bellard
        if ((q - device) < sizeof(device) - 1)
4752 7c9d8e07 bellard
            *q++ = *p;
4753 7c9d8e07 bellard
        p++;
4754 7c9d8e07 bellard
    }
4755 7c9d8e07 bellard
    *q = '\0';
4756 7c9d8e07 bellard
    if (*p == ',')
4757 7c9d8e07 bellard
        p++;
4758 7c9d8e07 bellard
    vlan_id = 0;
4759 7c9d8e07 bellard
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
4760 7c9d8e07 bellard
        vlan_id = strtol(buf, NULL, 0);
4761 7c9d8e07 bellard
    }
4762 7c9d8e07 bellard
    vlan = qemu_find_vlan(vlan_id);
4763 7c9d8e07 bellard
    if (!vlan) {
4764 7c9d8e07 bellard
        fprintf(stderr, "Could not create vlan %d\n", vlan_id);
4765 7c9d8e07 bellard
        return -1;
4766 7c9d8e07 bellard
    }
4767 7c9d8e07 bellard
    if (!strcmp(device, "nic")) {
4768 7c9d8e07 bellard
        NICInfo *nd;
4769 7c9d8e07 bellard
        uint8_t *macaddr;
4770 7c9d8e07 bellard
4771 7c9d8e07 bellard
        if (nb_nics >= MAX_NICS) {
4772 7c9d8e07 bellard
            fprintf(stderr, "Too Many NICs\n");
4773 7c9d8e07 bellard
            return -1;
4774 7c9d8e07 bellard
        }
4775 7c9d8e07 bellard
        nd = &nd_table[nb_nics];
4776 7c9d8e07 bellard
        macaddr = nd->macaddr;
4777 7c9d8e07 bellard
        macaddr[0] = 0x52;
4778 7c9d8e07 bellard
        macaddr[1] = 0x54;
4779 7c9d8e07 bellard
        macaddr[2] = 0x00;
4780 7c9d8e07 bellard
        macaddr[3] = 0x12;
4781 7c9d8e07 bellard
        macaddr[4] = 0x34;
4782 7c9d8e07 bellard
        macaddr[5] = 0x56 + nb_nics;
4783 7c9d8e07 bellard
4784 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
4785 7c9d8e07 bellard
            if (parse_macaddr(macaddr, buf) < 0) {
4786 7c9d8e07 bellard
                fprintf(stderr, "invalid syntax for ethernet address\n");
4787 7c9d8e07 bellard
                return -1;
4788 7c9d8e07 bellard
            }
4789 7c9d8e07 bellard
        }
4790 a41b2ff2 pbrook
        if (get_param_value(buf, sizeof(buf), "model", p)) {
4791 a41b2ff2 pbrook
            nd->model = strdup(buf);
4792 a41b2ff2 pbrook
        }
4793 7c9d8e07 bellard
        nd->vlan = vlan;
4794 7c9d8e07 bellard
        nb_nics++;
4795 833c7174 blueswir1
        vlan->nb_guest_devs++;
4796 7c9d8e07 bellard
        ret = 0;
4797 7c9d8e07 bellard
    } else
4798 7c9d8e07 bellard
    if (!strcmp(device, "none")) {
4799 7c9d8e07 bellard
        /* does nothing. It is needed to signal that no network cards
4800 7c9d8e07 bellard
           are wanted */
4801 7c9d8e07 bellard
        ret = 0;
4802 7c9d8e07 bellard
    } else
4803 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
4804 7c9d8e07 bellard
    if (!strcmp(device, "user")) {
4805 115defd1 pbrook
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
4806 3f423c9c bellard
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
4807 115defd1 pbrook
        }
4808 833c7174 blueswir1
        vlan->nb_host_devs++;
4809 7c9d8e07 bellard
        ret = net_slirp_init(vlan);
4810 7c9d8e07 bellard
    } else
4811 7c9d8e07 bellard
#endif
4812 7fb843f8 bellard
#ifdef _WIN32
4813 7fb843f8 bellard
    if (!strcmp(device, "tap")) {
4814 7fb843f8 bellard
        char ifname[64];
4815 7fb843f8 bellard
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4816 7fb843f8 bellard
            fprintf(stderr, "tap: no interface name\n");
4817 7fb843f8 bellard
            return -1;
4818 7fb843f8 bellard
        }
4819 833c7174 blueswir1
        vlan->nb_host_devs++;
4820 7fb843f8 bellard
        ret = tap_win32_init(vlan, ifname);
4821 7fb843f8 bellard
    } else
4822 7fb843f8 bellard
#else
4823 7c9d8e07 bellard
    if (!strcmp(device, "tap")) {
4824 7c9d8e07 bellard
        char ifname[64];
4825 b46a8906 ths
        char setup_script[1024], down_script[1024];
4826 7c9d8e07 bellard
        int fd;
4827 4f01035f pbrook
        vlan->nb_host_devs++;
4828 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4829 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4830 7c9d8e07 bellard
            ret = -1;
4831 7c9d8e07 bellard
            if (net_tap_fd_init(vlan, fd))
4832 7c9d8e07 bellard
                ret = 0;
4833 7c9d8e07 bellard
        } else {
4834 bf8c5342 bellard
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4835 bf8c5342 bellard
                ifname[0] = '\0';
4836 bf8c5342 bellard
            }
4837 7c9d8e07 bellard
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
4838 7c9d8e07 bellard
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
4839 7c9d8e07 bellard
            }
4840 b46a8906 ths
            if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {
4841 b46a8906 ths
                pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);
4842 b46a8906 ths
            }
4843 b46a8906 ths
            ret = net_tap_init(vlan, ifname, setup_script, down_script);
4844 7c9d8e07 bellard
        }
4845 7c9d8e07 bellard
    } else
4846 fd1dff4b bellard
#endif
4847 7c9d8e07 bellard
    if (!strcmp(device, "socket")) {
4848 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4849 7c9d8e07 bellard
            int fd;
4850 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4851 7c9d8e07 bellard
            ret = -1;
4852 7c9d8e07 bellard
            if (net_socket_fd_init(vlan, fd, 1))
4853 7c9d8e07 bellard
                ret = 0;
4854 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
4855 7c9d8e07 bellard
            ret = net_socket_listen_init(vlan, buf);
4856 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
4857 7c9d8e07 bellard
            ret = net_socket_connect_init(vlan, buf);
4858 3d830459 bellard
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
4859 3d830459 bellard
            ret = net_socket_mcast_init(vlan, buf);
4860 7c9d8e07 bellard
        } else {
4861 7c9d8e07 bellard
            fprintf(stderr, "Unknown socket options: %s\n", p);
4862 7c9d8e07 bellard
            return -1;
4863 7c9d8e07 bellard
        }
4864 833c7174 blueswir1
        vlan->nb_host_devs++;
4865 7c9d8e07 bellard
    } else
4866 7c9d8e07 bellard
    {
4867 7c9d8e07 bellard
        fprintf(stderr, "Unknown network device: %s\n", device);
4868 7c9d8e07 bellard
        return -1;
4869 7c9d8e07 bellard
    }
4870 7c9d8e07 bellard
    if (ret < 0) {
4871 7c9d8e07 bellard
        fprintf(stderr, "Could not initialize device '%s'\n", device);
4872 7c9d8e07 bellard
    }
4873 3b46e624 ths
4874 7c9d8e07 bellard
    return ret;
4875 7c9d8e07 bellard
}
4876 7c9d8e07 bellard
4877 7c9d8e07 bellard
void do_info_network(void)
4878 7c9d8e07 bellard
{
4879 7c9d8e07 bellard
    VLANState *vlan;
4880 7c9d8e07 bellard
    VLANClientState *vc;
4881 7c9d8e07 bellard
4882 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4883 7c9d8e07 bellard
        term_printf("VLAN %d devices:\n", vlan->id);
4884 7c9d8e07 bellard
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
4885 7c9d8e07 bellard
            term_printf("  %s\n", vc->info_str);
4886 7c9d8e07 bellard
    }
4887 7c9d8e07 bellard
}
4888 42550fde ths
4889 609497ab balrog
#define HD_ALIAS "index=%d,media=disk"
4890 e4bcb14c ths
#ifdef TARGET_PPC
4891 e4bcb14c ths
#define CDROM_ALIAS "index=1,media=cdrom"
4892 e4bcb14c ths
#else
4893 e4bcb14c ths
#define CDROM_ALIAS "index=2,media=cdrom"
4894 e4bcb14c ths
#endif
4895 e4bcb14c ths
#define FD_ALIAS "index=%d,if=floppy"
4896 609497ab balrog
#define PFLASH_ALIAS "if=pflash"
4897 609497ab balrog
#define MTD_ALIAS "if=mtd"
4898 9d413d1d balrog
#define SD_ALIAS "index=0,if=sd"
4899 e4bcb14c ths
4900 609497ab balrog
static int drive_add(const char *file, const char *fmt, ...)
4901 e4bcb14c ths
{
4902 e4bcb14c ths
    va_list ap;
4903 e4bcb14c ths
4904 e4bcb14c ths
    if (nb_drives_opt >= MAX_DRIVES) {
4905 e4bcb14c ths
        fprintf(stderr, "qemu: too many drives\n");
4906 e4bcb14c ths
        exit(1);
4907 e4bcb14c ths
    }
4908 e4bcb14c ths
4909 609497ab balrog
    drives_opt[nb_drives_opt].file = file;
4910 e4bcb14c ths
    va_start(ap, fmt);
4911 609497ab balrog
    vsnprintf(drives_opt[nb_drives_opt].opt,
4912 609497ab balrog
              sizeof(drives_opt[0].opt), fmt, ap);
4913 e4bcb14c ths
    va_end(ap);
4914 e4bcb14c ths
4915 e4bcb14c ths
    return nb_drives_opt++;
4916 e4bcb14c ths
}
4917 e4bcb14c ths
4918 f60d39bc ths
int drive_get_index(BlockInterfaceType type, int bus, int unit)
4919 e4bcb14c ths
{
4920 e4bcb14c ths
    int index;
4921 e4bcb14c ths
4922 e4bcb14c ths
    /* seek interface, bus and unit */
4923 e4bcb14c ths
4924 e4bcb14c ths
    for (index = 0; index < nb_drives; index++)
4925 f60d39bc ths
        if (drives_table[index].type == type &&
4926 e4bcb14c ths
            drives_table[index].bus == bus &&
4927 e4bcb14c ths
            drives_table[index].unit == unit)
4928 e4bcb14c ths
        return index;
4929 e4bcb14c ths
4930 e4bcb14c ths
    return -1;
4931 e4bcb14c ths
}
4932 e4bcb14c ths
4933 f60d39bc ths
int drive_get_max_bus(BlockInterfaceType type)
4934 e4bcb14c ths
{
4935 e4bcb14c ths
    int max_bus;
4936 e4bcb14c ths
    int index;
4937 e4bcb14c ths
4938 e4bcb14c ths
    max_bus = -1;
4939 e4bcb14c ths
    for (index = 0; index < nb_drives; index++) {
4940 f60d39bc ths
        if(drives_table[index].type == type &&
4941 e4bcb14c ths
           drives_table[index].bus > max_bus)
4942 e4bcb14c ths
            max_bus = drives_table[index].bus;
4943 e4bcb14c ths
    }
4944 e4bcb14c ths
    return max_bus;
4945 e4bcb14c ths
}
4946 e4bcb14c ths
4947 609497ab balrog
static int drive_init(struct drive_opt *arg, int snapshot,
4948 609497ab balrog
                      QEMUMachine *machine)
4949 e4bcb14c ths
{
4950 e4bcb14c ths
    char buf[128];
4951 e4bcb14c ths
    char file[1024];
4952 c8522bdf balrog
    char devname[128];
4953 c8522bdf balrog
    const char *mediastr = "";
4954 f60d39bc ths
    BlockInterfaceType type;
4955 e4bcb14c ths
    enum { MEDIA_DISK, MEDIA_CDROM } media;
4956 e4bcb14c ths
    int bus_id, unit_id;
4957 e4bcb14c ths
    int cyls, heads, secs, translation;
4958 e4bcb14c ths
    BlockDriverState *bdrv;
4959 e4bcb14c ths
    int max_devs;
4960 e4bcb14c ths
    int index;
4961 33f00271 balrog
    int cache;
4962 33f00271 balrog
    int bdrv_flags;
4963 609497ab balrog
    char *str = arg->opt;
4964 e4bcb14c ths
    char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
4965 33f00271 balrog
                       "secs", "trans", "media", "snapshot", "file",
4966 33f00271 balrog
                       "cache", NULL };
4967 e4bcb14c ths
4968 e4bcb14c ths
    if (check_params(buf, sizeof(buf), params, str) < 0) {
4969 ff993638 balrog
         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
4970 e4bcb14c ths
                         buf, str);
4971 e4bcb14c ths
         return -1;
4972 e4bcb14c ths
    }
4973 e4bcb14c ths
4974 e4bcb14c ths
    file[0] = 0;
4975 e4bcb14c ths
    cyls = heads = secs = 0;
4976 e4bcb14c ths
    bus_id = 0;
4977 e4bcb14c ths
    unit_id = -1;
4978 e4bcb14c ths
    translation = BIOS_ATA_TRANSLATION_AUTO;
4979 e4bcb14c ths
    index = -1;
4980 33f00271 balrog
    cache = 1;
4981 e4bcb14c ths
4982 e4bcb14c ths
    if (!strcmp(machine->name, "realview") ||
4983 e4bcb14c ths
        !strcmp(machine->name, "SS-5") ||
4984 e4bcb14c ths
        !strcmp(machine->name, "SS-10") ||
4985 e4bcb14c ths
        !strcmp(machine->name, "SS-600MP") ||
4986 e4bcb14c ths
        !strcmp(machine->name, "versatilepb") ||
4987 e4bcb14c ths
        !strcmp(machine->name, "versatileab")) {
4988 f60d39bc ths
        type = IF_SCSI;
4989 e4bcb14c ths
        max_devs = MAX_SCSI_DEVS;
4990 c8522bdf balrog
        strcpy(devname, "scsi");
4991 e4bcb14c ths
    } else {
4992 f60d39bc ths
        type = IF_IDE;
4993 e4bcb14c ths
        max_devs = MAX_IDE_DEVS;
4994 c8522bdf balrog
        strcpy(devname, "ide");
4995 e4bcb14c ths
    }
4996 e4bcb14c ths
    media = MEDIA_DISK;
4997 e4bcb14c ths
4998 e4bcb14c ths
    /* extract parameters */
4999 e4bcb14c ths
5000 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "bus", str)) {
5001 e4bcb14c ths
        bus_id = strtol(buf, NULL, 0);
5002 e4bcb14c ths
        if (bus_id < 0) {
5003 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
5004 e4bcb14c ths
            return -1;
5005 e4bcb14c ths
        }
5006 e4bcb14c ths
    }
5007 e4bcb14c ths
5008 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "unit", str)) {
5009 e4bcb14c ths
        unit_id = strtol(buf, NULL, 0);
5010 e4bcb14c ths
        if (unit_id < 0) {
5011 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
5012 e4bcb14c ths
            return -1;
5013 e4bcb14c ths
        }
5014 e4bcb14c ths
    }
5015 e4bcb14c ths
5016 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "if", str)) {
5017 c8522bdf balrog
        strncpy(devname, buf, sizeof(devname));
5018 e4bcb14c ths
        if (!strcmp(buf, "ide")) {
5019 f60d39bc ths
            type = IF_IDE;
5020 e4bcb14c ths
            max_devs = MAX_IDE_DEVS;
5021 e4bcb14c ths
        } else if (!strcmp(buf, "scsi")) {
5022 f60d39bc ths
            type = IF_SCSI;
5023 e4bcb14c ths
            max_devs = MAX_SCSI_DEVS;
5024 e4bcb14c ths
        } else if (!strcmp(buf, "floppy")) {
5025 f60d39bc ths
            type = IF_FLOPPY;
5026 e4bcb14c ths
            max_devs = 0;
5027 e4bcb14c ths
        } else if (!strcmp(buf, "pflash")) {
5028 f60d39bc ths
            type = IF_PFLASH;
5029 e4bcb14c ths
            max_devs = 0;
5030 e4bcb14c ths
        } else if (!strcmp(buf, "mtd")) {
5031 f60d39bc ths
            type = IF_MTD;
5032 e4bcb14c ths
            max_devs = 0;
5033 e4bcb14c ths
        } else if (!strcmp(buf, "sd")) {
5034 f60d39bc ths
            type = IF_SD;
5035 e4bcb14c ths
            max_devs = 0;
5036 e4bcb14c ths
        } else {
5037 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
5038 e4bcb14c ths
            return -1;
5039 e4bcb14c ths
        }
5040 e4bcb14c ths
    }
5041 e4bcb14c ths
5042 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "index", str)) {
5043 e4bcb14c ths
        index = strtol(buf, NULL, 0);
5044 e4bcb14c ths
        if (index < 0) {
5045 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid index\n", str);
5046 e4bcb14c ths
            return -1;
5047 e4bcb14c ths
        }
5048 e4bcb14c ths
    }
5049 e4bcb14c ths
5050 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "cyls", str)) {
5051 e4bcb14c ths
        cyls = strtol(buf, NULL, 0);
5052 e4bcb14c ths
    }
5053 e4bcb14c ths
5054 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "heads", str)) {
5055 e4bcb14c ths
        heads = strtol(buf, NULL, 0);
5056 e4bcb14c ths
    }
5057 e4bcb14c ths
5058 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "secs", str)) {
5059 e4bcb14c ths
        secs = strtol(buf, NULL, 0);
5060 e4bcb14c ths
    }
5061 e4bcb14c ths
5062 e4bcb14c ths
    if (cyls || heads || secs) {
5063 e4bcb14c ths
        if (cyls < 1 || cyls > 16383) {
5064 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
5065 e4bcb14c ths
            return -1;
5066 e4bcb14c ths
        }
5067 e4bcb14c ths
        if (heads < 1 || heads > 16) {
5068 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
5069 e4bcb14c ths
            return -1;
5070 e4bcb14c ths
        }
5071 e4bcb14c ths
        if (secs < 1 || secs > 63) {
5072 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
5073 e4bcb14c ths
            return -1;
5074 e4bcb14c ths
        }
5075 e4bcb14c ths
    }
5076 e4bcb14c ths
5077 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "trans", str)) {
5078 e4bcb14c ths
        if (!cyls) {
5079 e4bcb14c ths
            fprintf(stderr,
5080 e4bcb14c ths
                    "qemu: '%s' trans must be used with cyls,heads and secs\n",
5081 e4bcb14c ths
                    str);
5082 e4bcb14c ths
            return -1;
5083 e4bcb14c ths
        }
5084 e4bcb14c ths
        if (!strcmp(buf, "none"))
5085 e4bcb14c ths
            translation = BIOS_ATA_TRANSLATION_NONE;
5086 e4bcb14c ths
        else if (!strcmp(buf, "lba"))
5087 e4bcb14c ths
            translation = BIOS_ATA_TRANSLATION_LBA;
5088 e4bcb14c ths
        else if (!strcmp(buf, "auto"))
5089 e4bcb14c ths
            translation = BIOS_ATA_TRANSLATION_AUTO;
5090 e4bcb14c ths
        else {
5091 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
5092 e4bcb14c ths
            return -1;
5093 e4bcb14c ths
        }
5094 e4bcb14c ths
    }
5095 e4bcb14c ths
5096 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "media", str)) {
5097 e4bcb14c ths
        if (!strcmp(buf, "disk")) {
5098 e4bcb14c ths
            media = MEDIA_DISK;
5099 e4bcb14c ths
        } else if (!strcmp(buf, "cdrom")) {
5100 e4bcb14c ths
            if (cyls || secs || heads) {
5101 e4bcb14c ths
                fprintf(stderr,
5102 e4bcb14c ths
                        "qemu: '%s' invalid physical CHS format\n", str);
5103 e4bcb14c ths
                return -1;
5104 e4bcb14c ths
            }
5105 e4bcb14c ths
            media = MEDIA_CDROM;
5106 e4bcb14c ths
        } else {
5107 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid media\n", str);
5108 e4bcb14c ths
            return -1;
5109 e4bcb14c ths
        }
5110 e4bcb14c ths
    }
5111 e4bcb14c ths
5112 e4bcb14c ths
    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
5113 e4bcb14c ths
        if (!strcmp(buf, "on"))
5114 e4bcb14c ths
            snapshot = 1;
5115 e4bcb14c ths
        else if (!strcmp(buf, "off"))
5116 e4bcb14c ths
            snapshot = 0;
5117 e4bcb14c ths
        else {
5118 e4bcb14c ths
            fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
5119 e4bcb14c ths
            return -1;
5120 e4bcb14c ths
        }
5121 e4bcb14c ths
    }
5122 e4bcb14c ths
5123 33f00271 balrog
    if (get_param_value(buf, sizeof(buf), "cache", str)) {
5124 33f00271 balrog
        if (!strcmp(buf, "off"))
5125 33f00271 balrog
            cache = 0;
5126 33f00271 balrog
        else if (!strcmp(buf, "on"))
5127 33f00271 balrog
            cache = 1;
5128 33f00271 balrog
        else {
5129 33f00271 balrog
           fprintf(stderr, "qemu: invalid cache option\n");
5130 33f00271 balrog
           return -1;
5131 33f00271 balrog
        }
5132 33f00271 balrog
    }
5133 33f00271 balrog
5134 609497ab balrog
    if (arg->file == NULL)
5135 609497ab balrog
        get_param_value(file, sizeof(file), "file", str);
5136 609497ab balrog
    else
5137 609497ab balrog
        pstrcpy(file, sizeof(file), arg->file);
5138 e4bcb14c ths
5139 e4bcb14c ths
    /* compute bus and unit according index */
5140 e4bcb14c ths
5141 e4bcb14c ths
    if (index != -1) {
5142 e4bcb14c ths
        if (bus_id != 0 || unit_id != -1) {
5143 e4bcb14c ths
            fprintf(stderr,
5144 e4bcb14c ths
                    "qemu: '%s' index cannot be used with bus and unit\n", str);
5145 e4bcb14c ths
            return -1;
5146 e4bcb14c ths
        }
5147 e4bcb14c ths
        if (max_devs == 0)
5148 e4bcb14c ths
        {
5149 e4bcb14c ths
            unit_id = index;
5150 e4bcb14c ths
            bus_id = 0;
5151 e4bcb14c ths
        } else {
5152 e4bcb14c ths
            unit_id = index % max_devs;
5153 e4bcb14c ths
            bus_id = index / max_devs;
5154 e4bcb14c ths
        }
5155 e4bcb14c ths
    }
5156 e4bcb14c ths
5157 e4bcb14c ths
    /* if user doesn't specify a unit_id,
5158 e4bcb14c ths
     * try to find the first free
5159 e4bcb14c ths
     */
5160 e4bcb14c ths
5161 e4bcb14c ths
    if (unit_id == -1) {
5162 e4bcb14c ths
       unit_id = 0;
5163 f60d39bc ths
       while (drive_get_index(type, bus_id, unit_id) != -1) {
5164 e4bcb14c ths
           unit_id++;
5165 e4bcb14c ths
           if (max_devs && unit_id >= max_devs) {
5166 e4bcb14c ths
               unit_id -= max_devs;
5167 e4bcb14c ths
               bus_id++;
5168 e4bcb14c ths
           }
5169 e4bcb14c ths
       }
5170 e4bcb14c ths
    }
5171 e4bcb14c ths
5172 e4bcb14c ths
    /* check unit id */
5173 e4bcb14c ths
5174 e4bcb14c ths
    if (max_devs && unit_id >= max_devs) {
5175 e4bcb14c ths
        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
5176 e4bcb14c ths
                        str, unit_id, max_devs - 1);
5177 e4bcb14c ths
        return -1;
5178 e4bcb14c ths
    }
5179 e4bcb14c ths
5180 e4bcb14c ths
    /*
5181 e4bcb14c ths
     * ignore multiple definitions
5182 e4bcb14c ths
     */
5183 e4bcb14c ths
5184 f60d39bc ths
    if (drive_get_index(type, bus_id, unit_id) != -1)
5185 e4bcb14c ths
        return 0;
5186 e4bcb14c ths
5187 e4bcb14c ths
    /* init */
5188 e4bcb14c ths
5189 f60d39bc ths
    if (type == IF_IDE || type == IF_SCSI)
5190 c8522bdf balrog
        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
5191 e6198a70 balrog
    if (max_devs)
5192 e6198a70 balrog
        snprintf(buf, sizeof(buf), "%s%i%s%i",
5193 e6198a70 balrog
                 devname, bus_id, mediastr, unit_id);
5194 e6198a70 balrog
    else
5195 e6198a70 balrog
        snprintf(buf, sizeof(buf), "%s%s%i",
5196 e6198a70 balrog
                 devname, mediastr, unit_id);
5197 e4bcb14c ths
    bdrv = bdrv_new(buf);
5198 e4bcb14c ths
    drives_table[nb_drives].bdrv = bdrv;
5199 f60d39bc ths
    drives_table[nb_drives].type = type;
5200 e4bcb14c ths
    drives_table[nb_drives].bus = bus_id;
5201 e4bcb14c ths
    drives_table[nb_drives].unit = unit_id;
5202 e4bcb14c ths
    nb_drives++;
5203 e4bcb14c ths
5204 f60d39bc ths
    switch(type) {
5205 e4bcb14c ths
    case IF_IDE:
5206 e4bcb14c ths
    case IF_SCSI:
5207 e4bcb14c ths
        switch(media) {
5208 e4bcb14c ths
        case MEDIA_DISK:
5209 e4bcb14c ths
            if (cyls != 0) {
5210 e4bcb14c ths
                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
5211 e4bcb14c ths
                bdrv_set_translation_hint(bdrv, translation);
5212 e4bcb14c ths
            }
5213 e4bcb14c ths
            break;
5214 e4bcb14c ths
        case MEDIA_CDROM:
5215 e4bcb14c ths
            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
5216 e4bcb14c ths
            break;
5217 e4bcb14c ths
        }
5218 e4bcb14c ths
        break;
5219 e4bcb14c ths
    case IF_SD:
5220 e4bcb14c ths
        /* FIXME: This isn't really a floppy, but it's a reasonable
5221 e4bcb14c ths
           approximation.  */
5222 e4bcb14c ths
    case IF_FLOPPY:
5223 e4bcb14c ths
        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
5224 e4bcb14c ths
        break;
5225 e4bcb14c ths
    case IF_PFLASH:
5226 e4bcb14c ths
    case IF_MTD:
5227 e4bcb14c ths
        break;
5228 e4bcb14c ths
    }
5229 e4bcb14c ths
    if (!file[0])
5230 e4bcb14c ths
        return 0;
5231 33f00271 balrog
    bdrv_flags = 0;
5232 33f00271 balrog
    if (snapshot)
5233 33f00271 balrog
        bdrv_flags |= BDRV_O_SNAPSHOT;
5234 33f00271 balrog
    if (!cache)
5235 33f00271 balrog
        bdrv_flags |= BDRV_O_DIRECT;
5236 33f00271 balrog
    if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) {
5237 e4bcb14c ths
        fprintf(stderr, "qemu: could not open disk image %s\n",
5238 e4bcb14c ths
                        file);
5239 e4bcb14c ths
        return -1;
5240 e4bcb14c ths
    }
5241 e4bcb14c ths
    return 0;
5242 e4bcb14c ths
}
5243 e4bcb14c ths
5244 330d0414 bellard
/***********************************************************/
5245 a594cfbf bellard
/* USB devices */
5246 a594cfbf bellard
5247 0d92ed30 pbrook
static USBPort *used_usb_ports;
5248 0d92ed30 pbrook
static USBPort *free_usb_ports;
5249 0d92ed30 pbrook
5250 0d92ed30 pbrook
/* ??? Maybe change this to register a hub to keep track of the topology.  */
5251 0d92ed30 pbrook
void qemu_register_usb_port(USBPort *port, void *opaque, int index,
5252 0d92ed30 pbrook
                            usb_attachfn attach)
5253 0d92ed30 pbrook
{
5254 0d92ed30 pbrook
    port->opaque = opaque;
5255 0d92ed30 pbrook
    port->index = index;
5256 0d92ed30 pbrook
    port->attach = attach;
5257 0d92ed30 pbrook
    port->next = free_usb_ports;
5258 0d92ed30 pbrook
    free_usb_ports = port;
5259 0d92ed30 pbrook
}
5260 0d92ed30 pbrook
5261 a594cfbf bellard
static int usb_device_add(const char *devname)
5262 a594cfbf bellard
{
5263 a594cfbf bellard
    const char *p;
5264 a594cfbf bellard
    USBDevice *dev;
5265 0d92ed30 pbrook
    USBPort *port;
5266 a594cfbf bellard
5267 0d92ed30 pbrook
    if (!free_usb_ports)
5268 a594cfbf bellard
        return -1;
5269 a594cfbf bellard
5270 a594cfbf bellard
    if (strstart(devname, "host:", &p)) {
5271 a594cfbf bellard
        dev = usb_host_device_open(p);
5272 a594cfbf bellard
    } else if (!strcmp(devname, "mouse")) {
5273 a594cfbf bellard
        dev = usb_mouse_init();
5274 09b26c5e bellard
    } else if (!strcmp(devname, "tablet")) {
5275 47b2d338 balrog
        dev = usb_tablet_init();
5276 47b2d338 balrog
    } else if (!strcmp(devname, "keyboard")) {
5277 47b2d338 balrog
        dev = usb_keyboard_init();
5278 2e5d83bb pbrook
    } else if (strstart(devname, "disk:", &p)) {
5279 2e5d83bb pbrook
        dev = usb_msd_init(p);
5280 f6d2a316 balrog
    } else if (!strcmp(devname, "wacom-tablet")) {
5281 f6d2a316 balrog
        dev = usb_wacom_init();
5282 a7954218 balrog
    } else if (strstart(devname, "serial:", &p)) {
5283 a7954218 balrog
        dev = usb_serial_init(p);
5284 a594cfbf bellard
    } else {
5285 a594cfbf bellard
        return -1;
5286 a594cfbf bellard
    }
5287 0d92ed30 pbrook
    if (!dev)
5288 0d92ed30 pbrook
        return -1;
5289 0d92ed30 pbrook
5290 0d92ed30 pbrook
    /* Find a USB port to add the device to.  */
5291 0d92ed30 pbrook
    port = free_usb_ports;
5292 0d92ed30 pbrook
    if (!port->next) {
5293 0d92ed30 pbrook
        USBDevice *hub;
5294 0d92ed30 pbrook
5295 0d92ed30 pbrook
        /* Create a new hub and chain it on.  */
5296 0d92ed30 pbrook
        free_usb_ports = NULL;
5297 0d92ed30 pbrook
        port->next = used_usb_ports;
5298 0d92ed30 pbrook
        used_usb_ports = port;
5299 0d92ed30 pbrook
5300 0d92ed30 pbrook
        hub = usb_hub_init(VM_USB_HUB_SIZE);
5301 0d92ed30 pbrook
        usb_attach(port, hub);
5302 0d92ed30 pbrook
        port = free_usb_ports;
5303 0d92ed30 pbrook
    }
5304 0d92ed30 pbrook
5305 0d92ed30 pbrook
    free_usb_ports = port->next;
5306 0d92ed30 pbrook
    port->next = used_usb_ports;
5307 0d92ed30 pbrook
    used_usb_ports = port;
5308 0d92ed30 pbrook
    usb_attach(port, dev);
5309 a594cfbf bellard
    return 0;
5310 a594cfbf bellard
}
5311 a594cfbf bellard
5312 a594cfbf bellard
static int usb_device_del(const char *devname)
5313 a594cfbf bellard
{
5314 0d92ed30 pbrook
    USBPort *port;
5315 0d92ed30 pbrook
    USBPort **lastp;
5316 059809e4 bellard
    USBDevice *dev;
5317 0d92ed30 pbrook
    int bus_num, addr;
5318 a594cfbf bellard
    const char *p;
5319 a594cfbf bellard
5320 0d92ed30 pbrook
    if (!used_usb_ports)
5321 a594cfbf bellard
        return -1;
5322 a594cfbf bellard
5323 a594cfbf bellard
    p = strchr(devname, '.');
5324 5fafdf24 ths
    if (!p)
5325 a594cfbf bellard
        return -1;
5326 a594cfbf bellard
    bus_num = strtoul(devname, NULL, 0);
5327 a594cfbf bellard
    addr = strtoul(p + 1, NULL, 0);
5328 a594cfbf bellard
    if (bus_num != 0)
5329 a594cfbf bellard
        return -1;
5330 0d92ed30 pbrook
5331 0d92ed30 pbrook
    lastp = &used_usb_ports;
5332 0d92ed30 pbrook
    port = used_usb_ports;
5333 0d92ed30 pbrook
    while (port && port->dev->addr != addr) {
5334 0d92ed30 pbrook
        lastp = &port->next;
5335 0d92ed30 pbrook
        port = port->next;
5336 a594cfbf bellard
    }
5337 0d92ed30 pbrook
5338 0d92ed30 pbrook
    if (!port)
5339 a594cfbf bellard
        return -1;
5340 0d92ed30 pbrook
5341 059809e4 bellard
    dev = port->dev;
5342 0d92ed30 pbrook
    *lastp = port->next;
5343 0d92ed30 pbrook
    usb_attach(port, NULL);
5344 059809e4 bellard
    dev->handle_destroy(dev);
5345 0d92ed30 pbrook
    port->next = free_usb_ports;
5346 0d92ed30 pbrook
    free_usb_ports = port;
5347 a594cfbf bellard
    return 0;
5348 a594cfbf bellard
}
5349 a594cfbf bellard
5350 a594cfbf bellard
void do_usb_add(const char *devname)
5351 a594cfbf bellard
{
5352 a594cfbf bellard
    int ret;
5353 a594cfbf bellard
    ret = usb_device_add(devname);
5354 5fafdf24 ths
    if (ret < 0)
5355 a594cfbf bellard
        term_printf("Could not add USB device '%s'\n", devname);
5356 a594cfbf bellard
}
5357 a594cfbf bellard
5358 a594cfbf bellard
void do_usb_del(const char *devname)
5359 a594cfbf bellard
{
5360 a594cfbf bellard
    int ret;
5361 a594cfbf bellard
    ret = usb_device_del(devname);
5362 5fafdf24 ths
    if (ret < 0)
5363 a594cfbf bellard
        term_printf("Could not remove USB device '%s'\n", devname);
5364 a594cfbf bellard
}
5365 a594cfbf bellard
5366 a594cfbf bellard
void usb_info(void)
5367 a594cfbf bellard
{
5368 a594cfbf bellard
    USBDevice *dev;
5369 0d92ed30 pbrook
    USBPort *port;
5370 a594cfbf bellard
    const char *speed_str;
5371 a594cfbf bellard
5372 0d92ed30 pbrook
    if (!usb_enabled) {
5373 a594cfbf bellard
        term_printf("USB support not enabled\n");
5374 a594cfbf bellard
        return;
5375 a594cfbf bellard
    }
5376 a594cfbf bellard
5377 0d92ed30 pbrook
    for (port = used_usb_ports; port; port = port->next) {
5378 0d92ed30 pbrook
        dev = port->dev;
5379 0d92ed30 pbrook
        if (!dev)
5380 0d92ed30 pbrook
            continue;
5381 0d92ed30 pbrook
        switch(dev->speed) {
5382 5fafdf24 ths
        case USB_SPEED_LOW:
5383 5fafdf24 ths
            speed_str = "1.5";
5384 0d92ed30 pbrook
            break;
5385 5fafdf24 ths
        case USB_SPEED_FULL:
5386 5fafdf24 ths
            speed_str = "12";
5387 0d92ed30 pbrook
            break;
5388 5fafdf24 ths
        case USB_SPEED_HIGH:
5389 5fafdf24 ths
            speed_str = "480";
5390 0d92ed30 pbrook
            break;
5391 0d92ed30 pbrook
        default:
5392 5fafdf24 ths
            speed_str = "?";
5393 0d92ed30 pbrook
            break;
5394 a594cfbf bellard
        }
5395 5fafdf24 ths
        term_printf("  Device %d.%d, Speed %s Mb/s, Product %s\n",
5396 1f6e24e7 bellard
                    0, dev->addr, speed_str, dev->devname);
5397 a594cfbf bellard
    }
5398 a594cfbf bellard
}
5399 a594cfbf bellard
5400 f7cce898 bellard
/***********************************************************/
5401 201a51fc balrog
/* PCMCIA/Cardbus */
5402 201a51fc balrog
5403 201a51fc balrog
static struct pcmcia_socket_entry_s {
5404 201a51fc balrog
    struct pcmcia_socket_s *socket;
5405 201a51fc balrog
    struct pcmcia_socket_entry_s *next;
5406 201a51fc balrog
} *pcmcia_sockets = 0;
5407 201a51fc balrog
5408 201a51fc balrog
void pcmcia_socket_register(struct pcmcia_socket_s *socket)
5409 201a51fc balrog
{
5410 201a51fc balrog
    struct pcmcia_socket_entry_s *entry;
5411 201a51fc balrog
5412 201a51fc balrog
    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
5413 201a51fc balrog
    entry->socket = socket;
5414 201a51fc balrog
    entry->next = pcmcia_sockets;
5415 201a51fc balrog
    pcmcia_sockets = entry;
5416 201a51fc balrog
}
5417 201a51fc balrog
5418 201a51fc balrog
void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
5419 201a51fc balrog
{
5420 201a51fc balrog
    struct pcmcia_socket_entry_s *entry, **ptr;
5421 201a51fc balrog
5422 201a51fc balrog
    ptr = &pcmcia_sockets;
5423 201a51fc balrog
    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
5424 201a51fc balrog
        if (entry->socket == socket) {
5425 201a51fc balrog
            *ptr = entry->next;
5426 201a51fc balrog
            qemu_free(entry);
5427 201a51fc balrog
        }
5428 201a51fc balrog
}
5429 201a51fc balrog
5430 201a51fc balrog
void pcmcia_info(void)
5431 201a51fc balrog
{
5432 201a51fc balrog
    struct pcmcia_socket_entry_s *iter;
5433 201a51fc balrog
    if (!pcmcia_sockets)
5434 201a51fc balrog
        term_printf("No PCMCIA sockets\n");
5435 201a51fc balrog
5436 201a51fc balrog
    for (iter = pcmcia_sockets; iter; iter = iter->next)
5437 201a51fc balrog
        term_printf("%s: %s\n", iter->socket->slot_string,
5438 201a51fc balrog
                    iter->socket->attached ? iter->socket->card_string :
5439 201a51fc balrog
                    "Empty");
5440 201a51fc balrog
}
5441 201a51fc balrog
5442 201a51fc balrog
/***********************************************************/
5443 2ff89790 ths
/* dumb display */
5444 2ff89790 ths
5445 2ff89790 ths
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
5446 2ff89790 ths
{
5447 2ff89790 ths
}
5448 2ff89790 ths
5449 2ff89790 ths
static void dumb_resize(DisplayState *ds, int w, int h)
5450 2ff89790 ths
{
5451 2ff89790 ths
}
5452 2ff89790 ths
5453 2ff89790 ths
static void dumb_refresh(DisplayState *ds)
5454 2ff89790 ths
{
5455 2ff89790 ths
#if defined(CONFIG_SDL)
5456 2ff89790 ths
    vga_hw_update();
5457 2ff89790 ths
#endif
5458 2ff89790 ths
}
5459 2ff89790 ths
5460 2ff89790 ths
static void dumb_display_init(DisplayState *ds)
5461 2ff89790 ths
{
5462 2ff89790 ths
    ds->data = NULL;
5463 2ff89790 ths
    ds->linesize = 0;
5464 2ff89790 ths
    ds->depth = 0;
5465 2ff89790 ths
    ds->dpy_update = dumb_update;
5466 2ff89790 ths
    ds->dpy_resize = dumb_resize;
5467 2ff89790 ths
    ds->dpy_refresh = dumb_refresh;
5468 2ff89790 ths
}
5469 2ff89790 ths
5470 2ff89790 ths
/***********************************************************/
5471 8a7ddc38 bellard
/* I/O handling */
5472 0824d6fc bellard
5473 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
5474 c4b1fcc0 bellard
5475 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
5476 c4b1fcc0 bellard
    int fd;
5477 7c9d8e07 bellard
    IOCanRWHandler *fd_read_poll;
5478 7c9d8e07 bellard
    IOHandler *fd_read;
5479 7c9d8e07 bellard
    IOHandler *fd_write;
5480 cafffd40 ths
    int deleted;
5481 c4b1fcc0 bellard
    void *opaque;
5482 c4b1fcc0 bellard
    /* temporary data */
5483 c4b1fcc0 bellard
    struct pollfd *ufd;
5484 8a7ddc38 bellard
    struct IOHandlerRecord *next;
5485 c4b1fcc0 bellard
} IOHandlerRecord;
5486 c4b1fcc0 bellard
5487 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
5488 c4b1fcc0 bellard
5489 7c9d8e07 bellard
/* XXX: fd_read_poll should be suppressed, but an API change is
5490 7c9d8e07 bellard
   necessary in the character devices to suppress fd_can_read(). */
5491 5fafdf24 ths
int qemu_set_fd_handler2(int fd,
5492 5fafdf24 ths
                         IOCanRWHandler *fd_read_poll,
5493 5fafdf24 ths
                         IOHandler *fd_read,
5494 5fafdf24 ths
                         IOHandler *fd_write,
5495 7c9d8e07 bellard
                         void *opaque)
5496 c4b1fcc0 bellard
{
5497 7c9d8e07 bellard
    IOHandlerRecord **pioh, *ioh;
5498 c4b1fcc0 bellard
5499 7c9d8e07 bellard
    if (!fd_read && !fd_write) {
5500 7c9d8e07 bellard
        pioh = &first_io_handler;
5501 7c9d8e07 bellard
        for(;;) {
5502 7c9d8e07 bellard
            ioh = *pioh;
5503 7c9d8e07 bellard
            if (ioh == NULL)
5504 7c9d8e07 bellard
                break;
5505 7c9d8e07 bellard
            if (ioh->fd == fd) {
5506 cafffd40 ths
                ioh->deleted = 1;
5507 7c9d8e07 bellard
                break;
5508 7c9d8e07 bellard
            }
5509 7c9d8e07 bellard
            pioh = &ioh->next;
5510 7c9d8e07 bellard
        }
5511 7c9d8e07 bellard
    } else {
5512 7c9d8e07 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
5513 7c9d8e07 bellard
            if (ioh->fd == fd)
5514 7c9d8e07 bellard
                goto found;
5515 7c9d8e07 bellard
        }
5516 7c9d8e07 bellard
        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
5517 7c9d8e07 bellard
        if (!ioh)
5518 7c9d8e07 bellard
            return -1;
5519 7c9d8e07 bellard
        ioh->next = first_io_handler;
5520 7c9d8e07 bellard
        first_io_handler = ioh;
5521 7c9d8e07 bellard
    found:
5522 7c9d8e07 bellard
        ioh->fd = fd;
5523 7c9d8e07 bellard
        ioh->fd_read_poll = fd_read_poll;
5524 7c9d8e07 bellard
        ioh->fd_read = fd_read;
5525 7c9d8e07 bellard
        ioh->fd_write = fd_write;
5526 7c9d8e07 bellard
        ioh->opaque = opaque;
5527 cafffd40 ths
        ioh->deleted = 0;
5528 7c9d8e07 bellard
    }
5529 c4b1fcc0 bellard
    return 0;
5530 c4b1fcc0 bellard
}
5531 c4b1fcc0 bellard
5532 5fafdf24 ths
int qemu_set_fd_handler(int fd,
5533 5fafdf24 ths
                        IOHandler *fd_read,
5534 5fafdf24 ths
                        IOHandler *fd_write,
5535 7c9d8e07 bellard
                        void *opaque)
5536 8a7ddc38 bellard
{
5537 7c9d8e07 bellard
    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
5538 8a7ddc38 bellard
}
5539 8a7ddc38 bellard
5540 8a7ddc38 bellard
/***********************************************************/
5541 f331110f bellard
/* Polling handling */
5542 f331110f bellard
5543 f331110f bellard
typedef struct PollingEntry {
5544 f331110f bellard
    PollingFunc *func;
5545 f331110f bellard
    void *opaque;
5546 f331110f bellard
    struct PollingEntry *next;
5547 f331110f bellard
} PollingEntry;
5548 f331110f bellard
5549 f331110f bellard
static PollingEntry *first_polling_entry;
5550 f331110f bellard
5551 f331110f bellard
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
5552 f331110f bellard
{
5553 f331110f bellard
    PollingEntry **ppe, *pe;
5554 f331110f bellard
    pe = qemu_mallocz(sizeof(PollingEntry));
5555 f331110f bellard
    if (!pe)
5556 f331110f bellard
        return -1;
5557 f331110f bellard
    pe->func = func;
5558 f331110f bellard
    pe->opaque = opaque;
5559 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
5560 f331110f bellard
    *ppe = pe;
5561 f331110f bellard
    return 0;
5562 f331110f bellard
}
5563 f331110f bellard
5564 f331110f bellard
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
5565 f331110f bellard
{
5566 f331110f bellard
    PollingEntry **ppe, *pe;
5567 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
5568 f331110f bellard
        pe = *ppe;
5569 f331110f bellard
        if (pe->func == func && pe->opaque == opaque) {
5570 f331110f bellard
            *ppe = pe->next;
5571 f331110f bellard
            qemu_free(pe);
5572 f331110f bellard
            break;
5573 f331110f bellard
        }
5574 f331110f bellard
    }
5575 f331110f bellard
}
5576 f331110f bellard
5577 a18e524a bellard
#ifdef _WIN32
5578 a18e524a bellard
/***********************************************************/
5579 a18e524a bellard
/* Wait objects support */
5580 a18e524a bellard
typedef struct WaitObjects {
5581 a18e524a bellard
    int num;
5582 a18e524a bellard
    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
5583 a18e524a bellard
    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
5584 a18e524a bellard
    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
5585 a18e524a bellard
} WaitObjects;
5586 a18e524a bellard
5587 a18e524a bellard
static WaitObjects wait_objects = {0};
5588 3b46e624 ths
5589 a18e524a bellard
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5590 a18e524a bellard
{
5591 a18e524a bellard
    WaitObjects *w = &wait_objects;
5592 a18e524a bellard
5593 a18e524a bellard
    if (w->num >= MAXIMUM_WAIT_OBJECTS)
5594 a18e524a bellard
        return -1;
5595 a18e524a bellard
    w->events[w->num] = handle;
5596 a18e524a bellard
    w->func[w->num] = func;
5597 a18e524a bellard
    w->opaque[w->num] = opaque;
5598 a18e524a bellard
    w->num++;
5599 a18e524a bellard
    return 0;
5600 a18e524a bellard
}
5601 a18e524a bellard
5602 a18e524a bellard
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5603 a18e524a bellard
{
5604 a18e524a bellard
    int i, found;
5605 a18e524a bellard
    WaitObjects *w = &wait_objects;
5606 a18e524a bellard
5607 a18e524a bellard
    found = 0;
5608 a18e524a bellard
    for (i = 0; i < w->num; i++) {
5609 a18e524a bellard
        if (w->events[i] == handle)
5610 a18e524a bellard
            found = 1;
5611 a18e524a bellard
        if (found) {
5612 a18e524a bellard
            w->events[i] = w->events[i + 1];
5613 a18e524a bellard
            w->func[i] = w->func[i + 1];
5614 a18e524a bellard
            w->opaque[i] = w->opaque[i + 1];
5615 3b46e624 ths
        }
5616 a18e524a bellard
    }
5617 a18e524a bellard
    if (found)
5618 a18e524a bellard
        w->num--;
5619 a18e524a bellard
}
5620 a18e524a bellard
#endif
5621 a18e524a bellard
5622 f331110f bellard
/***********************************************************/
5623 8a7ddc38 bellard
/* savevm/loadvm support */
5624 8a7ddc38 bellard
5625 faea38e7 bellard
#define IO_BUF_SIZE 32768
5626 faea38e7 bellard
5627 faea38e7 bellard
struct QEMUFile {
5628 faea38e7 bellard
    FILE *outfile;
5629 faea38e7 bellard
    BlockDriverState *bs;
5630 faea38e7 bellard
    int is_file;
5631 faea38e7 bellard
    int is_writable;
5632 faea38e7 bellard
    int64_t base_offset;
5633 faea38e7 bellard
    int64_t buf_offset; /* start of buffer when writing, end of buffer
5634 faea38e7 bellard
                           when reading */
5635 faea38e7 bellard
    int buf_index;
5636 faea38e7 bellard
    int buf_size; /* 0 when writing */
5637 faea38e7 bellard
    uint8_t buf[IO_BUF_SIZE];
5638 faea38e7 bellard
};
5639 faea38e7 bellard
5640 faea38e7 bellard
QEMUFile *qemu_fopen(const char *filename, const char *mode)
5641 faea38e7 bellard
{
5642 faea38e7 bellard
    QEMUFile *f;
5643 faea38e7 bellard
5644 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5645 faea38e7 bellard
    if (!f)
5646 faea38e7 bellard
        return NULL;
5647 faea38e7 bellard
    if (!strcmp(mode, "wb")) {
5648 faea38e7 bellard
        f->is_writable = 1;
5649 faea38e7 bellard
    } else if (!strcmp(mode, "rb")) {
5650 faea38e7 bellard
        f->is_writable = 0;
5651 faea38e7 bellard
    } else {
5652 faea38e7 bellard
        goto fail;
5653 faea38e7 bellard
    }
5654 faea38e7 bellard
    f->outfile = fopen(filename, mode);
5655 faea38e7 bellard
    if (!f->outfile)
5656 faea38e7 bellard
        goto fail;
5657 faea38e7 bellard
    f->is_file = 1;
5658 faea38e7 bellard
    return f;
5659 faea38e7 bellard
 fail:
5660 faea38e7 bellard
    if (f->outfile)
5661 faea38e7 bellard
        fclose(f->outfile);
5662 faea38e7 bellard
    qemu_free(f);
5663 faea38e7 bellard
    return NULL;
5664 faea38e7 bellard
}
5665 faea38e7 bellard
5666 9596ebb7 pbrook
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
5667 faea38e7 bellard
{
5668 faea38e7 bellard
    QEMUFile *f;
5669 faea38e7 bellard
5670 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5671 faea38e7 bellard
    if (!f)
5672 faea38e7 bellard
        return NULL;
5673 faea38e7 bellard
    f->is_file = 0;
5674 faea38e7 bellard
    f->bs = bs;
5675 faea38e7 bellard
    f->is_writable = is_writable;
5676 faea38e7 bellard
    f->base_offset = offset;
5677 faea38e7 bellard
    return f;
5678 faea38e7 bellard
}
5679 faea38e7 bellard
5680 faea38e7 bellard
void qemu_fflush(QEMUFile *f)
5681 faea38e7 bellard
{
5682 faea38e7 bellard
    if (!f->is_writable)
5683 faea38e7 bellard
        return;
5684 faea38e7 bellard
    if (f->buf_index > 0) {
5685 faea38e7 bellard
        if (f->is_file) {
5686 faea38e7 bellard
            fseek(f->outfile, f->buf_offset, SEEK_SET);
5687 faea38e7 bellard
            fwrite(f->buf, 1, f->buf_index, f->outfile);
5688 faea38e7 bellard
        } else {
5689 5fafdf24 ths
            bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
5690 faea38e7 bellard
                        f->buf, f->buf_index);
5691 faea38e7 bellard
        }
5692 faea38e7 bellard
        f->buf_offset += f->buf_index;
5693 faea38e7 bellard
        f->buf_index = 0;
5694 faea38e7 bellard
    }
5695 faea38e7 bellard
}
5696 faea38e7 bellard
5697 faea38e7 bellard
static void qemu_fill_buffer(QEMUFile *f)
5698 faea38e7 bellard
{
5699 faea38e7 bellard
    int len;
5700 faea38e7 bellard
5701 faea38e7 bellard
    if (f->is_writable)
5702 faea38e7 bellard
        return;
5703 faea38e7 bellard
    if (f->is_file) {
5704 faea38e7 bellard
        fseek(f->outfile, f->buf_offset, SEEK_SET);
5705 faea38e7 bellard
        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
5706 faea38e7 bellard
        if (len < 0)
5707 faea38e7 bellard
            len = 0;
5708 faea38e7 bellard
    } else {
5709 5fafdf24 ths
        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
5710 faea38e7 bellard
                         f->buf, IO_BUF_SIZE);
5711 faea38e7 bellard
        if (len < 0)
5712 faea38e7 bellard
            len = 0;
5713 faea38e7 bellard
    }
5714 faea38e7 bellard
    f->buf_index = 0;
5715 faea38e7 bellard
    f->buf_size = len;
5716 faea38e7 bellard
    f->buf_offset += len;
5717 faea38e7 bellard
}
5718 faea38e7 bellard
5719 faea38e7 bellard
void qemu_fclose(QEMUFile *f)
5720 faea38e7 bellard
{
5721 faea38e7 bellard
    if (f->is_writable)
5722 faea38e7 bellard
        qemu_fflush(f);
5723 faea38e7 bellard
    if (f->is_file) {
5724 faea38e7 bellard
        fclose(f->outfile);
5725 faea38e7 bellard
    }
5726 faea38e7 bellard
    qemu_free(f);
5727 faea38e7 bellard
}
5728 faea38e7 bellard
5729 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
5730 b4608c04 bellard
{
5731 faea38e7 bellard
    int l;
5732 faea38e7 bellard
    while (size > 0) {
5733 faea38e7 bellard
        l = IO_BUF_SIZE - f->buf_index;
5734 faea38e7 bellard
        if (l > size)
5735 faea38e7 bellard
            l = size;
5736 faea38e7 bellard
        memcpy(f->buf + f->buf_index, buf, l);
5737 faea38e7 bellard
        f->buf_index += l;
5738 faea38e7 bellard
        buf += l;
5739 faea38e7 bellard
        size -= l;
5740 faea38e7 bellard
        if (f->buf_index >= IO_BUF_SIZE)
5741 faea38e7 bellard
            qemu_fflush(f);
5742 faea38e7 bellard
    }
5743 b4608c04 bellard
}
5744 b4608c04 bellard
5745 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
5746 b4608c04 bellard
{
5747 faea38e7 bellard
    f->buf[f->buf_index++] = v;
5748 faea38e7 bellard
    if (f->buf_index >= IO_BUF_SIZE)
5749 faea38e7 bellard
        qemu_fflush(f);
5750 faea38e7 bellard
}
5751 faea38e7 bellard
5752 faea38e7 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
5753 faea38e7 bellard
{
5754 faea38e7 bellard
    int size, l;
5755 faea38e7 bellard
5756 faea38e7 bellard
    size = size1;
5757 faea38e7 bellard
    while (size > 0) {
5758 faea38e7 bellard
        l = f->buf_size - f->buf_index;
5759 faea38e7 bellard
        if (l == 0) {
5760 faea38e7 bellard
            qemu_fill_buffer(f);
5761 faea38e7 bellard
            l = f->buf_size - f->buf_index;
5762 faea38e7 bellard
            if (l == 0)
5763 faea38e7 bellard
                break;
5764 faea38e7 bellard
        }
5765 faea38e7 bellard
        if (l > size)
5766 faea38e7 bellard
            l = size;
5767 faea38e7 bellard
        memcpy(buf, f->buf + f->buf_index, l);
5768 faea38e7 bellard
        f->buf_index += l;
5769 faea38e7 bellard
        buf += l;
5770 faea38e7 bellard
        size -= l;
5771 faea38e7 bellard
    }
5772 faea38e7 bellard
    return size1 - size;
5773 faea38e7 bellard
}
5774 faea38e7 bellard
5775 faea38e7 bellard
int qemu_get_byte(QEMUFile *f)
5776 faea38e7 bellard
{
5777 faea38e7 bellard
    if (f->buf_index >= f->buf_size) {
5778 faea38e7 bellard
        qemu_fill_buffer(f);
5779 faea38e7 bellard
        if (f->buf_index >= f->buf_size)
5780 faea38e7 bellard
            return 0;
5781 faea38e7 bellard
    }
5782 faea38e7 bellard
    return f->buf[f->buf_index++];
5783 faea38e7 bellard
}
5784 faea38e7 bellard
5785 faea38e7 bellard
int64_t qemu_ftell(QEMUFile *f)
5786 faea38e7 bellard
{
5787 faea38e7 bellard
    return f->buf_offset - f->buf_size + f->buf_index;
5788 faea38e7 bellard
}
5789 faea38e7 bellard
5790 faea38e7 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
5791 faea38e7 bellard
{
5792 faea38e7 bellard
    if (whence == SEEK_SET) {
5793 faea38e7 bellard
        /* nothing to do */
5794 faea38e7 bellard
    } else if (whence == SEEK_CUR) {
5795 faea38e7 bellard
        pos += qemu_ftell(f);
5796 faea38e7 bellard
    } else {
5797 faea38e7 bellard
        /* SEEK_END not supported */
5798 faea38e7 bellard
        return -1;
5799 faea38e7 bellard
    }
5800 faea38e7 bellard
    if (f->is_writable) {
5801 faea38e7 bellard
        qemu_fflush(f);
5802 faea38e7 bellard
        f->buf_offset = pos;
5803 faea38e7 bellard
    } else {
5804 faea38e7 bellard
        f->buf_offset = pos;
5805 faea38e7 bellard
        f->buf_index = 0;
5806 faea38e7 bellard
        f->buf_size = 0;
5807 faea38e7 bellard
    }
5808 faea38e7 bellard
    return pos;
5809 8a7ddc38 bellard
}
5810 8a7ddc38 bellard
5811 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
5812 8a7ddc38 bellard
{
5813 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5814 8a7ddc38 bellard
    qemu_put_byte(f, v);
5815 8a7ddc38 bellard
}
5816 8a7ddc38 bellard
5817 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
5818 8a7ddc38 bellard
{
5819 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
5820 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
5821 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5822 8a7ddc38 bellard
    qemu_put_byte(f, v);
5823 8a7ddc38 bellard
}
5824 8a7ddc38 bellard
5825 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
5826 8a7ddc38 bellard
{
5827 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
5828 8a7ddc38 bellard
    qemu_put_be32(f, v);
5829 8a7ddc38 bellard
}
5830 8a7ddc38 bellard
5831 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
5832 8a7ddc38 bellard
{
5833 8a7ddc38 bellard
    unsigned int v;
5834 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
5835 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5836 8a7ddc38 bellard
    return v;
5837 8a7ddc38 bellard
}
5838 8a7ddc38 bellard
5839 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
5840 8a7ddc38 bellard
{
5841 8a7ddc38 bellard
    unsigned int v;
5842 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
5843 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
5844 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
5845 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5846 8a7ddc38 bellard
    return v;
5847 8a7ddc38 bellard
}
5848 8a7ddc38 bellard
5849 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
5850 8a7ddc38 bellard
{
5851 8a7ddc38 bellard
    uint64_t v;
5852 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
5853 8a7ddc38 bellard
    v |= qemu_get_be32(f);
5854 8a7ddc38 bellard
    return v;
5855 8a7ddc38 bellard
}
5856 8a7ddc38 bellard
5857 8a7ddc38 bellard
typedef struct SaveStateEntry {
5858 8a7ddc38 bellard
    char idstr[256];
5859 8a7ddc38 bellard
    int instance_id;
5860 8a7ddc38 bellard
    int version_id;
5861 8a7ddc38 bellard
    SaveStateHandler *save_state;
5862 8a7ddc38 bellard
    LoadStateHandler *load_state;
5863 8a7ddc38 bellard
    void *opaque;
5864 8a7ddc38 bellard
    struct SaveStateEntry *next;
5865 8a7ddc38 bellard
} SaveStateEntry;
5866 b4608c04 bellard
5867 8a7ddc38 bellard
static SaveStateEntry *first_se;
5868 8a7ddc38 bellard
5869 5fafdf24 ths
int register_savevm(const char *idstr,
5870 5fafdf24 ths
                    int instance_id,
5871 8a7ddc38 bellard
                    int version_id,
5872 8a7ddc38 bellard
                    SaveStateHandler *save_state,
5873 8a7ddc38 bellard
                    LoadStateHandler *load_state,
5874 8a7ddc38 bellard
                    void *opaque)
5875 8a7ddc38 bellard
{
5876 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
5877 8a7ddc38 bellard
5878 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
5879 8a7ddc38 bellard
    if (!se)
5880 8a7ddc38 bellard
        return -1;
5881 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
5882 8a7ddc38 bellard
    se->instance_id = instance_id;
5883 8a7ddc38 bellard
    se->version_id = version_id;
5884 8a7ddc38 bellard
    se->save_state = save_state;
5885 8a7ddc38 bellard
    se->load_state = load_state;
5886 8a7ddc38 bellard
    se->opaque = opaque;
5887 8a7ddc38 bellard
    se->next = NULL;
5888 8a7ddc38 bellard
5889 8a7ddc38 bellard
    /* add at the end of list */
5890 8a7ddc38 bellard
    pse = &first_se;
5891 8a7ddc38 bellard
    while (*pse != NULL)
5892 8a7ddc38 bellard
        pse = &(*pse)->next;
5893 8a7ddc38 bellard
    *pse = se;
5894 8a7ddc38 bellard
    return 0;
5895 8a7ddc38 bellard
}
5896 8a7ddc38 bellard
5897 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
5898 faea38e7 bellard
#define QEMU_VM_FILE_VERSION 0x00000002
5899 8a7ddc38 bellard
5900 9596ebb7 pbrook
static int qemu_savevm_state(QEMUFile *f)
5901 8a7ddc38 bellard
{
5902 8a7ddc38 bellard
    SaveStateEntry *se;
5903 faea38e7 bellard
    int len, ret;
5904 faea38e7 bellard
    int64_t cur_pos, len_pos, total_len_pos;
5905 313aa567 bellard
5906 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
5907 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
5908 faea38e7 bellard
    total_len_pos = qemu_ftell(f);
5909 faea38e7 bellard
    qemu_put_be64(f, 0); /* total size */
5910 8a7ddc38 bellard
5911 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5912 8a7ddc38 bellard
        /* ID string */
5913 8a7ddc38 bellard
        len = strlen(se->idstr);
5914 8a7ddc38 bellard
        qemu_put_byte(f, len);
5915 ffe8ab83 ths
        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
5916 8a7ddc38 bellard
5917 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
5918 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
5919 8a7ddc38 bellard
5920 8a7ddc38 bellard
        /* record size: filled later */
5921 faea38e7 bellard
        len_pos = qemu_ftell(f);
5922 8a7ddc38 bellard
        qemu_put_be32(f, 0);
5923 8a7ddc38 bellard
        se->save_state(f, se->opaque);
5924 8a7ddc38 bellard
5925 8a7ddc38 bellard
        /* fill record size */
5926 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5927 faea38e7 bellard
        len = cur_pos - len_pos - 4;
5928 faea38e7 bellard
        qemu_fseek(f, len_pos, SEEK_SET);
5929 8a7ddc38 bellard
        qemu_put_be32(f, len);
5930 faea38e7 bellard
        qemu_fseek(f, cur_pos, SEEK_SET);
5931 8a7ddc38 bellard
    }
5932 faea38e7 bellard
    cur_pos = qemu_ftell(f);
5933 faea38e7 bellard
    qemu_fseek(f, total_len_pos, SEEK_SET);
5934 faea38e7 bellard
    qemu_put_be64(f, cur_pos - total_len_pos - 8);
5935 faea38e7 bellard
    qemu_fseek(f, cur_pos, SEEK_SET);
5936 8a7ddc38 bellard
5937 8a7ddc38 bellard
    ret = 0;
5938 8a7ddc38 bellard
    return ret;
5939 8a7ddc38 bellard
}
5940 8a7ddc38 bellard
5941 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
5942 8a7ddc38 bellard
{
5943 8a7ddc38 bellard
    SaveStateEntry *se;
5944 8a7ddc38 bellard
5945 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5946 5fafdf24 ths
        if (!strcmp(se->idstr, idstr) &&
5947 8a7ddc38 bellard
            instance_id == se->instance_id)
5948 8a7ddc38 bellard
            return se;
5949 8a7ddc38 bellard
    }
5950 8a7ddc38 bellard
    return NULL;
5951 8a7ddc38 bellard
}
5952 8a7ddc38 bellard
5953 9596ebb7 pbrook
static int qemu_loadvm_state(QEMUFile *f)
5954 8a7ddc38 bellard
{
5955 8a7ddc38 bellard
    SaveStateEntry *se;
5956 faea38e7 bellard
    int len, ret, instance_id, record_len, version_id;
5957 faea38e7 bellard
    int64_t total_len, end_pos, cur_pos;
5958 8a7ddc38 bellard
    unsigned int v;
5959 8a7ddc38 bellard
    char idstr[256];
5960 3b46e624 ths
5961 8a7ddc38 bellard
    v = qemu_get_be32(f);
5962 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
5963 8a7ddc38 bellard
        goto fail;
5964 8a7ddc38 bellard
    v = qemu_get_be32(f);
5965 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
5966 8a7ddc38 bellard
    fail:
5967 8a7ddc38 bellard
        ret = -1;
5968 8a7ddc38 bellard
        goto the_end;
5969 8a7ddc38 bellard
    }
5970 faea38e7 bellard
    total_len = qemu_get_be64(f);
5971 faea38e7 bellard
    end_pos = total_len + qemu_ftell(f);
5972 b4608c04 bellard
    for(;;) {
5973 faea38e7 bellard
        if (qemu_ftell(f) >= end_pos)
5974 cd4c3e88 bellard
            break;
5975 faea38e7 bellard
        len = qemu_get_byte(f);
5976 ffe8ab83 ths
        qemu_get_buffer(f, (uint8_t *)idstr, len);
5977 8a7ddc38 bellard
        idstr[len] = '\0';
5978 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
5979 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
5980 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
5981 8a7ddc38 bellard
#if 0
5982 5fafdf24 ths
        printf("idstr=%s instance=0x%x version=%d len=%d\n",
5983 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
5984 8a7ddc38 bellard
#endif
5985 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5986 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
5987 8a7ddc38 bellard
        if (!se) {
5988 5fafdf24 ths
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
5989 8a7ddc38 bellard
                    instance_id, idstr);
5990 8a7ddc38 bellard
        } else {
5991 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
5992 8a7ddc38 bellard
            if (ret < 0) {
5993 5fafdf24 ths
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
5994 8a7ddc38 bellard
                        instance_id, idstr);
5995 8a7ddc38 bellard
            }
5996 34865134 bellard
        }
5997 8a7ddc38 bellard
        /* always seek to exact end of record */
5998 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
5999 8a7ddc38 bellard
    }
6000 8a7ddc38 bellard
    ret = 0;
6001 8a7ddc38 bellard
 the_end:
6002 faea38e7 bellard
    return ret;
6003 faea38e7 bellard
}
6004 faea38e7 bellard
6005 faea38e7 bellard
/* device can contain snapshots */
6006 faea38e7 bellard
static int bdrv_can_snapshot(BlockDriverState *bs)
6007 faea38e7 bellard
{
6008 faea38e7 bellard
    return (bs &&
6009 faea38e7 bellard
            !bdrv_is_removable(bs) &&
6010 faea38e7 bellard
            !bdrv_is_read_only(bs));
6011 faea38e7 bellard
}
6012 faea38e7 bellard
6013 faea38e7 bellard
/* device must be snapshots in order to have a reliable snapshot */
6014 faea38e7 bellard
static int bdrv_has_snapshot(BlockDriverState *bs)
6015 faea38e7 bellard
{
6016 faea38e7 bellard
    return (bs &&
6017 faea38e7 bellard
            !bdrv_is_removable(bs) &&
6018 faea38e7 bellard
            !bdrv_is_read_only(bs));
6019 faea38e7 bellard
}
6020 faea38e7 bellard
6021 faea38e7 bellard
static BlockDriverState *get_bs_snapshots(void)
6022 faea38e7 bellard
{
6023 faea38e7 bellard
    BlockDriverState *bs;
6024 faea38e7 bellard
    int i;
6025 faea38e7 bellard
6026 faea38e7 bellard
    if (bs_snapshots)
6027 faea38e7 bellard
        return bs_snapshots;
6028 e4bcb14c ths
    for(i = 0; i <= nb_drives; i++) {
6029 e4bcb14c ths
        bs = drives_table[i].bdrv;
6030 faea38e7 bellard
        if (bdrv_can_snapshot(bs))
6031 faea38e7 bellard
            goto ok;
6032 faea38e7 bellard
    }
6033 faea38e7 bellard
    return NULL;
6034 faea38e7 bellard
 ok:
6035 faea38e7 bellard
    bs_snapshots = bs;
6036 faea38e7 bellard
    return bs;
6037 faea38e7 bellard
}
6038 faea38e7 bellard
6039 faea38e7 bellard
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
6040 faea38e7 bellard
                              const char *name)
6041 faea38e7 bellard
{
6042 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
6043 faea38e7 bellard
    int nb_sns, i, ret;
6044 3b46e624 ths
6045 faea38e7 bellard
    ret = -ENOENT;
6046 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6047 faea38e7 bellard
    if (nb_sns < 0)
6048 faea38e7 bellard
        return ret;
6049 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
6050 faea38e7 bellard
        sn = &sn_tab[i];
6051 faea38e7 bellard
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
6052 faea38e7 bellard
            *sn_info = *sn;
6053 faea38e7 bellard
            ret = 0;
6054 faea38e7 bellard
            break;
6055 faea38e7 bellard
        }
6056 faea38e7 bellard
    }
6057 faea38e7 bellard
    qemu_free(sn_tab);
6058 faea38e7 bellard
    return ret;
6059 faea38e7 bellard
}
6060 faea38e7 bellard
6061 faea38e7 bellard
void do_savevm(const char *name)
6062 faea38e7 bellard
{
6063 faea38e7 bellard
    BlockDriverState *bs, *bs1;
6064 faea38e7 bellard
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
6065 faea38e7 bellard
    int must_delete, ret, i;
6066 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
6067 faea38e7 bellard
    QEMUFile *f;
6068 faea38e7 bellard
    int saved_vm_running;
6069 4c279bdf bellard
#ifdef _WIN32
6070 4c279bdf bellard
    struct _timeb tb;
6071 4c279bdf bellard
#else
6072 faea38e7 bellard
    struct timeval tv;
6073 4c279bdf bellard
#endif
6074 faea38e7 bellard
6075 faea38e7 bellard
    bs = get_bs_snapshots();
6076 faea38e7 bellard
    if (!bs) {
6077 faea38e7 bellard
        term_printf("No block device can accept snapshots\n");
6078 faea38e7 bellard
        return;
6079 faea38e7 bellard
    }
6080 faea38e7 bellard
6081 6192bc37 pbrook
    /* ??? Should this occur after vm_stop?  */
6082 6192bc37 pbrook
    qemu_aio_flush();
6083 6192bc37 pbrook
6084 faea38e7 bellard
    saved_vm_running = vm_running;
6085 faea38e7 bellard
    vm_stop(0);
6086 3b46e624 ths
6087 faea38e7 bellard
    must_delete = 0;
6088 faea38e7 bellard
    if (name) {
6089 faea38e7 bellard
        ret = bdrv_snapshot_find(bs, old_sn, name);
6090 faea38e7 bellard
        if (ret >= 0) {
6091 faea38e7 bellard
            must_delete = 1;
6092 faea38e7 bellard
        }
6093 faea38e7 bellard
    }
6094 faea38e7 bellard
    memset(sn, 0, sizeof(*sn));
6095 faea38e7 bellard
    if (must_delete) {
6096 faea38e7 bellard
        pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
6097 faea38e7 bellard
        pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
6098 faea38e7 bellard
    } else {
6099 faea38e7 bellard
        if (name)
6100 faea38e7 bellard
            pstrcpy(sn->name, sizeof(sn->name), name);
6101 faea38e7 bellard
    }
6102 faea38e7 bellard
6103 faea38e7 bellard
    /* fill auxiliary fields */
6104 4c279bdf bellard
#ifdef _WIN32
6105 4c279bdf bellard
    _ftime(&tb);
6106 4c279bdf bellard
    sn->date_sec = tb.time;
6107 4c279bdf bellard
    sn->date_nsec = tb.millitm * 1000000;
6108 4c279bdf bellard
#else
6109 faea38e7 bellard
    gettimeofday(&tv, NULL);
6110 faea38e7 bellard
    sn->date_sec = tv.tv_sec;
6111 faea38e7 bellard
    sn->date_nsec = tv.tv_usec * 1000;
6112 4c279bdf bellard
#endif
6113 faea38e7 bellard
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
6114 3b46e624 ths
6115 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6116 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
6117 faea38e7 bellard
                    bdrv_get_device_name(bs));
6118 faea38e7 bellard
        goto the_end;
6119 faea38e7 bellard
    }
6120 3b46e624 ths
6121 faea38e7 bellard
    /* save the VM state */
6122 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
6123 faea38e7 bellard
    if (!f) {
6124 faea38e7 bellard
        term_printf("Could not open VM state file\n");
6125 faea38e7 bellard
        goto the_end;
6126 faea38e7 bellard
    }
6127 faea38e7 bellard
    ret = qemu_savevm_state(f);
6128 faea38e7 bellard
    sn->vm_state_size = qemu_ftell(f);
6129 faea38e7 bellard
    qemu_fclose(f);
6130 faea38e7 bellard
    if (ret < 0) {
6131 faea38e7 bellard
        term_printf("Error %d while writing VM\n", ret);
6132 faea38e7 bellard
        goto the_end;
6133 faea38e7 bellard
    }
6134 3b46e624 ths
6135 faea38e7 bellard
    /* create the snapshots */
6136 faea38e7 bellard
6137 e4bcb14c ths
    for(i = 0; i < nb_drives; i++) {
6138 e4bcb14c ths
        bs1 = drives_table[i].bdrv;
6139 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
6140 faea38e7 bellard
            if (must_delete) {
6141 faea38e7 bellard
                ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
6142 faea38e7 bellard
                if (ret < 0) {
6143 faea38e7 bellard
                    term_printf("Error while deleting snapshot on '%s'\n",
6144 faea38e7 bellard
                                bdrv_get_device_name(bs1));
6145 faea38e7 bellard
                }
6146 faea38e7 bellard
            }
6147 faea38e7 bellard
            ret = bdrv_snapshot_create(bs1, sn);
6148 faea38e7 bellard
            if (ret < 0) {
6149 faea38e7 bellard
                term_printf("Error while creating snapshot on '%s'\n",
6150 faea38e7 bellard
                            bdrv_get_device_name(bs1));
6151 faea38e7 bellard
            }
6152 faea38e7 bellard
        }
6153 faea38e7 bellard
    }
6154 faea38e7 bellard
6155 faea38e7 bellard
 the_end:
6156 8a7ddc38 bellard
    if (saved_vm_running)
6157 8a7ddc38 bellard
        vm_start();
6158 faea38e7 bellard
}
6159 faea38e7 bellard
6160 faea38e7 bellard
void do_loadvm(const char *name)
6161 faea38e7 bellard
{
6162 faea38e7 bellard
    BlockDriverState *bs, *bs1;
6163 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
6164 faea38e7 bellard
    QEMUFile *f;
6165 faea38e7 bellard
    int i, ret;
6166 faea38e7 bellard
    int saved_vm_running;
6167 faea38e7 bellard
6168 faea38e7 bellard
    bs = get_bs_snapshots();
6169 faea38e7 bellard
    if (!bs) {
6170 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
6171 faea38e7 bellard
        return;
6172 faea38e7 bellard
    }
6173 3b46e624 ths
6174 6192bc37 pbrook
    /* Flush all IO requests so they don't interfere with the new state.  */
6175 6192bc37 pbrook
    qemu_aio_flush();
6176 6192bc37 pbrook
6177 faea38e7 bellard
    saved_vm_running = vm_running;
6178 faea38e7 bellard
    vm_stop(0);
6179 faea38e7 bellard
6180 e4bcb14c ths
    for(i = 0; i <= nb_drives; i++) {
6181 e4bcb14c ths
        bs1 = drives_table[i].bdrv;
6182 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
6183 faea38e7 bellard
            ret = bdrv_snapshot_goto(bs1, name);
6184 faea38e7 bellard
            if (ret < 0) {
6185 faea38e7 bellard
                if (bs != bs1)
6186 faea38e7 bellard
                    term_printf("Warning: ");
6187 faea38e7 bellard
                switch(ret) {
6188 faea38e7 bellard
                case -ENOTSUP:
6189 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
6190 faea38e7 bellard
                                bdrv_get_device_name(bs1));
6191 faea38e7 bellard
                    break;
6192 faea38e7 bellard
                case -ENOENT:
6193 faea38e7 bellard
                    term_printf("Could not find snapshot '%s' on device '%s'\n",
6194 faea38e7 bellard
                                name, bdrv_get_device_name(bs1));
6195 faea38e7 bellard
                    break;
6196 faea38e7 bellard
                default:
6197 faea38e7 bellard
                    term_printf("Error %d while activating snapshot on '%s'\n",
6198 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
6199 faea38e7 bellard
                    break;
6200 faea38e7 bellard
                }
6201 faea38e7 bellard
                /* fatal on snapshot block device */
6202 faea38e7 bellard
                if (bs == bs1)
6203 faea38e7 bellard
                    goto the_end;
6204 faea38e7 bellard
            }
6205 faea38e7 bellard
        }
6206 faea38e7 bellard
    }
6207 faea38e7 bellard
6208 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
6209 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
6210 faea38e7 bellard
                    bdrv_get_device_name(bs));
6211 faea38e7 bellard
        return;
6212 faea38e7 bellard
    }
6213 3b46e624 ths
6214 faea38e7 bellard
    /* restore the VM state */
6215 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
6216 faea38e7 bellard
    if (!f) {
6217 faea38e7 bellard
        term_printf("Could not open VM state file\n");
6218 faea38e7 bellard
        goto the_end;
6219 faea38e7 bellard
    }
6220 faea38e7 bellard
    ret = qemu_loadvm_state(f);
6221 faea38e7 bellard
    qemu_fclose(f);
6222 faea38e7 bellard
    if (ret < 0) {
6223 faea38e7 bellard
        term_printf("Error %d while loading VM state\n", ret);
6224 faea38e7 bellard
    }
6225 faea38e7 bellard
 the_end:
6226 faea38e7 bellard
    if (saved_vm_running)
6227 faea38e7 bellard
        vm_start();
6228 faea38e7 bellard
}
6229 faea38e7 bellard
6230 faea38e7 bellard
void do_delvm(const char *name)
6231 faea38e7 bellard
{
6232 faea38e7 bellard
    BlockDriverState *bs, *bs1;
6233 faea38e7 bellard
    int i, ret;
6234 faea38e7 bellard
6235 faea38e7 bellard
    bs = get_bs_snapshots();
6236 faea38e7 bellard
    if (!bs) {
6237 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
6238 faea38e7 bellard
        return;
6239 faea38e7 bellard
    }
6240 3b46e624 ths
6241 e4bcb14c ths
    for(i = 0; i <= nb_drives; i++) {
6242 e4bcb14c ths
        bs1 = drives_table[i].bdrv;
6243 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
6244 faea38e7 bellard
            ret = bdrv_snapshot_delete(bs1, name);
6245 faea38e7 bellard
            if (ret < 0) {
6246 faea38e7 bellard
                if (ret == -ENOTSUP)
6247 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
6248 faea38e7 bellard
                                bdrv_get_device_name(bs1));
6249 faea38e7 bellard
                else
6250 faea38e7 bellard
                    term_printf("Error %d while deleting snapshot on '%s'\n",
6251 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
6252 faea38e7 bellard
            }
6253 faea38e7 bellard
        }
6254 faea38e7 bellard
    }
6255 faea38e7 bellard
}
6256 faea38e7 bellard
6257 faea38e7 bellard
void do_info_snapshots(void)
6258 faea38e7 bellard
{
6259 faea38e7 bellard
    BlockDriverState *bs, *bs1;
6260 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
6261 faea38e7 bellard
    int nb_sns, i;
6262 faea38e7 bellard
    char buf[256];
6263 faea38e7 bellard
6264 faea38e7 bellard
    bs = get_bs_snapshots();
6265 faea38e7 bellard
    if (!bs) {
6266 faea38e7 bellard
        term_printf("No available block device supports snapshots\n");
6267 faea38e7 bellard
        return;
6268 faea38e7 bellard
    }
6269 faea38e7 bellard
    term_printf("Snapshot devices:");
6270 e4bcb14c ths
    for(i = 0; i <= nb_drives; i++) {
6271 e4bcb14c ths
        bs1 = drives_table[i].bdrv;
6272 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
6273 faea38e7 bellard
            if (bs == bs1)
6274 faea38e7 bellard
                term_printf(" %s", bdrv_get_device_name(bs1));
6275 faea38e7 bellard
        }
6276 faea38e7 bellard
    }
6277 faea38e7 bellard
    term_printf("\n");
6278 faea38e7 bellard
6279 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
6280 faea38e7 bellard
    if (nb_sns < 0) {
6281 faea38e7 bellard
        term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
6282 faea38e7 bellard
        return;
6283 faea38e7 bellard
    }
6284 faea38e7 bellard
    term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
6285 faea38e7 bellard
    term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
6286 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
6287 faea38e7 bellard
        sn = &sn_tab[i];
6288 faea38e7 bellard
        term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
6289 faea38e7 bellard
    }
6290 faea38e7 bellard
    qemu_free(sn_tab);
6291 8a7ddc38 bellard
}
6292 8a7ddc38 bellard
6293 8a7ddc38 bellard
/***********************************************************/
6294 8a7ddc38 bellard
/* cpu save/restore */
6295 8a7ddc38 bellard
6296 8a7ddc38 bellard
#if defined(TARGET_I386)
6297 8a7ddc38 bellard
6298 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
6299 8a7ddc38 bellard
{
6300 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
6301 20f32282 bellard
    qemu_put_betl(f, dt->base);
6302 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
6303 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
6304 8a7ddc38 bellard
}
6305 8a7ddc38 bellard
6306 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
6307 8a7ddc38 bellard
{
6308 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
6309 20f32282 bellard
    dt->base = qemu_get_betl(f);
6310 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
6311 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
6312 8a7ddc38 bellard
}
6313 8a7ddc38 bellard
6314 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
6315 8a7ddc38 bellard
{
6316 8a7ddc38 bellard
    CPUState *env = opaque;
6317 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
6318 8a7ddc38 bellard
    uint32_t hflags;
6319 8a7ddc38 bellard
    int i;
6320 3b46e624 ths
6321 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
6322 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
6323 20f32282 bellard
    qemu_put_betls(f, &env->eip);
6324 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
6325 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
6326 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
6327 3b46e624 ths
6328 8a7ddc38 bellard
    /* FPU */
6329 8a7ddc38 bellard
    fpuc = env->fpuc;
6330 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
6331 8a7ddc38 bellard
    fptag = 0;
6332 664e0f19 bellard
    for(i = 0; i < 8; i++) {
6333 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
6334 8a7ddc38 bellard
    }
6335 3b46e624 ths
6336 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
6337 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
6338 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
6339 8a7ddc38 bellard
6340 664e0f19 bellard
#ifdef USE_X86LDOUBLE
6341 664e0f19 bellard
    fpregs_format = 0;
6342 664e0f19 bellard
#else
6343 664e0f19 bellard
    fpregs_format = 1;
6344 664e0f19 bellard
#endif
6345 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
6346 3b46e624 ths
6347 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
6348 664e0f19 bellard
#ifdef USE_X86LDOUBLE
6349 8636b5d8 bellard
        {
6350 8636b5d8 bellard
            uint64_t mant;
6351 8636b5d8 bellard
            uint16_t exp;
6352 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
6353 8636b5d8 bellard
               contains the MMX register */
6354 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
6355 8636b5d8 bellard
            qemu_put_be64(f, mant);
6356 8636b5d8 bellard
            qemu_put_be16(f, exp);
6357 8636b5d8 bellard
        }
6358 664e0f19 bellard
#else
6359 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
6360 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
6361 664e0f19 bellard
           problems if the image is restored on a CPU where long
6362 664e0f19 bellard
           doubles are used instead. */
6363 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
6364 664e0f19 bellard
#endif
6365 8a7ddc38 bellard
    }
6366 8a7ddc38 bellard
6367 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
6368 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
6369 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
6370 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
6371 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
6372 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
6373 3b46e624 ths
6374 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
6375 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
6376 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
6377 3b46e624 ths
6378 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
6379 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
6380 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
6381 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
6382 3b46e624 ths
6383 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
6384 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
6385 8a7ddc38 bellard
6386 8a7ddc38 bellard
    /* MMU */
6387 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
6388 02536f8b bellard
6389 664e0f19 bellard
    /* XMM */
6390 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
6391 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
6392 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
6393 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
6394 02536f8b bellard
    }
6395 02536f8b bellard
6396 664e0f19 bellard
#ifdef TARGET_X86_64
6397 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
6398 02536f8b bellard
    qemu_put_be64s(f, &env->star);
6399 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
6400 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
6401 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
6402 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
6403 02536f8b bellard
#endif
6404 3b21e03e bellard
    qemu_put_be32s(f, &env->smbase);
6405 8a7ddc38 bellard
}
6406 8a7ddc38 bellard
6407 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
6408 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
6409 664e0f19 bellard
union x86_longdouble {
6410 664e0f19 bellard
    uint64_t mant;
6411 664e0f19 bellard
    uint16_t exp;
6412 664e0f19 bellard
};
6413 664e0f19 bellard
6414 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
6415 664e0f19 bellard
#define EXPBIAS1 1023
6416 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
6417 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
6418 664e0f19 bellard
6419 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
6420 664e0f19 bellard
{
6421 664e0f19 bellard
    int e;
6422 664e0f19 bellard
    /* mantissa */
6423 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
6424 664e0f19 bellard
    /* exponent + sign */
6425 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
6426 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
6427 664e0f19 bellard
    p->exp = e;
6428 664e0f19 bellard
}
6429 8636b5d8 bellard
#endif
6430 664e0f19 bellard
6431 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6432 8a7ddc38 bellard
{
6433 8a7ddc38 bellard
    CPUState *env = opaque;
6434 664e0f19 bellard
    int i, guess_mmx;
6435 8a7ddc38 bellard
    uint32_t hflags;
6436 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
6437 8a7ddc38 bellard
6438 3b21e03e bellard
    if (version_id != 3 && version_id != 4)
6439 8a7ddc38 bellard
        return -EINVAL;
6440 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
6441 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
6442 20f32282 bellard
    qemu_get_betls(f, &env->eip);
6443 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
6444 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
6445 8a7ddc38 bellard
6446 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
6447 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
6448 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
6449 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
6450 3b46e624 ths
6451 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
6452 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
6453 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
6454 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
6455 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
6456 8a7ddc38 bellard
        uint64_t mant;
6457 8a7ddc38 bellard
        uint16_t exp;
6458 3b46e624 ths
6459 664e0f19 bellard
        switch(fpregs_format) {
6460 664e0f19 bellard
        case 0:
6461 664e0f19 bellard
            mant = qemu_get_be64(f);
6462 664e0f19 bellard
            exp = qemu_get_be16(f);
6463 664e0f19 bellard
#ifdef USE_X86LDOUBLE
6464 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
6465 664e0f19 bellard
#else
6466 664e0f19 bellard
            /* difficult case */
6467 664e0f19 bellard
            if (guess_mmx)
6468 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
6469 664e0f19 bellard
            else
6470 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
6471 664e0f19 bellard
#endif
6472 664e0f19 bellard
            break;
6473 664e0f19 bellard
        case 1:
6474 664e0f19 bellard
            mant = qemu_get_be64(f);
6475 664e0f19 bellard
#ifdef USE_X86LDOUBLE
6476 8636b5d8 bellard
            {
6477 8636b5d8 bellard
                union x86_longdouble *p;
6478 8636b5d8 bellard
                /* difficult case */
6479 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
6480 8636b5d8 bellard
                if (guess_mmx) {
6481 8636b5d8 bellard
                    p->mant = mant;
6482 8636b5d8 bellard
                    p->exp = 0xffff;
6483 8636b5d8 bellard
                } else {
6484 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
6485 8636b5d8 bellard
                }
6486 664e0f19 bellard
            }
6487 664e0f19 bellard
#else
6488 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
6489 3b46e624 ths
#endif
6490 664e0f19 bellard
            break;
6491 664e0f19 bellard
        default:
6492 664e0f19 bellard
            return -EINVAL;
6493 664e0f19 bellard
        }
6494 8a7ddc38 bellard
    }
6495 8a7ddc38 bellard
6496 8a7ddc38 bellard
    env->fpuc = fpuc;
6497 7a0e1f41 bellard
    /* XXX: restore FPU round state */
6498 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
6499 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
6500 664e0f19 bellard
    fptag ^= 0xff;
6501 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
6502 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
6503 8a7ddc38 bellard
    }
6504 3b46e624 ths
6505 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
6506 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
6507 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
6508 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
6509 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
6510 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
6511 3b46e624 ths
6512 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
6513 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
6514 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
6515 3b46e624 ths
6516 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
6517 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
6518 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
6519 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
6520 3b46e624 ths
6521 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
6522 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
6523 8a7ddc38 bellard
6524 8a7ddc38 bellard
    /* MMU */
6525 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
6526 8a7ddc38 bellard
6527 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
6528 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
6529 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
6530 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
6531 02536f8b bellard
    }
6532 02536f8b bellard
6533 664e0f19 bellard
#ifdef TARGET_X86_64
6534 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
6535 02536f8b bellard
    qemu_get_be64s(f, &env->star);
6536 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
6537 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
6538 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
6539 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
6540 02536f8b bellard
#endif
6541 5fafdf24 ths
    if (version_id >= 4)
6542 3b21e03e bellard
        qemu_get_be32s(f, &env->smbase);
6543 02536f8b bellard
6544 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
6545 8a7ddc38 bellard
    env->hflags = hflags;
6546 8a7ddc38 bellard
    tlb_flush(env, 1);
6547 8a7ddc38 bellard
    return 0;
6548 8a7ddc38 bellard
}
6549 8a7ddc38 bellard
6550 a541f297 bellard
#elif defined(TARGET_PPC)
6551 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
6552 a541f297 bellard
{
6553 a541f297 bellard
}
6554 a541f297 bellard
6555 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6556 a541f297 bellard
{
6557 a541f297 bellard
    return 0;
6558 a541f297 bellard
}
6559 6af0bf9c bellard
6560 6af0bf9c bellard
#elif defined(TARGET_MIPS)
6561 6af0bf9c bellard
void cpu_save(QEMUFile *f, void *opaque)
6562 6af0bf9c bellard
{
6563 6af0bf9c bellard
}
6564 6af0bf9c bellard
6565 6af0bf9c bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6566 6af0bf9c bellard
{
6567 6af0bf9c bellard
    return 0;
6568 6af0bf9c bellard
}
6569 6af0bf9c bellard
6570 e95c8d51 bellard
#elif defined(TARGET_SPARC)
6571 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
6572 e95c8d51 bellard
{
6573 e80cfcfc bellard
    CPUState *env = opaque;
6574 e80cfcfc bellard
    int i;
6575 e80cfcfc bellard
    uint32_t tmp;
6576 e80cfcfc bellard
6577 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6578 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
6579 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6580 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
6581 e80cfcfc bellard
6582 e80cfcfc bellard
    /* FPU */
6583 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6584 4fa5d772 bellard
        union {
6585 1bdb68ea bellard
            float32 f;
6586 1bdb68ea bellard
            uint32_t i;
6587 4fa5d772 bellard
        } u;
6588 4fa5d772 bellard
        u.f = env->fpr[i];
6589 1bdb68ea bellard
        qemu_put_be32(f, u.i);
6590 4fa5d772 bellard
    }
6591 4fa5d772 bellard
6592 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
6593 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
6594 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
6595 e80cfcfc bellard
    tmp = GET_PSR(env);
6596 4fa5d772 bellard
    qemu_put_be32(f, tmp);
6597 3475187d bellard
    qemu_put_betls(f, &env->fsr);
6598 3475187d bellard
    qemu_put_betls(f, &env->tbr);
6599 3475187d bellard
#ifndef TARGET_SPARC64
6600 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
6601 e80cfcfc bellard
    /* MMU */
6602 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6603 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
6604 3475187d bellard
#endif
6605 e95c8d51 bellard
}
6606 e95c8d51 bellard
6607 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6608 e95c8d51 bellard
{
6609 e80cfcfc bellard
    CPUState *env = opaque;
6610 e80cfcfc bellard
    int i;
6611 e80cfcfc bellard
    uint32_t tmp;
6612 e80cfcfc bellard
6613 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6614 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
6615 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6616 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
6617 e80cfcfc bellard
6618 e80cfcfc bellard
    /* FPU */
6619 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6620 4fa5d772 bellard
        union {
6621 1bdb68ea bellard
            float32 f;
6622 1bdb68ea bellard
            uint32_t i;
6623 4fa5d772 bellard
        } u;
6624 1bdb68ea bellard
        u.i = qemu_get_be32(f);
6625 4fa5d772 bellard
        env->fpr[i] = u.f;
6626 4fa5d772 bellard
    }
6627 4fa5d772 bellard
6628 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
6629 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
6630 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
6631 4fa5d772 bellard
    tmp = qemu_get_be32(f);
6632 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
6633 4fa5d772 bellard
                     correctly updated */
6634 e80cfcfc bellard
    PUT_PSR(env, tmp);
6635 3475187d bellard
    qemu_get_betls(f, &env->fsr);
6636 3475187d bellard
    qemu_get_betls(f, &env->tbr);
6637 3475187d bellard
#ifndef TARGET_SPARC64
6638 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
6639 e80cfcfc bellard
    /* MMU */
6640 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6641 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
6642 3475187d bellard
#endif
6643 e80cfcfc bellard
    tlb_flush(env, 1);
6644 e95c8d51 bellard
    return 0;
6645 e95c8d51 bellard
}
6646 b5ff1b31 bellard
6647 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6648 b5ff1b31 bellard
6649 b5ff1b31 bellard
void cpu_save(QEMUFile *f, void *opaque)
6650 b5ff1b31 bellard
{
6651 aa941b94 balrog
    int i;
6652 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6653 aa941b94 balrog
6654 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6655 aa941b94 balrog
        qemu_put_be32(f, env->regs[i]);
6656 aa941b94 balrog
    }
6657 aa941b94 balrog
    qemu_put_be32(f, cpsr_read(env));
6658 aa941b94 balrog
    qemu_put_be32(f, env->spsr);
6659 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6660 aa941b94 balrog
        qemu_put_be32(f, env->banked_spsr[i]);
6661 aa941b94 balrog
        qemu_put_be32(f, env->banked_r13[i]);
6662 aa941b94 balrog
        qemu_put_be32(f, env->banked_r14[i]);
6663 aa941b94 balrog
    }
6664 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6665 aa941b94 balrog
        qemu_put_be32(f, env->usr_regs[i]);
6666 aa941b94 balrog
        qemu_put_be32(f, env->fiq_regs[i]);
6667 aa941b94 balrog
    }
6668 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cpuid);
6669 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cachetype);
6670 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_sys);
6671 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_coproc);
6672 610c3c8a balrog
    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
6673 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c2_base0);
6674 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c2_base1);
6675 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c2_mask);
6676 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_data);
6677 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_insn);
6678 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c3);
6679 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_insn);
6680 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_data);
6681 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6682 aa941b94 balrog
        qemu_put_be32(f, env->cp15.c6_region[i]);
6683 aa941b94 balrog
    }
6684 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_insn);
6685 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_data);
6686 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_insn);
6687 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_data);
6688 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_fcse);
6689 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_context);
6690 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c13_tls1);
6691 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c13_tls2);
6692 9ee6e8bb pbrook
    qemu_put_be32(f, env->cp15.c13_tls3);
6693 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c15_cpar);
6694 aa941b94 balrog
6695 aa941b94 balrog
    qemu_put_be32(f, env->features);
6696 aa941b94 balrog
6697 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6698 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6699 aa941b94 balrog
            CPU_DoubleU u;
6700 aa941b94 balrog
            u.d = env->vfp.regs[i];
6701 aa941b94 balrog
            qemu_put_be32(f, u.l.upper);
6702 aa941b94 balrog
            qemu_put_be32(f, u.l.lower);
6703 aa941b94 balrog
        }
6704 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6705 aa941b94 balrog
            qemu_put_be32(f, env->vfp.xregs[i]);
6706 aa941b94 balrog
        }
6707 aa941b94 balrog
6708 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6709 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_len);
6710 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_stride);
6711 9ee6e8bb pbrook
6712 9ee6e8bb pbrook
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
6713 9ee6e8bb pbrook
            for (i = 16;  i < 32; i++) {
6714 9ee6e8bb pbrook
                CPU_DoubleU u;
6715 9ee6e8bb pbrook
                u.d = env->vfp.regs[i];
6716 9ee6e8bb pbrook
                qemu_put_be32(f, u.l.upper);
6717 9ee6e8bb pbrook
                qemu_put_be32(f, u.l.lower);
6718 9ee6e8bb pbrook
            }
6719 9ee6e8bb pbrook
        }
6720 aa941b94 balrog
    }
6721 aa941b94 balrog
6722 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6723 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6724 aa941b94 balrog
            qemu_put_be64(f, env->iwmmxt.regs[i]);
6725 aa941b94 balrog
        }
6726 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6727 aa941b94 balrog
            qemu_put_be32(f, env->iwmmxt.cregs[i]);
6728 aa941b94 balrog
        }
6729 aa941b94 balrog
    }
6730 9ee6e8bb pbrook
6731 9ee6e8bb pbrook
    if (arm_feature(env, ARM_FEATURE_M)) {
6732 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.other_sp);
6733 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.vecbase);
6734 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.basepri);
6735 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.control);
6736 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.current_sp);
6737 9ee6e8bb pbrook
        qemu_put_be32(f, env->v7m.exception);
6738 9ee6e8bb pbrook
    }
6739 b5ff1b31 bellard
}
6740 b5ff1b31 bellard
6741 b5ff1b31 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6742 b5ff1b31 bellard
{
6743 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6744 aa941b94 balrog
    int i;
6745 aa941b94 balrog
6746 9ee6e8bb pbrook
    if (version_id != ARM_CPU_SAVE_VERSION)
6747 aa941b94 balrog
        return -EINVAL;
6748 aa941b94 balrog
6749 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6750 aa941b94 balrog
        env->regs[i] = qemu_get_be32(f);
6751 aa941b94 balrog
    }
6752 aa941b94 balrog
    cpsr_write(env, qemu_get_be32(f), 0xffffffff);
6753 aa941b94 balrog
    env->spsr = qemu_get_be32(f);
6754 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6755 aa941b94 balrog
        env->banked_spsr[i] = qemu_get_be32(f);
6756 aa941b94 balrog
        env->banked_r13[i] = qemu_get_be32(f);
6757 aa941b94 balrog
        env->banked_r14[i] = qemu_get_be32(f);
6758 aa941b94 balrog
    }
6759 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6760 aa941b94 balrog
        env->usr_regs[i] = qemu_get_be32(f);
6761 aa941b94 balrog
        env->fiq_regs[i] = qemu_get_be32(f);
6762 aa941b94 balrog
    }
6763 aa941b94 balrog
    env->cp15.c0_cpuid = qemu_get_be32(f);
6764 aa941b94 balrog
    env->cp15.c0_cachetype = qemu_get_be32(f);
6765 aa941b94 balrog
    env->cp15.c1_sys = qemu_get_be32(f);
6766 aa941b94 balrog
    env->cp15.c1_coproc = qemu_get_be32(f);
6767 610c3c8a balrog
    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
6768 9ee6e8bb pbrook
    env->cp15.c2_base0 = qemu_get_be32(f);
6769 9ee6e8bb pbrook
    env->cp15.c2_base1 = qemu_get_be32(f);
6770 9ee6e8bb pbrook
    env->cp15.c2_mask = qemu_get_be32(f);
6771 aa941b94 balrog
    env->cp15.c2_data = qemu_get_be32(f);
6772 aa941b94 balrog
    env->cp15.c2_insn = qemu_get_be32(f);
6773 aa941b94 balrog
    env->cp15.c3 = qemu_get_be32(f);
6774 aa941b94 balrog
    env->cp15.c5_insn = qemu_get_be32(f);
6775 aa941b94 balrog
    env->cp15.c5_data = qemu_get_be32(f);
6776 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6777 aa941b94 balrog
        env->cp15.c6_region[i] = qemu_get_be32(f);
6778 aa941b94 balrog
    }
6779 aa941b94 balrog
    env->cp15.c6_insn = qemu_get_be32(f);
6780 aa941b94 balrog
    env->cp15.c6_data = qemu_get_be32(f);
6781 aa941b94 balrog
    env->cp15.c9_insn = qemu_get_be32(f);
6782 aa941b94 balrog
    env->cp15.c9_data = qemu_get_be32(f);
6783 aa941b94 balrog
    env->cp15.c13_fcse = qemu_get_be32(f);
6784 aa941b94 balrog
    env->cp15.c13_context = qemu_get_be32(f);
6785 9ee6e8bb pbrook
    env->cp15.c13_tls1 = qemu_get_be32(f);
6786 9ee6e8bb pbrook
    env->cp15.c13_tls2 = qemu_get_be32(f);
6787 9ee6e8bb pbrook
    env->cp15.c13_tls3 = qemu_get_be32(f);
6788 aa941b94 balrog
    env->cp15.c15_cpar = qemu_get_be32(f);
6789 aa941b94 balrog
6790 aa941b94 balrog
    env->features = qemu_get_be32(f);
6791 aa941b94 balrog
6792 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6793 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6794 aa941b94 balrog
            CPU_DoubleU u;
6795 aa941b94 balrog
            u.l.upper = qemu_get_be32(f);
6796 aa941b94 balrog
            u.l.lower = qemu_get_be32(f);
6797 aa941b94 balrog
            env->vfp.regs[i] = u.d;
6798 aa941b94 balrog
        }
6799 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6800 aa941b94 balrog
            env->vfp.xregs[i] = qemu_get_be32(f);
6801 aa941b94 balrog
        }
6802 aa941b94 balrog
6803 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6804 aa941b94 balrog
        env->vfp.vec_len = qemu_get_be32(f);
6805 aa941b94 balrog
        env->vfp.vec_stride = qemu_get_be32(f);
6806 9ee6e8bb pbrook
6807 9ee6e8bb pbrook
        if (arm_feature(env, ARM_FEATURE_VFP3)) {
6808 9ee6e8bb pbrook
            for (i = 0;  i < 16; i++) {
6809 9ee6e8bb pbrook
                CPU_DoubleU u;
6810 9ee6e8bb pbrook
                u.l.upper = qemu_get_be32(f);
6811 9ee6e8bb pbrook
                u.l.lower = qemu_get_be32(f);
6812 9ee6e8bb pbrook
                env->vfp.regs[i] = u.d;
6813 9ee6e8bb pbrook
            }
6814 9ee6e8bb pbrook
        }
6815 aa941b94 balrog
    }
6816 aa941b94 balrog
6817 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6818 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6819 aa941b94 balrog
            env->iwmmxt.regs[i] = qemu_get_be64(f);
6820 aa941b94 balrog
        }
6821 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6822 aa941b94 balrog
            env->iwmmxt.cregs[i] = qemu_get_be32(f);
6823 aa941b94 balrog
        }
6824 aa941b94 balrog
    }
6825 aa941b94 balrog
6826 9ee6e8bb pbrook
    if (arm_feature(env, ARM_FEATURE_M)) {
6827 9ee6e8bb pbrook
        env->v7m.other_sp = qemu_get_be32(f);
6828 9ee6e8bb pbrook
        env->v7m.vecbase = qemu_get_be32(f);
6829 9ee6e8bb pbrook
        env->v7m.basepri = qemu_get_be32(f);
6830 9ee6e8bb pbrook
        env->v7m.control = qemu_get_be32(f);
6831 9ee6e8bb pbrook
        env->v7m.current_sp = qemu_get_be32(f);
6832 9ee6e8bb pbrook
        env->v7m.exception = qemu_get_be32(f);
6833 9ee6e8bb pbrook
    }
6834 9ee6e8bb pbrook
6835 b5ff1b31 bellard
    return 0;
6836 b5ff1b31 bellard
}
6837 b5ff1b31 bellard
6838 8a7ddc38 bellard
#else
6839 8a7ddc38 bellard
6840 6dfd59d6 bellard
//#warning No CPU save/restore functions
6841 8a7ddc38 bellard
6842 8a7ddc38 bellard
#endif
6843 8a7ddc38 bellard
6844 8a7ddc38 bellard
/***********************************************************/
6845 8a7ddc38 bellard
/* ram save/restore */
6846 8a7ddc38 bellard
6847 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6848 8a7ddc38 bellard
{
6849 8a7ddc38 bellard
    int v;
6850 8a7ddc38 bellard
6851 8a7ddc38 bellard
    v = qemu_get_byte(f);
6852 8a7ddc38 bellard
    switch(v) {
6853 8a7ddc38 bellard
    case 0:
6854 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
6855 8a7ddc38 bellard
            return -EIO;
6856 8a7ddc38 bellard
        break;
6857 8a7ddc38 bellard
    case 1:
6858 8a7ddc38 bellard
        v = qemu_get_byte(f);
6859 8a7ddc38 bellard
        memset(buf, v, len);
6860 8a7ddc38 bellard
        break;
6861 8a7ddc38 bellard
    default:
6862 8a7ddc38 bellard
        return -EINVAL;
6863 8a7ddc38 bellard
    }
6864 8a7ddc38 bellard
    return 0;
6865 8a7ddc38 bellard
}
6866 8a7ddc38 bellard
6867 c88676f8 bellard
static int ram_load_v1(QEMUFile *f, void *opaque)
6868 c88676f8 bellard
{
6869 c88676f8 bellard
    int i, ret;
6870 c88676f8 bellard
6871 c88676f8 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6872 c88676f8 bellard
        return -EINVAL;
6873 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6874 c88676f8 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6875 c88676f8 bellard
        if (ret)
6876 c88676f8 bellard
            return ret;
6877 c88676f8 bellard
    }
6878 c88676f8 bellard
    return 0;
6879 c88676f8 bellard
}
6880 c88676f8 bellard
6881 c88676f8 bellard
#define BDRV_HASH_BLOCK_SIZE 1024
6882 c88676f8 bellard
#define IOBUF_SIZE 4096
6883 c88676f8 bellard
#define RAM_CBLOCK_MAGIC 0xfabe
6884 c88676f8 bellard
6885 c88676f8 bellard
typedef struct RamCompressState {
6886 c88676f8 bellard
    z_stream zstream;
6887 c88676f8 bellard
    QEMUFile *f;
6888 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6889 c88676f8 bellard
} RamCompressState;
6890 c88676f8 bellard
6891 c88676f8 bellard
static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6892 c88676f8 bellard
{
6893 c88676f8 bellard
    int ret;
6894 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6895 c88676f8 bellard
    s->f = f;
6896 c88676f8 bellard
    ret = deflateInit2(&s->zstream, 1,
6897 5fafdf24 ths
                       Z_DEFLATED, 15,
6898 c88676f8 bellard
                       9, Z_DEFAULT_STRATEGY);
6899 c88676f8 bellard
    if (ret != Z_OK)
6900 c88676f8 bellard
        return -1;
6901 c88676f8 bellard
    s->zstream.avail_out = IOBUF_SIZE;
6902 c88676f8 bellard
    s->zstream.next_out = s->buf;
6903 c88676f8 bellard
    return 0;
6904 c88676f8 bellard
}
6905 c88676f8 bellard
6906 c88676f8 bellard
static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6907 c88676f8 bellard
{
6908 c88676f8 bellard
    qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6909 c88676f8 bellard
    qemu_put_be16(s->f, len);
6910 c88676f8 bellard
    qemu_put_buffer(s->f, buf, len);
6911 c88676f8 bellard
}
6912 c88676f8 bellard
6913 c88676f8 bellard
static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6914 c88676f8 bellard
{
6915 c88676f8 bellard
    int ret;
6916 c88676f8 bellard
6917 c88676f8 bellard
    s->zstream.avail_in = len;
6918 c88676f8 bellard
    s->zstream.next_in = (uint8_t *)buf;
6919 c88676f8 bellard
    while (s->zstream.avail_in > 0) {
6920 c88676f8 bellard
        ret = deflate(&s->zstream, Z_NO_FLUSH);
6921 c88676f8 bellard
        if (ret != Z_OK)
6922 c88676f8 bellard
            return -1;
6923 c88676f8 bellard
        if (s->zstream.avail_out == 0) {
6924 c88676f8 bellard
            ram_put_cblock(s, s->buf, IOBUF_SIZE);
6925 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6926 c88676f8 bellard
            s->zstream.next_out = s->buf;
6927 c88676f8 bellard
        }
6928 c88676f8 bellard
    }
6929 c88676f8 bellard
    return 0;
6930 c88676f8 bellard
}
6931 c88676f8 bellard
6932 c88676f8 bellard
static void ram_compress_close(RamCompressState *s)
6933 c88676f8 bellard
{
6934 c88676f8 bellard
    int len, ret;
6935 c88676f8 bellard
6936 c88676f8 bellard
    /* compress last bytes */
6937 c88676f8 bellard
    for(;;) {
6938 c88676f8 bellard
        ret = deflate(&s->zstream, Z_FINISH);
6939 c88676f8 bellard
        if (ret == Z_OK || ret == Z_STREAM_END) {
6940 c88676f8 bellard
            len = IOBUF_SIZE - s->zstream.avail_out;
6941 c88676f8 bellard
            if (len > 0) {
6942 c88676f8 bellard
                ram_put_cblock(s, s->buf, len);
6943 c88676f8 bellard
            }
6944 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6945 c88676f8 bellard
            s->zstream.next_out = s->buf;
6946 c88676f8 bellard
            if (ret == Z_STREAM_END)
6947 c88676f8 bellard
                break;
6948 c88676f8 bellard
        } else {
6949 c88676f8 bellard
            goto fail;
6950 c88676f8 bellard
        }
6951 c88676f8 bellard
    }
6952 c88676f8 bellard
fail:
6953 c88676f8 bellard
    deflateEnd(&s->zstream);
6954 c88676f8 bellard
}
6955 c88676f8 bellard
6956 c88676f8 bellard
typedef struct RamDecompressState {
6957 c88676f8 bellard
    z_stream zstream;
6958 c88676f8 bellard
    QEMUFile *f;
6959 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6960 c88676f8 bellard
} RamDecompressState;
6961 c88676f8 bellard
6962 c88676f8 bellard
static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6963 c88676f8 bellard
{
6964 c88676f8 bellard
    int ret;
6965 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6966 c88676f8 bellard
    s->f = f;
6967 c88676f8 bellard
    ret = inflateInit(&s->zstream);
6968 c88676f8 bellard
    if (ret != Z_OK)
6969 c88676f8 bellard
        return -1;
6970 c88676f8 bellard
    return 0;
6971 c88676f8 bellard
}
6972 c88676f8 bellard
6973 c88676f8 bellard
static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6974 c88676f8 bellard
{
6975 c88676f8 bellard
    int ret, clen;
6976 c88676f8 bellard
6977 c88676f8 bellard
    s->zstream.avail_out = len;
6978 c88676f8 bellard
    s->zstream.next_out = buf;
6979 c88676f8 bellard
    while (s->zstream.avail_out > 0) {
6980 c88676f8 bellard
        if (s->zstream.avail_in == 0) {
6981 c88676f8 bellard
            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6982 c88676f8 bellard
                return -1;
6983 c88676f8 bellard
            clen = qemu_get_be16(s->f);
6984 c88676f8 bellard
            if (clen > IOBUF_SIZE)
6985 c88676f8 bellard
                return -1;
6986 c88676f8 bellard
            qemu_get_buffer(s->f, s->buf, clen);
6987 c88676f8 bellard
            s->zstream.avail_in = clen;
6988 c88676f8 bellard
            s->zstream.next_in = s->buf;
6989 c88676f8 bellard
        }
6990 c88676f8 bellard
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6991 c88676f8 bellard
        if (ret != Z_OK && ret != Z_STREAM_END) {
6992 c88676f8 bellard
            return -1;
6993 c88676f8 bellard
        }
6994 c88676f8 bellard
    }
6995 c88676f8 bellard
    return 0;
6996 c88676f8 bellard
}
6997 c88676f8 bellard
6998 c88676f8 bellard
static void ram_decompress_close(RamDecompressState *s)
6999 c88676f8 bellard
{
7000 c88676f8 bellard
    inflateEnd(&s->zstream);
7001 c88676f8 bellard
}
7002 c88676f8 bellard
7003 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
7004 8a7ddc38 bellard
{
7005 8a7ddc38 bellard
    int i;
7006 c88676f8 bellard
    RamCompressState s1, *s = &s1;
7007 c88676f8 bellard
    uint8_t buf[10];
7008 3b46e624 ths
7009 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
7010 c88676f8 bellard
    if (ram_compress_open(s, f) < 0)
7011 c88676f8 bellard
        return;
7012 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
7013 c88676f8 bellard
#if 0
7014 c88676f8 bellard
        if (tight_savevm_enabled) {
7015 c88676f8 bellard
            int64_t sector_num;
7016 c88676f8 bellard
            int j;
7017 c88676f8 bellard

7018 c88676f8 bellard
            /* find if the memory block is available on a virtual
7019 c88676f8 bellard
               block device */
7020 c88676f8 bellard
            sector_num = -1;
7021 e4bcb14c ths
            for(j = 0; j < nb_drives; j++) {
7022 e4bcb14c ths
                sector_num = bdrv_hash_find(drives_table[j].bdrv,
7023 e4bcb14c ths
                                            phys_ram_base + i,
7024 e4bcb14c ths
                                            BDRV_HASH_BLOCK_SIZE);
7025 e4bcb14c ths
                if (sector_num >= 0)
7026 e4bcb14c ths
                    break;
7027 c88676f8 bellard
            }
7028 e4bcb14c ths
            if (j == nb_drives)
7029 c88676f8 bellard
                goto normal_compress;
7030 c88676f8 bellard
            buf[0] = 1;
7031 c88676f8 bellard
            buf[1] = j;
7032 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
7033 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
7034 5fafdf24 ths
        } else
7035 c88676f8 bellard
#endif
7036 c88676f8 bellard
        {
7037 c88676f8 bellard
            //        normal_compress:
7038 c88676f8 bellard
            buf[0] = 0;
7039 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
7040 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
7041 c88676f8 bellard
        }
7042 8a7ddc38 bellard
    }
7043 c88676f8 bellard
    ram_compress_close(s);
7044 8a7ddc38 bellard
}
7045 8a7ddc38 bellard
7046 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
7047 8a7ddc38 bellard
{
7048 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
7049 c88676f8 bellard
    uint8_t buf[10];
7050 c88676f8 bellard
    int i;
7051 8a7ddc38 bellard
7052 c88676f8 bellard
    if (version_id == 1)
7053 c88676f8 bellard
        return ram_load_v1(f, opaque);
7054 c88676f8 bellard
    if (version_id != 2)
7055 8a7ddc38 bellard
        return -EINVAL;
7056 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
7057 8a7ddc38 bellard
        return -EINVAL;
7058 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
7059 c88676f8 bellard
        return -EINVAL;
7060 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
7061 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
7062 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
7063 c88676f8 bellard
            goto error;
7064 c88676f8 bellard
        }
7065 c88676f8 bellard
        if (buf[0] == 0) {
7066 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
7067 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
7068 c88676f8 bellard
                goto error;
7069 c88676f8 bellard
            }
7070 5fafdf24 ths
        } else
7071 c88676f8 bellard
#if 0
7072 c88676f8 bellard
        if (buf[0] == 1) {
7073 c88676f8 bellard
            int bs_index;
7074 c88676f8 bellard
            int64_t sector_num;
7075 c88676f8 bellard

7076 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
7077 c88676f8 bellard
            bs_index = buf[1];
7078 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
7079 e4bcb14c ths
            if (bs_index >= nb_drives) {
7080 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
7081 c88676f8 bellard
                goto error;
7082 c88676f8 bellard
            }
7083 e4bcb14c ths
            if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
7084 e4bcb14c ths
                          phys_ram_base + i,
7085 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
7086 5fafdf24 ths
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
7087 c88676f8 bellard
                        bs_index, sector_num);
7088 c88676f8 bellard
                goto error;
7089 c88676f8 bellard
            }
7090 5fafdf24 ths
        } else
7091 c88676f8 bellard
#endif
7092 c88676f8 bellard
        {
7093 c88676f8 bellard
        error:
7094 c88676f8 bellard
            printf("Error block header\n");
7095 c88676f8 bellard
            return -EINVAL;
7096 c88676f8 bellard
        }
7097 8a7ddc38 bellard
    }
7098 c88676f8 bellard
    ram_decompress_close(s);
7099 8a7ddc38 bellard
    return 0;
7100 8a7ddc38 bellard
}
7101 8a7ddc38 bellard
7102 8a7ddc38 bellard
/***********************************************************/
7103 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
7104 83f64091 bellard
7105 83f64091 bellard
struct QEMUBH {
7106 83f64091 bellard
    QEMUBHFunc *cb;
7107 83f64091 bellard
    void *opaque;
7108 83f64091 bellard
    int scheduled;
7109 83f64091 bellard
    QEMUBH *next;
7110 83f64091 bellard
};
7111 83f64091 bellard
7112 83f64091 bellard
static QEMUBH *first_bh = NULL;
7113 83f64091 bellard
7114 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
7115 83f64091 bellard
{
7116 83f64091 bellard
    QEMUBH *bh;
7117 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
7118 83f64091 bellard
    if (!bh)
7119 83f64091 bellard
        return NULL;
7120 83f64091 bellard
    bh->cb = cb;
7121 83f64091 bellard
    bh->opaque = opaque;
7122 83f64091 bellard
    return bh;
7123 83f64091 bellard
}
7124 83f64091 bellard
7125 6eb5733a bellard
int qemu_bh_poll(void)
7126 83f64091 bellard
{
7127 83f64091 bellard
    QEMUBH *bh, **pbh;
7128 6eb5733a bellard
    int ret;
7129 83f64091 bellard
7130 6eb5733a bellard
    ret = 0;
7131 83f64091 bellard
    for(;;) {
7132 83f64091 bellard
        pbh = &first_bh;
7133 83f64091 bellard
        bh = *pbh;
7134 83f64091 bellard
        if (!bh)
7135 83f64091 bellard
            break;
7136 6eb5733a bellard
        ret = 1;
7137 83f64091 bellard
        *pbh = bh->next;
7138 83f64091 bellard
        bh->scheduled = 0;
7139 83f64091 bellard
        bh->cb(bh->opaque);
7140 83f64091 bellard
    }
7141 6eb5733a bellard
    return ret;
7142 83f64091 bellard
}
7143 83f64091 bellard
7144 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
7145 83f64091 bellard
{
7146 83f64091 bellard
    CPUState *env = cpu_single_env;
7147 83f64091 bellard
    if (bh->scheduled)
7148 83f64091 bellard
        return;
7149 83f64091 bellard
    bh->scheduled = 1;
7150 83f64091 bellard
    bh->next = first_bh;
7151 83f64091 bellard
    first_bh = bh;
7152 83f64091 bellard
7153 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
7154 83f64091 bellard
    if (env) {
7155 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
7156 83f64091 bellard
    }
7157 83f64091 bellard
}
7158 83f64091 bellard
7159 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
7160 83f64091 bellard
{
7161 83f64091 bellard
    QEMUBH **pbh;
7162 83f64091 bellard
    if (bh->scheduled) {
7163 83f64091 bellard
        pbh = &first_bh;
7164 83f64091 bellard
        while (*pbh != bh)
7165 83f64091 bellard
            pbh = &(*pbh)->next;
7166 83f64091 bellard
        *pbh = bh->next;
7167 83f64091 bellard
        bh->scheduled = 0;
7168 83f64091 bellard
    }
7169 83f64091 bellard
}
7170 83f64091 bellard
7171 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
7172 83f64091 bellard
{
7173 83f64091 bellard
    qemu_bh_cancel(bh);
7174 83f64091 bellard
    qemu_free(bh);
7175 83f64091 bellard
}
7176 83f64091 bellard
7177 83f64091 bellard
/***********************************************************/
7178 cc1daa40 bellard
/* machine registration */
7179 cc1daa40 bellard
7180 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
7181 cc1daa40 bellard
7182 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
7183 cc1daa40 bellard
{
7184 cc1daa40 bellard
    QEMUMachine **pm;
7185 cc1daa40 bellard
    pm = &first_machine;
7186 cc1daa40 bellard
    while (*pm != NULL)
7187 cc1daa40 bellard
        pm = &(*pm)->next;
7188 cc1daa40 bellard
    m->next = NULL;
7189 cc1daa40 bellard
    *pm = m;
7190 cc1daa40 bellard
    return 0;
7191 cc1daa40 bellard
}
7192 cc1daa40 bellard
7193 9596ebb7 pbrook
static QEMUMachine *find_machine(const char *name)
7194 cc1daa40 bellard
{
7195 cc1daa40 bellard
    QEMUMachine *m;
7196 cc1daa40 bellard
7197 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
7198 cc1daa40 bellard
        if (!strcmp(m->name, name))
7199 cc1daa40 bellard
            return m;
7200 cc1daa40 bellard
    }
7201 cc1daa40 bellard
    return NULL;
7202 cc1daa40 bellard
}
7203 cc1daa40 bellard
7204 cc1daa40 bellard
/***********************************************************/
7205 8a7ddc38 bellard
/* main execution loop */
7206 8a7ddc38 bellard
7207 9596ebb7 pbrook
static void gui_update(void *opaque)
7208 8a7ddc38 bellard
{
7209 740733bb ths
    DisplayState *ds = opaque;
7210 740733bb ths
    ds->dpy_refresh(ds);
7211 740733bb ths
    qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
7212 8a7ddc38 bellard
}
7213 8a7ddc38 bellard
7214 0bd48850 bellard
struct vm_change_state_entry {
7215 0bd48850 bellard
    VMChangeStateHandler *cb;
7216 0bd48850 bellard
    void *opaque;
7217 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
7218 0bd48850 bellard
};
7219 0bd48850 bellard
7220 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
7221 0bd48850 bellard
7222 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
7223 0bd48850 bellard
                                                     void *opaque)
7224 0bd48850 bellard
{
7225 0bd48850 bellard
    VMChangeStateEntry *e;
7226 0bd48850 bellard
7227 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
7228 0bd48850 bellard
    if (!e)
7229 0bd48850 bellard
        return NULL;
7230 0bd48850 bellard
7231 0bd48850 bellard
    e->cb = cb;
7232 0bd48850 bellard
    e->opaque = opaque;
7233 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
7234 0bd48850 bellard
    return e;
7235 0bd48850 bellard
}
7236 0bd48850 bellard
7237 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
7238 0bd48850 bellard
{
7239 0bd48850 bellard
    LIST_REMOVE (e, entries);
7240 0bd48850 bellard
    qemu_free (e);
7241 0bd48850 bellard
}
7242 0bd48850 bellard
7243 0bd48850 bellard
static void vm_state_notify(int running)
7244 0bd48850 bellard
{
7245 0bd48850 bellard
    VMChangeStateEntry *e;
7246 0bd48850 bellard
7247 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
7248 0bd48850 bellard
        e->cb(e->opaque, running);
7249 0bd48850 bellard
    }
7250 0bd48850 bellard
}
7251 0bd48850 bellard
7252 8a7ddc38 bellard
/* XXX: support several handlers */
7253 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
7254 0bd48850 bellard
static void *vm_stop_opaque;
7255 8a7ddc38 bellard
7256 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
7257 8a7ddc38 bellard
{
7258 8a7ddc38 bellard
    vm_stop_cb = cb;
7259 8a7ddc38 bellard
    vm_stop_opaque = opaque;
7260 8a7ddc38 bellard
    return 0;
7261 8a7ddc38 bellard
}
7262 8a7ddc38 bellard
7263 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
7264 8a7ddc38 bellard
{
7265 8a7ddc38 bellard
    vm_stop_cb = NULL;
7266 8a7ddc38 bellard
}
7267 8a7ddc38 bellard
7268 8a7ddc38 bellard
void vm_start(void)
7269 8a7ddc38 bellard
{
7270 8a7ddc38 bellard
    if (!vm_running) {
7271 8a7ddc38 bellard
        cpu_enable_ticks();
7272 8a7ddc38 bellard
        vm_running = 1;
7273 0bd48850 bellard
        vm_state_notify(1);
7274 efe75411 ths
        qemu_rearm_alarm_timer(alarm_timer);
7275 8a7ddc38 bellard
    }
7276 8a7ddc38 bellard
}
7277 8a7ddc38 bellard
7278 5fafdf24 ths
void vm_stop(int reason)
7279 8a7ddc38 bellard
{
7280 8a7ddc38 bellard
    if (vm_running) {
7281 8a7ddc38 bellard
        cpu_disable_ticks();
7282 8a7ddc38 bellard
        vm_running = 0;
7283 8a7ddc38 bellard
        if (reason != 0) {
7284 8a7ddc38 bellard
            if (vm_stop_cb) {
7285 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
7286 8a7ddc38 bellard
            }
7287 34865134 bellard
        }
7288 0bd48850 bellard
        vm_state_notify(0);
7289 8a7ddc38 bellard
    }
7290 8a7ddc38 bellard
}
7291 8a7ddc38 bellard
7292 bb0c6722 bellard
/* reset/shutdown handler */
7293 bb0c6722 bellard
7294 bb0c6722 bellard
typedef struct QEMUResetEntry {
7295 bb0c6722 bellard
    QEMUResetHandler *func;
7296 bb0c6722 bellard
    void *opaque;
7297 bb0c6722 bellard
    struct QEMUResetEntry *next;
7298 bb0c6722 bellard
} QEMUResetEntry;
7299 bb0c6722 bellard
7300 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
7301 bb0c6722 bellard
static int reset_requested;
7302 bb0c6722 bellard
static int shutdown_requested;
7303 3475187d bellard
static int powerdown_requested;
7304 bb0c6722 bellard
7305 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
7306 bb0c6722 bellard
{
7307 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
7308 bb0c6722 bellard
7309 bb0c6722 bellard
    pre = &first_reset_entry;
7310 bb0c6722 bellard
    while (*pre != NULL)
7311 bb0c6722 bellard
        pre = &(*pre)->next;
7312 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
7313 bb0c6722 bellard
    re->func = func;
7314 bb0c6722 bellard
    re->opaque = opaque;
7315 bb0c6722 bellard
    re->next = NULL;
7316 bb0c6722 bellard
    *pre = re;
7317 bb0c6722 bellard
}
7318 bb0c6722 bellard
7319 52f61fde ths
static void qemu_system_reset(void)
7320 bb0c6722 bellard
{
7321 bb0c6722 bellard
    QEMUResetEntry *re;
7322 bb0c6722 bellard
7323 bb0c6722 bellard
    /* reset all devices */
7324 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
7325 bb0c6722 bellard
        re->func(re->opaque);
7326 bb0c6722 bellard
    }
7327 bb0c6722 bellard
}
7328 bb0c6722 bellard
7329 bb0c6722 bellard
void qemu_system_reset_request(void)
7330 bb0c6722 bellard
{
7331 d1beab82 bellard
    if (no_reboot) {
7332 d1beab82 bellard
        shutdown_requested = 1;
7333 d1beab82 bellard
    } else {
7334 d1beab82 bellard
        reset_requested = 1;
7335 d1beab82 bellard
    }
7336 6a00d601 bellard
    if (cpu_single_env)
7337 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7338 bb0c6722 bellard
}
7339 bb0c6722 bellard
7340 bb0c6722 bellard
void qemu_system_shutdown_request(void)
7341 bb0c6722 bellard
{
7342 bb0c6722 bellard
    shutdown_requested = 1;
7343 6a00d601 bellard
    if (cpu_single_env)
7344 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7345 bb0c6722 bellard
}
7346 bb0c6722 bellard
7347 3475187d bellard
void qemu_system_powerdown_request(void)
7348 3475187d bellard
{
7349 3475187d bellard
    powerdown_requested = 1;
7350 6a00d601 bellard
    if (cpu_single_env)
7351 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7352 bb0c6722 bellard
}
7353 bb0c6722 bellard
7354 5905b2e5 bellard
void main_loop_wait(int timeout)
7355 8a7ddc38 bellard
{
7356 cafffd40 ths
    IOHandlerRecord *ioh;
7357 e035649e bellard
    fd_set rfds, wfds, xfds;
7358 877cf882 ths
    int ret, nfds;
7359 877cf882 ths
#ifdef _WIN32
7360 877cf882 ths
    int ret2, i;
7361 877cf882 ths
#endif
7362 fd1dff4b bellard
    struct timeval tv;
7363 f331110f bellard
    PollingEntry *pe;
7364 f331110f bellard
7365 c4b1fcc0 bellard
7366 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
7367 f331110f bellard
    ret = 0;
7368 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
7369 f331110f bellard
        ret |= pe->func(pe->opaque);
7370 f331110f bellard
    }
7371 38e205a2 bellard
#ifdef _WIN32
7372 e6b1e558 ths
    if (ret == 0) {
7373 a18e524a bellard
        int err;
7374 a18e524a bellard
        WaitObjects *w = &wait_objects;
7375 3b46e624 ths
7376 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
7377 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
7378 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
7379 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
7380 3b46e624 ths
7381 5fafdf24 ths
            /* Check for additional signaled events */
7382 e6b1e558 ths
            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
7383 3b46e624 ths
7384 e6b1e558 ths
                /* Check if event is signaled */
7385 e6b1e558 ths
                ret2 = WaitForSingleObject(w->events[i], 0);
7386 e6b1e558 ths
                if(ret2 == WAIT_OBJECT_0) {
7387 e6b1e558 ths
                    if (w->func[i])
7388 e6b1e558 ths
                        w->func[i](w->opaque[i]);
7389 e6b1e558 ths
                } else if (ret2 == WAIT_TIMEOUT) {
7390 e6b1e558 ths
                } else {
7391 e6b1e558 ths
                    err = GetLastError();
7392 e6b1e558 ths
                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
7393 3b46e624 ths
                }
7394 3b46e624 ths
            }
7395 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
7396 a18e524a bellard
        } else {
7397 a18e524a bellard
            err = GetLastError();
7398 e6b1e558 ths
            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
7399 a18e524a bellard
        }
7400 f331110f bellard
    }
7401 fd1dff4b bellard
#endif
7402 fd1dff4b bellard
    /* poll any events */
7403 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
7404 fd1dff4b bellard
    nfds = -1;
7405 fd1dff4b bellard
    FD_ZERO(&rfds);
7406 fd1dff4b bellard
    FD_ZERO(&wfds);
7407 e035649e bellard
    FD_ZERO(&xfds);
7408 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
7409 cafffd40 ths
        if (ioh->deleted)
7410 cafffd40 ths
            continue;
7411 fd1dff4b bellard
        if (ioh->fd_read &&
7412 fd1dff4b bellard
            (!ioh->fd_read_poll ||
7413 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
7414 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
7415 fd1dff4b bellard
            if (ioh->fd > nfds)
7416 fd1dff4b bellard
                nfds = ioh->fd;
7417 fd1dff4b bellard
        }
7418 fd1dff4b bellard
        if (ioh->fd_write) {
7419 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
7420 fd1dff4b bellard
            if (ioh->fd > nfds)
7421 fd1dff4b bellard
                nfds = ioh->fd;
7422 fd1dff4b bellard
        }
7423 fd1dff4b bellard
    }
7424 3b46e624 ths
7425 fd1dff4b bellard
    tv.tv_sec = 0;
7426 fd1dff4b bellard
#ifdef _WIN32
7427 fd1dff4b bellard
    tv.tv_usec = 0;
7428 38e205a2 bellard
#else
7429 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
7430 fd1dff4b bellard
#endif
7431 e035649e bellard
#if defined(CONFIG_SLIRP)
7432 e035649e bellard
    if (slirp_inited) {
7433 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
7434 e035649e bellard
    }
7435 e035649e bellard
#endif
7436 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
7437 fd1dff4b bellard
    if (ret > 0) {
7438 cafffd40 ths
        IOHandlerRecord **pioh;
7439 cafffd40 ths
7440 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
7441 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
7442 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
7443 7c9d8e07 bellard
            }
7444 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
7445 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
7446 c4b1fcc0 bellard
            }
7447 b4608c04 bellard
        }
7448 cafffd40 ths
7449 cafffd40 ths
        /* remove deleted IO handlers */
7450 cafffd40 ths
        pioh = &first_io_handler;
7451 cafffd40 ths
        while (*pioh) {
7452 cafffd40 ths
            ioh = *pioh;
7453 cafffd40 ths
            if (ioh->deleted) {
7454 cafffd40 ths
                *pioh = ioh->next;
7455 cafffd40 ths
                qemu_free(ioh);
7456 5fafdf24 ths
            } else
7457 cafffd40 ths
                pioh = &ioh->next;
7458 cafffd40 ths
        }
7459 fd1dff4b bellard
    }
7460 c20709aa bellard
#if defined(CONFIG_SLIRP)
7461 fd1dff4b bellard
    if (slirp_inited) {
7462 e035649e bellard
        if (ret < 0) {
7463 e035649e bellard
            FD_ZERO(&rfds);
7464 e035649e bellard
            FD_ZERO(&wfds);
7465 e035649e bellard
            FD_ZERO(&xfds);
7466 c20709aa bellard
        }
7467 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
7468 fd1dff4b bellard
    }
7469 c20709aa bellard
#endif
7470 83f64091 bellard
    qemu_aio_poll();
7471 c20709aa bellard
7472 fd1dff4b bellard
    if (vm_running) {
7473 5fafdf24 ths
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
7474 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
7475 fd1dff4b bellard
        /* run dma transfers, if any */
7476 fd1dff4b bellard
        DMA_run();
7477 fd1dff4b bellard
    }
7478 423f0742 pbrook
7479 fd1dff4b bellard
    /* real time timers */
7480 5fafdf24 ths
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
7481 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
7482 423f0742 pbrook
7483 d5d08334 balrog
    if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
7484 d5d08334 balrog
        alarm_timer->flags &= ~(ALARM_FLAG_EXPIRED);
7485 d5d08334 balrog
        qemu_rearm_alarm_timer(alarm_timer);
7486 d5d08334 balrog
    }
7487 b99dc0d1 balrog
7488 423f0742 pbrook
    /* Check bottom-halves last in case any of the earlier events triggered
7489 423f0742 pbrook
       them.  */
7490 423f0742 pbrook
    qemu_bh_poll();
7491 3b46e624 ths
7492 5905b2e5 bellard
}
7493 5905b2e5 bellard
7494 9596ebb7 pbrook
static int main_loop(void)
7495 5905b2e5 bellard
{
7496 5905b2e5 bellard
    int ret, timeout;
7497 89bfc105 bellard
#ifdef CONFIG_PROFILER
7498 89bfc105 bellard
    int64_t ti;
7499 89bfc105 bellard
#endif
7500 6a00d601 bellard
    CPUState *env;
7501 5905b2e5 bellard
7502 6a00d601 bellard
    cur_cpu = first_cpu;
7503 ee5605e5 balrog
    next_cpu = cur_cpu->next_cpu ?: first_cpu;
7504 5905b2e5 bellard
    for(;;) {
7505 5905b2e5 bellard
        if (vm_running) {
7506 15a76449 bellard
7507 15a76449 bellard
            for(;;) {
7508 15a76449 bellard
                /* get next cpu */
7509 ee5605e5 balrog
                env = next_cpu;
7510 89bfc105 bellard
#ifdef CONFIG_PROFILER
7511 89bfc105 bellard
                ti = profile_getclock();
7512 89bfc105 bellard
#endif
7513 6a00d601 bellard
                ret = cpu_exec(env);
7514 89bfc105 bellard
#ifdef CONFIG_PROFILER
7515 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
7516 89bfc105 bellard
#endif
7517 ee5605e5 balrog
                next_cpu = env->next_cpu ?: first_cpu;
7518 ee5605e5 balrog
                if (event_pending) {
7519 ee5605e5 balrog
                    ret = EXCP_INTERRUPT;
7520 ee5605e5 balrog
                    event_pending = 0;
7521 ee5605e5 balrog
                    break;
7522 ee5605e5 balrog
                }
7523 bd967e05 pbrook
                if (ret == EXCP_HLT) {
7524 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
7525 bd967e05 pbrook
                    cur_cpu = env;
7526 bd967e05 pbrook
                    continue;
7527 bd967e05 pbrook
                }
7528 15a76449 bellard
                if (ret != EXCP_HALTED)
7529 15a76449 bellard
                    break;
7530 15a76449 bellard
                /* all CPUs are halted ? */
7531 bd967e05 pbrook
                if (env == cur_cpu)
7532 15a76449 bellard
                    break;
7533 15a76449 bellard
            }
7534 15a76449 bellard
            cur_cpu = env;
7535 15a76449 bellard
7536 5905b2e5 bellard
            if (shutdown_requested) {
7537 3475187d bellard
                ret = EXCP_INTERRUPT;
7538 5905b2e5 bellard
                break;
7539 5905b2e5 bellard
            }
7540 5905b2e5 bellard
            if (reset_requested) {
7541 5905b2e5 bellard
                reset_requested = 0;
7542 5905b2e5 bellard
                qemu_system_reset();
7543 3475187d bellard
                ret = EXCP_INTERRUPT;
7544 3475187d bellard
            }
7545 3475187d bellard
            if (powerdown_requested) {
7546 3475187d bellard
                powerdown_requested = 0;
7547 3475187d bellard
                qemu_system_powerdown();
7548 3475187d bellard
                ret = EXCP_INTERRUPT;
7549 5905b2e5 bellard
            }
7550 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
7551 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
7552 5905b2e5 bellard
            }
7553 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
7554 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
7555 bd967e05 pbrook
            if (ret == EXCP_HALTED)
7556 5905b2e5 bellard
                timeout = 10;
7557 5905b2e5 bellard
            else
7558 5905b2e5 bellard
                timeout = 0;
7559 5905b2e5 bellard
        } else {
7560 5905b2e5 bellard
            timeout = 10;
7561 5905b2e5 bellard
        }
7562 89bfc105 bellard
#ifdef CONFIG_PROFILER
7563 89bfc105 bellard
        ti = profile_getclock();
7564 89bfc105 bellard
#endif
7565 5905b2e5 bellard
        main_loop_wait(timeout);
7566 89bfc105 bellard
#ifdef CONFIG_PROFILER
7567 89bfc105 bellard
        dev_time += profile_getclock() - ti;
7568 89bfc105 bellard
#endif
7569 b4608c04 bellard
    }
7570 34865134 bellard
    cpu_disable_ticks();
7571 34865134 bellard
    return ret;
7572 b4608c04 bellard
}
7573 b4608c04 bellard
7574 15f82208 ths
static void help(int exitcode)
7575 0824d6fc bellard
{
7576 68d0f70e bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
7577 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
7578 0824d6fc bellard
           "\n"
7579 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
7580 fc01f7e7 bellard
           "\n"
7581 a20dd508 bellard
           "Standard options:\n"
7582 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
7583 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
7584 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
7585 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
7586 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
7587 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
7588 e4bcb14c ths
           "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n"
7589 33f00271 balrog
           "       [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]"
7590 33f00271 balrog
           "       [,cache=on|off]\n"
7591 e4bcb14c ths
           "                use 'file' as a drive image\n"
7592 3e3d5815 balrog
           "-mtdblock file  use 'file' as on-board Flash memory image\n"
7593 a1bb27b1 pbrook
           "-sd file        use 'file' as SecureDigital card image\n"
7594 86f55663 j_mayer
           "-pflash file    use 'file' as a parallel flash image\n"
7595 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
7596 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
7597 667accab ths
#ifdef CONFIG_SDL
7598 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
7599 3780e197 ths
           "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
7600 667accab ths
           "-no-quit        disable SDL window close capability\n"
7601 667accab ths
#endif
7602 52ca8d6a bellard
#ifdef TARGET_I386
7603 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
7604 52ca8d6a bellard
#endif
7605 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
7606 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
7607 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
7608 a171fe39 balrog
           "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"
7609 4ca0074c bellard
#ifndef _WIN32
7610 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
7611 4ca0074c bellard
#endif
7612 1d14ffa9 bellard
#ifdef HAS_AUDIO
7613 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
7614 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
7615 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
7616 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
7617 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
7618 1d14ffa9 bellard
#endif
7619 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
7620 d63d307f bellard
           "-full-screen    start in full screen\n"
7621 a09db21f bellard
#ifdef TARGET_I386
7622 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
7623 a09db21f bellard
#endif
7624 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
7625 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
7626 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7627 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
7628 bb0c6722 bellard
#endif
7629 c35734b2 ths
           "-name string    set the name of the guest\n"
7630 c4b1fcc0 bellard
           "\n"
7631 c4b1fcc0 bellard
           "Network options:\n"
7632 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
7633 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
7634 c20709aa bellard
#ifdef CONFIG_SLIRP
7635 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
7636 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
7637 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
7638 7c9d8e07 bellard
#endif
7639 7fb843f8 bellard
#ifdef _WIN32
7640 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
7641 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
7642 7fb843f8 bellard
#else
7643 b46a8906 ths
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7644 b46a8906 ths
           "                connect the host TAP network interface to VLAN 'n' and use the\n"
7645 b46a8906 ths
           "                network scripts 'file' (default=%s)\n"
7646 b46a8906 ths
           "                and 'dfile' (default=%s);\n"
7647 b46a8906 ths
           "                use '[down]script=no' to disable script execution;\n"
7648 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
7649 7fb843f8 bellard
#endif
7650 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
7651 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
7652 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7653 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
7654 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
7655 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
7656 7c9d8e07 bellard
           "\n"
7657 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
7658 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
7659 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
7660 7c9d8e07 bellard
#ifndef _WIN32
7661 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
7662 c94c8d64 bellard
#endif
7663 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
7664 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
7665 c20709aa bellard
#endif
7666 a20dd508 bellard
           "\n"
7667 c4b1fcc0 bellard
           "Linux boot specific:\n"
7668 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
7669 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
7670 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
7671 fc01f7e7 bellard
           "\n"
7672 330d0414 bellard
           "Debug/Expert options:\n"
7673 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
7674 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
7675 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
7676 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
7677 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
7678 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
7679 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
7680 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
7681 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
7682 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
7683 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
7684 d993e026 bellard
#ifdef USE_KQEMU
7685 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
7686 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
7687 d993e026 bellard
#endif
7688 bb0c6722 bellard
#ifdef TARGET_I386
7689 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
7690 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
7691 6515b203 bellard
           "-no-acpi        disable ACPI\n"
7692 bb0c6722 bellard
#endif
7693 4d3b6f6e balrog
#ifdef CONFIG_CURSES
7694 4d3b6f6e balrog
           "-curses         use a curses/ncurses interface instead of SDL\n"
7695 4d3b6f6e balrog
#endif
7696 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
7697 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
7698 24236869 bellard
           "-vnc display    start a VNC server on display\n"
7699 71e3ceb8 ths
#ifndef _WIN32
7700 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
7701 71e3ceb8 ths
#endif
7702 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
7703 66508601 blueswir1
#ifdef TARGET_SPARC
7704 66508601 blueswir1
           "-prom-env variable=value  set OpenBIOS nvram variables\n"
7705 66508601 blueswir1
#endif
7706 f3dcfada ths
           "-clock          force the use of the given methods for timer alarm.\n"
7707 f3dcfada ths
           "                To see what timers are available use -clock help\n"
7708 bce61846 bellard
           "-startdate      select initial date of the clock\n"
7709 0824d6fc bellard
           "\n"
7710 82c643ff bellard
           "During emulation, the following keys are useful:\n"
7711 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
7712 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
7713 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
7714 82c643ff bellard
           "\n"
7715 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
7716 82c643ff bellard
           ,
7717 0db63474 bellard
           "qemu",
7718 a00bad7e bellard
           DEFAULT_RAM_SIZE,
7719 7c9d8e07 bellard
#ifndef _WIN32
7720 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
7721 b46a8906 ths
           DEFAULT_NETWORK_DOWN_SCRIPT,
7722 7c9d8e07 bellard
#endif
7723 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
7724 bce61846 bellard
           "/tmp/qemu.log");
7725 15f82208 ths
    exit(exitcode);
7726 0824d6fc bellard
}
7727 0824d6fc bellard
7728 cd6f1169 bellard
#define HAS_ARG 0x0001
7729 cd6f1169 bellard
7730 cd6f1169 bellard
enum {
7731 cd6f1169 bellard
    QEMU_OPTION_h,
7732 cd6f1169 bellard
7733 cc1daa40 bellard
    QEMU_OPTION_M,
7734 94fc95cd j_mayer
    QEMU_OPTION_cpu,
7735 cd6f1169 bellard
    QEMU_OPTION_fda,
7736 cd6f1169 bellard
    QEMU_OPTION_fdb,
7737 cd6f1169 bellard
    QEMU_OPTION_hda,
7738 cd6f1169 bellard
    QEMU_OPTION_hdb,
7739 cd6f1169 bellard
    QEMU_OPTION_hdc,
7740 cd6f1169 bellard
    QEMU_OPTION_hdd,
7741 e4bcb14c ths
    QEMU_OPTION_drive,
7742 cd6f1169 bellard
    QEMU_OPTION_cdrom,
7743 3e3d5815 balrog
    QEMU_OPTION_mtdblock,
7744 a1bb27b1 pbrook
    QEMU_OPTION_sd,
7745 86f55663 j_mayer
    QEMU_OPTION_pflash,
7746 cd6f1169 bellard
    QEMU_OPTION_boot,
7747 cd6f1169 bellard
    QEMU_OPTION_snapshot,
7748 52ca8d6a bellard
#ifdef TARGET_I386
7749 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
7750 52ca8d6a bellard
#endif
7751 cd6f1169 bellard
    QEMU_OPTION_m,
7752 cd6f1169 bellard
    QEMU_OPTION_nographic,
7753 a171fe39 balrog
    QEMU_OPTION_portrait,
7754 1d14ffa9 bellard
#ifdef HAS_AUDIO
7755 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
7756 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
7757 1d14ffa9 bellard
#endif
7758 cd6f1169 bellard
7759 7c9d8e07 bellard
    QEMU_OPTION_net,
7760 c7f74643 bellard
    QEMU_OPTION_tftp,
7761 47d5d01a ths
    QEMU_OPTION_bootp,
7762 9d728e8c bellard
    QEMU_OPTION_smb,
7763 9bf05444 bellard
    QEMU_OPTION_redir,
7764 cd6f1169 bellard
7765 cd6f1169 bellard
    QEMU_OPTION_kernel,
7766 cd6f1169 bellard
    QEMU_OPTION_append,
7767 cd6f1169 bellard
    QEMU_OPTION_initrd,
7768 cd6f1169 bellard
7769 cd6f1169 bellard
    QEMU_OPTION_S,
7770 cd6f1169 bellard
    QEMU_OPTION_s,
7771 cd6f1169 bellard
    QEMU_OPTION_p,
7772 cd6f1169 bellard
    QEMU_OPTION_d,
7773 cd6f1169 bellard
    QEMU_OPTION_hdachs,
7774 cd6f1169 bellard
    QEMU_OPTION_L,
7775 1192dad8 j_mayer
    QEMU_OPTION_bios,
7776 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
7777 3d11d0eb bellard
    QEMU_OPTION_k,
7778 ee22c2f7 bellard
    QEMU_OPTION_localtime,
7779 1f04275e bellard
    QEMU_OPTION_cirrusvga,
7780 d34cab9f ths
    QEMU_OPTION_vmsvga,
7781 e9b137c2 bellard
    QEMU_OPTION_g,
7782 1bfe856e bellard
    QEMU_OPTION_std_vga,
7783 20d8a3ed ths
    QEMU_OPTION_echr,
7784 82c643ff bellard
    QEMU_OPTION_monitor,
7785 82c643ff bellard
    QEMU_OPTION_serial,
7786 6508fe59 bellard
    QEMU_OPTION_parallel,
7787 d63d307f bellard
    QEMU_OPTION_loadvm,
7788 d63d307f bellard
    QEMU_OPTION_full_screen,
7789 43523e93 ths
    QEMU_OPTION_no_frame,
7790 3780e197 ths
    QEMU_OPTION_alt_grab,
7791 667accab ths
    QEMU_OPTION_no_quit,
7792 f7cce898 bellard
    QEMU_OPTION_pidfile,
7793 d993e026 bellard
    QEMU_OPTION_no_kqemu,
7794 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
7795 a09db21f bellard
    QEMU_OPTION_win2k_hack,
7796 bb36d470 bellard
    QEMU_OPTION_usb,
7797 a594cfbf bellard
    QEMU_OPTION_usbdevice,
7798 6a00d601 bellard
    QEMU_OPTION_smp,
7799 24236869 bellard
    QEMU_OPTION_vnc,
7800 6515b203 bellard
    QEMU_OPTION_no_acpi,
7801 4d3b6f6e balrog
    QEMU_OPTION_curses,
7802 d1beab82 bellard
    QEMU_OPTION_no_reboot,
7803 9467cd46 balrog
    QEMU_OPTION_show_cursor,
7804 71e3ceb8 ths
    QEMU_OPTION_daemonize,
7805 9ae02555 ths
    QEMU_OPTION_option_rom,
7806 c35734b2 ths
    QEMU_OPTION_semihosting,
7807 c35734b2 ths
    QEMU_OPTION_name,
7808 66508601 blueswir1
    QEMU_OPTION_prom_env,
7809 2b8f2d41 balrog
    QEMU_OPTION_old_param,
7810 f3dcfada ths
    QEMU_OPTION_clock,
7811 7e0af5d0 bellard
    QEMU_OPTION_startdate,
7812 cd6f1169 bellard
};
7813 cd6f1169 bellard
7814 cd6f1169 bellard
typedef struct QEMUOption {
7815 cd6f1169 bellard
    const char *name;
7816 cd6f1169 bellard
    int flags;
7817 cd6f1169 bellard
    int index;
7818 cd6f1169 bellard
} QEMUOption;
7819 cd6f1169 bellard
7820 cd6f1169 bellard
const QEMUOption qemu_options[] = {
7821 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
7822 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
7823 cd6f1169 bellard
7824 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
7825 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
7826 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
7827 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7828 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
7829 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7830 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7831 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
7832 e4bcb14c ths
    { "drive", HAS_ARG, QEMU_OPTION_drive },
7833 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
7834 3e3d5815 balrog
    { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
7835 a1bb27b1 pbrook
    { "sd", HAS_ARG, QEMU_OPTION_sd },
7836 86f55663 j_mayer
    { "pflash", HAS_ARG, QEMU_OPTION_pflash },
7837 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
7838 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
7839 52ca8d6a bellard
#ifdef TARGET_I386
7840 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7841 52ca8d6a bellard
#endif
7842 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
7843 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
7844 a171fe39 balrog
    { "portrait", 0, QEMU_OPTION_portrait },
7845 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
7846 1d14ffa9 bellard
#ifdef HAS_AUDIO
7847 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
7848 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7849 1d14ffa9 bellard
#endif
7850 cd6f1169 bellard
7851 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
7852 158156d1 bellard
#ifdef CONFIG_SLIRP
7853 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
7854 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
7855 c94c8d64 bellard
#ifndef _WIN32
7856 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
7857 c94c8d64 bellard
#endif
7858 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
7859 158156d1 bellard
#endif
7860 cd6f1169 bellard
7861 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7862 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
7863 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7864 cd6f1169 bellard
7865 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
7866 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
7867 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
7868 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
7869 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7870 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
7871 1192dad8 j_mayer
    { "bios", HAS_ARG, QEMU_OPTION_bios },
7872 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
7873 d993e026 bellard
#ifdef USE_KQEMU
7874 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
7875 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
7876 d993e026 bellard
#endif
7877 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7878 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
7879 77d4bc34 bellard
#endif
7880 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
7881 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
7882 8b6e0729 balrog
    { "echr", HAS_ARG, QEMU_OPTION_echr },
7883 8b6e0729 balrog
    { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7884 8b6e0729 balrog
    { "serial", HAS_ARG, QEMU_OPTION_serial },
7885 8b6e0729 balrog
    { "parallel", HAS_ARG, QEMU_OPTION_parallel },
7886 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7887 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
7888 667accab ths
#ifdef CONFIG_SDL
7889 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
7890 3780e197 ths
    { "alt-grab", 0, QEMU_OPTION_alt_grab },
7891 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
7892 667accab ths
#endif
7893 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
7894 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
7895 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
7896 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
7897 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
7898 4d3b6f6e balrog
#ifdef CONFIG_CURSES
7899 4d3b6f6e balrog
    { "curses", 0, QEMU_OPTION_curses },
7900 4d3b6f6e balrog
#endif
7901 96d30e48 ths
7902 1f04275e bellard
    /* temporary options */
7903 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
7904 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
7905 d34cab9f ths
    { "vmwarevga", 0, QEMU_OPTION_vmsvga },
7906 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
7907 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
7908 9467cd46 balrog
    { "show-cursor", 0, QEMU_OPTION_show_cursor },
7909 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
7910 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
7911 a87295e8 pbrook
#if defined(TARGET_ARM) || defined(TARGET_M68K)
7912 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
7913 8e71621f pbrook
#endif
7914 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
7915 66508601 blueswir1
#if defined(TARGET_SPARC)
7916 66508601 blueswir1
    { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
7917 66508601 blueswir1
#endif
7918 2b8f2d41 balrog
#if defined(TARGET_ARM)
7919 2b8f2d41 balrog
    { "old-param", 0, QEMU_OPTION_old_param },
7920 2b8f2d41 balrog
#endif
7921 f3dcfada ths
    { "clock", HAS_ARG, QEMU_OPTION_clock },
7922 7e0af5d0 bellard
    { "startdate", HAS_ARG, QEMU_OPTION_startdate },
7923 cd6f1169 bellard
    { NULL },
7924 fc01f7e7 bellard
};
7925 fc01f7e7 bellard
7926 5905b2e5 bellard
/* password input */
7927 5905b2e5 bellard
7928 2bac6019 balrog
int qemu_key_check(BlockDriverState *bs, const char *name)
7929 2bac6019 balrog
{
7930 2bac6019 balrog
    char password[256];
7931 2bac6019 balrog
    int i;
7932 2bac6019 balrog
7933 2bac6019 balrog
    if (!bdrv_is_encrypted(bs))
7934 2bac6019 balrog
        return 0;
7935 2bac6019 balrog
7936 2bac6019 balrog
    term_printf("%s is encrypted.\n", name);
7937 2bac6019 balrog
    for(i = 0; i < 3; i++) {
7938 2bac6019 balrog
        monitor_readline("Password: ", 1, password, sizeof(password));
7939 2bac6019 balrog
        if (bdrv_set_key(bs, password) == 0)
7940 2bac6019 balrog
            return 0;
7941 2bac6019 balrog
        term_printf("invalid password\n");
7942 2bac6019 balrog
    }
7943 2bac6019 balrog
    return -EPERM;
7944 2bac6019 balrog
}
7945 2bac6019 balrog
7946 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
7947 5905b2e5 bellard
{
7948 e4bcb14c ths
    if (index > nb_drives)
7949 e4bcb14c ths
        return NULL;
7950 e4bcb14c ths
    return drives_table[index].bdrv;
7951 5905b2e5 bellard
}
7952 5905b2e5 bellard
7953 5905b2e5 bellard
static void read_passwords(void)
7954 5905b2e5 bellard
{
7955 5905b2e5 bellard
    BlockDriverState *bs;
7956 2bac6019 balrog
    int i;
7957 5905b2e5 bellard
7958 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
7959 5905b2e5 bellard
        bs = get_bdrv(i);
7960 2bac6019 balrog
        if (bs)
7961 2bac6019 balrog
            qemu_key_check(bs, bdrv_get_device_name(bs));
7962 5905b2e5 bellard
    }
7963 5905b2e5 bellard
}
7964 5905b2e5 bellard
7965 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
7966 9596ebb7 pbrook
static void register_machines(void)
7967 cc1daa40 bellard
{
7968 cc1daa40 bellard
#if defined(TARGET_I386)
7969 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
7970 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
7971 cc1daa40 bellard
#elif defined(TARGET_PPC)
7972 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
7973 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
7974 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
7975 1a6c0886 j_mayer
    qemu_register_machine(&ref405ep_machine);
7976 1a6c0886 j_mayer
    qemu_register_machine(&taihu_machine);
7977 6af0bf9c bellard
#elif defined(TARGET_MIPS)
7978 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
7979 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
7980 ad6fe1d2 ths
    qemu_register_machine(&mips_pica61_machine);
7981 6bf5b4e8 ths
    qemu_register_machine(&mips_mipssim_machine);
7982 cc1daa40 bellard
#elif defined(TARGET_SPARC)
7983 3475187d bellard
#ifdef TARGET_SPARC64
7984 3475187d bellard
    qemu_register_machine(&sun4u_machine);
7985 3475187d bellard
#else
7986 36cd9210 blueswir1
    qemu_register_machine(&ss5_machine);
7987 e0353fe2 blueswir1
    qemu_register_machine(&ss10_machine);
7988 6a3b9cc9 blueswir1
    qemu_register_machine(&ss600mp_machine);
7989 ae40972f blueswir1
    qemu_register_machine(&ss20_machine);
7990 ee76f82e blueswir1
    qemu_register_machine(&ss2_machine);
7991 a526a31c blueswir1
    qemu_register_machine(&voyager_machine);
7992 a526a31c blueswir1
    qemu_register_machine(&ss_lx_machine);
7993 a526a31c blueswir1
    qemu_register_machine(&ss4_machine);
7994 a526a31c blueswir1
    qemu_register_machine(&scls_machine);
7995 a526a31c blueswir1
    qemu_register_machine(&sbook_machine);
7996 7d85892b blueswir1
    qemu_register_machine(&ss1000_machine);
7997 7d85892b blueswir1
    qemu_register_machine(&ss2000_machine);
7998 cc1daa40 bellard
#endif
7999 b5ff1b31 bellard
#elif defined(TARGET_ARM)
8000 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
8001 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
8002 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
8003 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
8004 b00052e4 balrog
    qemu_register_machine(&akitapda_machine);
8005 b00052e4 balrog
    qemu_register_machine(&spitzpda_machine);
8006 b00052e4 balrog
    qemu_register_machine(&borzoipda_machine);
8007 b00052e4 balrog
    qemu_register_machine(&terrierpda_machine);
8008 c3d2689d balrog
    qemu_register_machine(&palmte_machine);
8009 9ee6e8bb pbrook
    qemu_register_machine(&lm3s811evb_machine);
8010 9ee6e8bb pbrook
    qemu_register_machine(&lm3s6965evb_machine);
8011 05ee37eb balrog
    qemu_register_machine(&connex_machine);
8012 3e3f6754 balrog
    qemu_register_machine(&verdex_machine);
8013 ef056e43 balrog
    qemu_register_machine(&mainstone2_machine);
8014 27c7ca7e bellard
#elif defined(TARGET_SH4)
8015 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
8016 0d78f544 ths
    qemu_register_machine(&r2d_machine);
8017 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
8018 eddf68a6 j_mayer
    /* XXX: TODO */
8019 0633879f pbrook
#elif defined(TARGET_M68K)
8020 20dcee94 pbrook
    qemu_register_machine(&mcf5208evb_machine);
8021 0633879f pbrook
    qemu_register_machine(&an5206_machine);
8022 ca02f319 pbrook
    qemu_register_machine(&dummy_m68k_machine);
8023 f1ccf904 ths
#elif defined(TARGET_CRIS)
8024 f1ccf904 ths
    qemu_register_machine(&bareetraxfs_machine);
8025 b5ff1b31 bellard
#else
8026 b5ff1b31 bellard
#error unsupported CPU
8027 3475187d bellard
#endif
8028 cc1daa40 bellard
}
8029 cc1daa40 bellard
8030 1d14ffa9 bellard
#ifdef HAS_AUDIO
8031 6a36d84e bellard
struct soundhw soundhw[] = {
8032 b00052e4 balrog
#ifdef HAS_AUDIO_CHOICE
8033 fd06c375 bellard
#ifdef TARGET_I386
8034 fd06c375 bellard
    {
8035 fd06c375 bellard
        "pcspk",
8036 fd06c375 bellard
        "PC speaker",
8037 fd06c375 bellard
        0,
8038 fd06c375 bellard
        1,
8039 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
8040 fd06c375 bellard
    },
8041 fd06c375 bellard
#endif
8042 6a36d84e bellard
    {
8043 6a36d84e bellard
        "sb16",
8044 6a36d84e bellard
        "Creative Sound Blaster 16",
8045 6a36d84e bellard
        0,
8046 6a36d84e bellard
        1,
8047 6a36d84e bellard
        { .init_isa = SB16_init }
8048 6a36d84e bellard
    },
8049 6a36d84e bellard
8050 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
8051 6a36d84e bellard
    {
8052 6a36d84e bellard
        "adlib",
8053 1d14ffa9 bellard
#ifdef HAS_YMF262
8054 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
8055 1d14ffa9 bellard
#else
8056 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
8057 1d14ffa9 bellard
#endif
8058 6a36d84e bellard
        0,
8059 6a36d84e bellard
        1,
8060 6a36d84e bellard
        { .init_isa = Adlib_init }
8061 6a36d84e bellard
    },
8062 1d14ffa9 bellard
#endif
8063 6a36d84e bellard
8064 1d14ffa9 bellard
#ifdef CONFIG_GUS
8065 6a36d84e bellard
    {
8066 6a36d84e bellard
        "gus",
8067 6a36d84e bellard
        "Gravis Ultrasound GF1",
8068 6a36d84e bellard
        0,
8069 6a36d84e bellard
        1,
8070 6a36d84e bellard
        { .init_isa = GUS_init }
8071 6a36d84e bellard
    },
8072 1d14ffa9 bellard
#endif
8073 6a36d84e bellard
8074 e5c9a13e balrog
#ifdef CONFIG_AC97
8075 e5c9a13e balrog
    {
8076 e5c9a13e balrog
        "ac97",
8077 e5c9a13e balrog
        "Intel 82801AA AC97 Audio",
8078 e5c9a13e balrog
        0,
8079 e5c9a13e balrog
        0,
8080 e5c9a13e balrog
        { .init_pci = ac97_init }
8081 e5c9a13e balrog
    },
8082 e5c9a13e balrog
#endif
8083 e5c9a13e balrog
8084 6a36d84e bellard
    {
8085 6a36d84e bellard
        "es1370",
8086 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
8087 6a36d84e bellard
        0,
8088 6a36d84e bellard
        0,
8089 6a36d84e bellard
        { .init_pci = es1370_init }
8090 6a36d84e bellard
    },
8091 b00052e4 balrog
#endif
8092 6a36d84e bellard
8093 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
8094 6a36d84e bellard
};
8095 6a36d84e bellard
8096 6a36d84e bellard
static void select_soundhw (const char *optarg)
8097 6a36d84e bellard
{
8098 6a36d84e bellard
    struct soundhw *c;
8099 6a36d84e bellard
8100 6a36d84e bellard
    if (*optarg == '?') {
8101 6a36d84e bellard
    show_valid_cards:
8102 6a36d84e bellard
8103 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
8104 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
8105 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
8106 6a36d84e bellard
        }
8107 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
8108 1d14ffa9 bellard
        exit (*optarg != '?');
8109 1d14ffa9 bellard
    }
8110 1d14ffa9 bellard
    else {
8111 6a36d84e bellard
        size_t l;
8112 1d14ffa9 bellard
        const char *p;
8113 1d14ffa9 bellard
        char *e;
8114 1d14ffa9 bellard
        int bad_card = 0;
8115 1d14ffa9 bellard
8116 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
8117 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
8118 6a36d84e bellard
                c->enabled = 1;
8119 6a36d84e bellard
            }
8120 6a36d84e bellard
            return;
8121 6a36d84e bellard
        }
8122 1d14ffa9 bellard
8123 6a36d84e bellard
        p = optarg;
8124 1d14ffa9 bellard
        while (*p) {
8125 1d14ffa9 bellard
            e = strchr (p, ',');
8126 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
8127 6a36d84e bellard
8128 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
8129 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
8130 6a36d84e bellard
                    c->enabled = 1;
8131 1d14ffa9 bellard
                    break;
8132 1d14ffa9 bellard
                }
8133 1d14ffa9 bellard
            }
8134 6a36d84e bellard
8135 6a36d84e bellard
            if (!c->name) {
8136 1d14ffa9 bellard
                if (l > 80) {
8137 1d14ffa9 bellard
                    fprintf (stderr,
8138 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
8139 1d14ffa9 bellard
                }
8140 1d14ffa9 bellard
                else {
8141 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
8142 1d14ffa9 bellard
                             (int) l, p);
8143 1d14ffa9 bellard
                }
8144 1d14ffa9 bellard
                bad_card = 1;
8145 1d14ffa9 bellard
            }
8146 1d14ffa9 bellard
            p += l + (e != NULL);
8147 1d14ffa9 bellard
        }
8148 1d14ffa9 bellard
8149 1d14ffa9 bellard
        if (bad_card)
8150 1d14ffa9 bellard
            goto show_valid_cards;
8151 1d14ffa9 bellard
    }
8152 1d14ffa9 bellard
}
8153 1d14ffa9 bellard
#endif
8154 1d14ffa9 bellard
8155 3587d7e6 bellard
#ifdef _WIN32
8156 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
8157 3587d7e6 bellard
{
8158 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
8159 3587d7e6 bellard
    return TRUE;
8160 3587d7e6 bellard
}
8161 3587d7e6 bellard
#endif
8162 3587d7e6 bellard
8163 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
8164 c20709aa bellard
8165 0824d6fc bellard
int main(int argc, char **argv)
8166 0824d6fc bellard
{
8167 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8168 cfc3475a pbrook
    int use_gdbstub;
8169 cfc3475a pbrook
    const char *gdbstub_port;
8170 67b915a5 bellard
#endif
8171 28c5af54 j_mayer
    uint32_t boot_devices_bitmap = 0;
8172 e4bcb14c ths
    int i;
8173 28c5af54 j_mayer
    int snapshot, linux_boot, net_boot;
8174 7f7f9873 bellard
    const char *initrd_filename;
8175 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
8176 28c5af54 j_mayer
    const char *boot_devices = "";
8177 313aa567 bellard
    DisplayState *ds = &display_state;
8178 46d4767d bellard
    int cyls, heads, secs, translation;
8179 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
8180 7c9d8e07 bellard
    int nb_net_clients;
8181 e4bcb14c ths
    int hda_index;
8182 cd6f1169 bellard
    int optind;
8183 cd6f1169 bellard
    const char *r, *optarg;
8184 82c643ff bellard
    CharDriverState *monitor_hd;
8185 82c643ff bellard
    char monitor_device[128];
8186 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
8187 8d11df9e bellard
    int serial_device_index;
8188 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
8189 6508fe59 bellard
    int parallel_device_index;
8190 d63d307f bellard
    const char *loadvm = NULL;
8191 cc1daa40 bellard
    QEMUMachine *machine;
8192 94fc95cd j_mayer
    const char *cpu_model;
8193 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
8194 a594cfbf bellard
    int usb_devices_index;
8195 71e3ceb8 ths
    int fds[2];
8196 93815bc2 ths
    const char *pid_file = NULL;
8197 833c7174 blueswir1
    VLANState *vlan;
8198 0bd48850 bellard
8199 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
8200 be995c27 bellard
#ifndef _WIN32
8201 be995c27 bellard
    {
8202 be995c27 bellard
        struct sigaction act;
8203 be995c27 bellard
        sigfillset(&act.sa_mask);
8204 be995c27 bellard
        act.sa_flags = 0;
8205 be995c27 bellard
        act.sa_handler = SIG_IGN;
8206 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
8207 be995c27 bellard
    }
8208 3587d7e6 bellard
#else
8209 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
8210 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
8211 a8e5ac33 bellard
       QEMU to run on a single CPU */
8212 a8e5ac33 bellard
    {
8213 a8e5ac33 bellard
        HANDLE h;
8214 a8e5ac33 bellard
        DWORD mask, smask;
8215 a8e5ac33 bellard
        int i;
8216 a8e5ac33 bellard
        h = GetCurrentProcess();
8217 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
8218 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
8219 a8e5ac33 bellard
                if (mask & (1 << i))
8220 a8e5ac33 bellard
                    break;
8221 a8e5ac33 bellard
            }
8222 a8e5ac33 bellard
            if (i != 32) {
8223 a8e5ac33 bellard
                mask = 1 << i;
8224 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
8225 a8e5ac33 bellard
            }
8226 a8e5ac33 bellard
        }
8227 a8e5ac33 bellard
    }
8228 67b915a5 bellard
#endif
8229 be995c27 bellard
8230 cc1daa40 bellard
    register_machines();
8231 cc1daa40 bellard
    machine = first_machine;
8232 94fc95cd j_mayer
    cpu_model = NULL;
8233 fc01f7e7 bellard
    initrd_filename = NULL;
8234 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
8235 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
8236 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8237 b4608c04 bellard
    use_gdbstub = 0;
8238 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
8239 67b915a5 bellard
#endif
8240 33e3963e bellard
    snapshot = 0;
8241 a20dd508 bellard
    nographic = 0;
8242 4d3b6f6e balrog
    curses = 0;
8243 a20dd508 bellard
    kernel_filename = NULL;
8244 a20dd508 bellard
    kernel_cmdline = "";
8245 c4b1fcc0 bellard
    cyls = heads = secs = 0;
8246 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
8247 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
8248 c4b1fcc0 bellard
8249 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
8250 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
8251 8d11df9e bellard
        serial_devices[i][0] = '\0';
8252 8d11df9e bellard
    serial_device_index = 0;
8253 3b46e624 ths
8254 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
8255 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
8256 6508fe59 bellard
        parallel_devices[i][0] = '\0';
8257 6508fe59 bellard
    parallel_device_index = 0;
8258 3b46e624 ths
8259 a594cfbf bellard
    usb_devices_index = 0;
8260 3b46e624 ths
8261 7c9d8e07 bellard
    nb_net_clients = 0;
8262 e4bcb14c ths
    nb_drives = 0;
8263 e4bcb14c ths
    nb_drives_opt = 0;
8264 e4bcb14c ths
    hda_index = -1;
8265 7c9d8e07 bellard
8266 7c9d8e07 bellard
    nb_nics = 0;
8267 702c651c bellard
    /* default mac address of the first network interface */
8268 3b46e624 ths
8269 cd6f1169 bellard
    optind = 1;
8270 0824d6fc bellard
    for(;;) {
8271 cd6f1169 bellard
        if (optind >= argc)
8272 0824d6fc bellard
            break;
8273 cd6f1169 bellard
        r = argv[optind];
8274 cd6f1169 bellard
        if (r[0] != '-') {
8275 609497ab balrog
            hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
8276 cd6f1169 bellard
        } else {
8277 cd6f1169 bellard
            const QEMUOption *popt;
8278 cd6f1169 bellard
8279 cd6f1169 bellard
            optind++;
8280 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
8281 dff5efc8 pbrook
            if (r[1] == '-')
8282 dff5efc8 pbrook
                r++;
8283 cd6f1169 bellard
            popt = qemu_options;
8284 cd6f1169 bellard
            for(;;) {
8285 cd6f1169 bellard
                if (!popt->name) {
8286 5fafdf24 ths
                    fprintf(stderr, "%s: invalid option -- '%s'\n",
8287 cd6f1169 bellard
                            argv[0], r);
8288 cd6f1169 bellard
                    exit(1);
8289 cd6f1169 bellard
                }
8290 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
8291 cd6f1169 bellard
                    break;
8292 cd6f1169 bellard
                popt++;
8293 cd6f1169 bellard
            }
8294 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
8295 cd6f1169 bellard
                if (optind >= argc) {
8296 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
8297 cd6f1169 bellard
                            argv[0], r);
8298 cd6f1169 bellard
                    exit(1);
8299 cd6f1169 bellard
                }
8300 cd6f1169 bellard
                optarg = argv[optind++];
8301 cd6f1169 bellard
            } else {
8302 cd6f1169 bellard
                optarg = NULL;
8303 cd6f1169 bellard
            }
8304 cd6f1169 bellard
8305 cd6f1169 bellard
            switch(popt->index) {
8306 cc1daa40 bellard
            case QEMU_OPTION_M:
8307 cc1daa40 bellard
                machine = find_machine(optarg);
8308 cc1daa40 bellard
                if (!machine) {
8309 cc1daa40 bellard
                    QEMUMachine *m;
8310 cc1daa40 bellard
                    printf("Supported machines are:\n");
8311 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
8312 cc1daa40 bellard
                        printf("%-10s %s%s\n",
8313 5fafdf24 ths
                               m->name, m->desc,
8314 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
8315 cc1daa40 bellard
                    }
8316 15f82208 ths
                    exit(*optarg != '?');
8317 cc1daa40 bellard
                }
8318 cc1daa40 bellard
                break;
8319 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
8320 94fc95cd j_mayer
                /* hw initialization will check this */
8321 15f82208 ths
                if (*optarg == '?') {
8322 c732abe2 j_mayer
/* XXX: implement xxx_cpu_list for targets that still miss it */
8323 c732abe2 j_mayer
#if defined(cpu_list)
8324 c732abe2 j_mayer
                    cpu_list(stdout, &fprintf);
8325 94fc95cd j_mayer
#endif
8326 15f82208 ths
                    exit(0);
8327 94fc95cd j_mayer
                } else {
8328 94fc95cd j_mayer
                    cpu_model = optarg;
8329 94fc95cd j_mayer
                }
8330 94fc95cd j_mayer
                break;
8331 cd6f1169 bellard
            case QEMU_OPTION_initrd:
8332 fc01f7e7 bellard
                initrd_filename = optarg;
8333 fc01f7e7 bellard
                break;
8334 cd6f1169 bellard
            case QEMU_OPTION_hda:
8335 e4bcb14c ths
                if (cyls == 0)
8336 609497ab balrog
                    hda_index = drive_add(optarg, HD_ALIAS, 0);
8337 e4bcb14c ths
                else
8338 609497ab balrog
                    hda_index = drive_add(optarg, HD_ALIAS
8339 e4bcb14c ths
                             ",cyls=%d,heads=%d,secs=%d%s",
8340 609497ab balrog
                             0, cyls, heads, secs,
8341 e4bcb14c ths
                             translation == BIOS_ATA_TRANSLATION_LBA ?
8342 e4bcb14c ths
                                 ",trans=lba" :
8343 e4bcb14c ths
                             translation == BIOS_ATA_TRANSLATION_NONE ?
8344 e4bcb14c ths
                                 ",trans=none" : "");
8345 e4bcb14c ths
                 break;
8346 cd6f1169 bellard
            case QEMU_OPTION_hdb:
8347 cc1daa40 bellard
            case QEMU_OPTION_hdc:
8348 cc1daa40 bellard
            case QEMU_OPTION_hdd:
8349 609497ab balrog
                drive_add(optarg, HD_ALIAS, popt->index - QEMU_OPTION_hda);
8350 fc01f7e7 bellard
                break;
8351 e4bcb14c ths
            case QEMU_OPTION_drive:
8352 609497ab balrog
                drive_add(NULL, "%s", optarg);
8353 e4bcb14c ths
                break;
8354 3e3d5815 balrog
            case QEMU_OPTION_mtdblock:
8355 609497ab balrog
                drive_add(optarg, MTD_ALIAS);
8356 3e3d5815 balrog
                break;
8357 a1bb27b1 pbrook
            case QEMU_OPTION_sd:
8358 609497ab balrog
                drive_add(optarg, SD_ALIAS);
8359 a1bb27b1 pbrook
                break;
8360 86f55663 j_mayer
            case QEMU_OPTION_pflash:
8361 609497ab balrog
                drive_add(optarg, PFLASH_ALIAS);
8362 86f55663 j_mayer
                break;
8363 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
8364 33e3963e bellard
                snapshot = 1;
8365 33e3963e bellard
                break;
8366 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
8367 330d0414 bellard
                {
8368 330d0414 bellard
                    const char *p;
8369 330d0414 bellard
                    p = optarg;
8370 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
8371 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
8372 46d4767d bellard
                        goto chs_fail;
8373 330d0414 bellard
                    if (*p != ',')
8374 330d0414 bellard
                        goto chs_fail;
8375 330d0414 bellard
                    p++;
8376 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
8377 46d4767d bellard
                    if (heads < 1 || heads > 16)
8378 46d4767d bellard
                        goto chs_fail;
8379 330d0414 bellard
                    if (*p != ',')
8380 330d0414 bellard
                        goto chs_fail;
8381 330d0414 bellard
                    p++;
8382 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
8383 46d4767d bellard
                    if (secs < 1 || secs > 63)
8384 46d4767d bellard
                        goto chs_fail;
8385 46d4767d bellard
                    if (*p == ',') {
8386 46d4767d bellard
                        p++;
8387 46d4767d bellard
                        if (!strcmp(p, "none"))
8388 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
8389 46d4767d bellard
                        else if (!strcmp(p, "lba"))
8390 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
8391 46d4767d bellard
                        else if (!strcmp(p, "auto"))
8392 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
8393 46d4767d bellard
                        else
8394 46d4767d bellard
                            goto chs_fail;
8395 46d4767d bellard
                    } else if (*p != '\0') {
8396 c4b1fcc0 bellard
                    chs_fail:
8397 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
8398 46d4767d bellard
                        exit(1);
8399 c4b1fcc0 bellard
                    }
8400 e4bcb14c ths
                    if (hda_index != -1)
8401 609497ab balrog
                        snprintf(drives_opt[hda_index].opt,
8402 609497ab balrog
                                 sizeof(drives_opt[hda_index].opt),
8403 609497ab balrog
                                 HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
8404 609497ab balrog
                                 0, cyls, heads, secs,
8405 e4bcb14c ths
                                 translation == BIOS_ATA_TRANSLATION_LBA ?
8406 e4bcb14c ths
                                         ",trans=lba" :
8407 e4bcb14c ths
                                 translation == BIOS_ATA_TRANSLATION_NONE ?
8408 e4bcb14c ths
                                     ",trans=none" : "");
8409 330d0414 bellard
                }
8410 330d0414 bellard
                break;
8411 cd6f1169 bellard
            case QEMU_OPTION_nographic:
8412 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
8413 a39437aa ths
                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
8414 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
8415 a20dd508 bellard
                nographic = 1;
8416 a20dd508 bellard
                break;
8417 4d3b6f6e balrog
#ifdef CONFIG_CURSES
8418 4d3b6f6e balrog
            case QEMU_OPTION_curses:
8419 4d3b6f6e balrog
                curses = 1;
8420 4d3b6f6e balrog
                break;
8421 4d3b6f6e balrog
#endif
8422 a171fe39 balrog
            case QEMU_OPTION_portrait:
8423 a171fe39 balrog
                graphic_rotate = 1;
8424 a171fe39 balrog
                break;
8425 cd6f1169 bellard
            case QEMU_OPTION_kernel:
8426 a20dd508 bellard
                kernel_filename = optarg;
8427 a20dd508 bellard
                break;
8428 cd6f1169 bellard
            case QEMU_OPTION_append:
8429 a20dd508 bellard
                kernel_cmdline = optarg;
8430 313aa567 bellard
                break;
8431 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
8432 609497ab balrog
                drive_add(optarg, CDROM_ALIAS);
8433 36b486bb bellard
                break;
8434 cd6f1169 bellard
            case QEMU_OPTION_boot:
8435 28c5af54 j_mayer
                boot_devices = optarg;
8436 28c5af54 j_mayer
                /* We just do some generic consistency checks */
8437 28c5af54 j_mayer
                {
8438 28c5af54 j_mayer
                    /* Could easily be extended to 64 devices if needed */
8439 60fe76f3 ths
                    const char *p;
8440 28c5af54 j_mayer
                    
8441 28c5af54 j_mayer
                    boot_devices_bitmap = 0;
8442 28c5af54 j_mayer
                    for (p = boot_devices; *p != '\0'; p++) {
8443 28c5af54 j_mayer
                        /* Allowed boot devices are:
8444 28c5af54 j_mayer
                         * a b     : floppy disk drives
8445 28c5af54 j_mayer
                         * c ... f : IDE disk drives
8446 28c5af54 j_mayer
                         * g ... m : machine implementation dependant drives
8447 28c5af54 j_mayer
                         * n ... p : network devices
8448 28c5af54 j_mayer
                         * It's up to each machine implementation to check
8449 28c5af54 j_mayer
                         * if the given boot devices match the actual hardware
8450 28c5af54 j_mayer
                         * implementation and firmware features.
8451 28c5af54 j_mayer
                         */
8452 28c5af54 j_mayer
                        if (*p < 'a' || *p > 'q') {
8453 28c5af54 j_mayer
                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
8454 28c5af54 j_mayer
                            exit(1);
8455 28c5af54 j_mayer
                        }
8456 28c5af54 j_mayer
                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
8457 28c5af54 j_mayer
                            fprintf(stderr,
8458 28c5af54 j_mayer
                                    "Boot device '%c' was given twice\n",*p);
8459 28c5af54 j_mayer
                            exit(1);
8460 28c5af54 j_mayer
                        }
8461 28c5af54 j_mayer
                        boot_devices_bitmap |= 1 << (*p - 'a');
8462 28c5af54 j_mayer
                    }
8463 36b486bb bellard
                }
8464 36b486bb bellard
                break;
8465 cd6f1169 bellard
            case QEMU_OPTION_fda:
8466 cd6f1169 bellard
            case QEMU_OPTION_fdb:
8467 609497ab balrog
                drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda);
8468 c45886db bellard
                break;
8469 52ca8d6a bellard
#ifdef TARGET_I386
8470 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
8471 52ca8d6a bellard
                fd_bootchk = 0;
8472 52ca8d6a bellard
                break;
8473 52ca8d6a bellard
#endif
8474 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
8475 77fef8c1 bellard
                code_copy_enabled = 0;
8476 77fef8c1 bellard
                break;
8477 7c9d8e07 bellard
            case QEMU_OPTION_net:
8478 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
8479 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
8480 c4b1fcc0 bellard
                    exit(1);
8481 c4b1fcc0 bellard
                }
8482 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
8483 7c9d8e07 bellard
                        sizeof(net_clients[0]),
8484 7c9d8e07 bellard
                        optarg);
8485 7c9d8e07 bellard
                nb_net_clients++;
8486 702c651c bellard
                break;
8487 c7f74643 bellard
#ifdef CONFIG_SLIRP
8488 c7f74643 bellard
            case QEMU_OPTION_tftp:
8489 c7f74643 bellard
                tftp_prefix = optarg;
8490 9bf05444 bellard
                break;
8491 47d5d01a ths
            case QEMU_OPTION_bootp:
8492 47d5d01a ths
                bootp_filename = optarg;
8493 47d5d01a ths
                break;
8494 c94c8d64 bellard
#ifndef _WIN32
8495 9d728e8c bellard
            case QEMU_OPTION_smb:
8496 9d728e8c bellard
                net_slirp_smb(optarg);
8497 9d728e8c bellard
                break;
8498 c94c8d64 bellard
#endif
8499 9bf05444 bellard
            case QEMU_OPTION_redir:
8500 3b46e624 ths
                net_slirp_redir(optarg);
8501 9bf05444 bellard
                break;
8502 c7f74643 bellard
#endif
8503 1d14ffa9 bellard
#ifdef HAS_AUDIO
8504 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
8505 1d14ffa9 bellard
                AUD_help ();
8506 1d14ffa9 bellard
                exit (0);
8507 1d14ffa9 bellard
                break;
8508 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
8509 1d14ffa9 bellard
                select_soundhw (optarg);
8510 1d14ffa9 bellard
                break;
8511 1d14ffa9 bellard
#endif
8512 cd6f1169 bellard
            case QEMU_OPTION_h:
8513 15f82208 ths
                help(0);
8514 cd6f1169 bellard
                break;
8515 cd6f1169 bellard
            case QEMU_OPTION_m:
8516 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
8517 cd6f1169 bellard
                if (ram_size <= 0)
8518 15f82208 ths
                    help(1);
8519 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
8520 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
8521 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
8522 cd6f1169 bellard
                    exit(1);
8523 cd6f1169 bellard
                }
8524 cd6f1169 bellard
                break;
8525 cd6f1169 bellard
            case QEMU_OPTION_d:
8526 cd6f1169 bellard
                {
8527 cd6f1169 bellard
                    int mask;
8528 cd6f1169 bellard
                    CPULogItem *item;
8529 3b46e624 ths
8530 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
8531 cd6f1169 bellard
                    if (!mask) {
8532 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
8533 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
8534 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
8535 f193c797 bellard
                    }
8536 f193c797 bellard
                    exit(1);
8537 cd6f1169 bellard
                    }
8538 cd6f1169 bellard
                    cpu_set_log(mask);
8539 f193c797 bellard
                }
8540 cd6f1169 bellard
                break;
8541 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8542 cd6f1169 bellard
            case QEMU_OPTION_s:
8543 cd6f1169 bellard
                use_gdbstub = 1;
8544 cd6f1169 bellard
                break;
8545 cd6f1169 bellard
            case QEMU_OPTION_p:
8546 cfc3475a pbrook
                gdbstub_port = optarg;
8547 cd6f1169 bellard
                break;
8548 67b915a5 bellard
#endif
8549 cd6f1169 bellard
            case QEMU_OPTION_L:
8550 cd6f1169 bellard
                bios_dir = optarg;
8551 cd6f1169 bellard
                break;
8552 1192dad8 j_mayer
            case QEMU_OPTION_bios:
8553 1192dad8 j_mayer
                bios_name = optarg;
8554 1192dad8 j_mayer
                break;
8555 cd6f1169 bellard
            case QEMU_OPTION_S:
8556 3c07f8e8 pbrook
                autostart = 0;
8557 cd6f1169 bellard
                break;
8558 3d11d0eb bellard
            case QEMU_OPTION_k:
8559 3d11d0eb bellard
                keyboard_layout = optarg;
8560 3d11d0eb bellard
                break;
8561 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
8562 ee22c2f7 bellard
                rtc_utc = 0;
8563 ee22c2f7 bellard
                break;
8564 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
8565 1f04275e bellard
                cirrus_vga_enabled = 1;
8566 d34cab9f ths
                vmsvga_enabled = 0;
8567 d34cab9f ths
                break;
8568 d34cab9f ths
            case QEMU_OPTION_vmsvga:
8569 d34cab9f ths
                cirrus_vga_enabled = 0;
8570 d34cab9f ths
                vmsvga_enabled = 1;
8571 1f04275e bellard
                break;
8572 1bfe856e bellard
            case QEMU_OPTION_std_vga:
8573 1bfe856e bellard
                cirrus_vga_enabled = 0;
8574 d34cab9f ths
                vmsvga_enabled = 0;
8575 1bfe856e bellard
                break;
8576 e9b137c2 bellard
            case QEMU_OPTION_g:
8577 e9b137c2 bellard
                {
8578 e9b137c2 bellard
                    const char *p;
8579 e9b137c2 bellard
                    int w, h, depth;
8580 e9b137c2 bellard
                    p = optarg;
8581 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
8582 e9b137c2 bellard
                    if (w <= 0) {
8583 e9b137c2 bellard
                    graphic_error:
8584 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
8585 e9b137c2 bellard
                        exit(1);
8586 e9b137c2 bellard
                    }
8587 e9b137c2 bellard
                    if (*p != 'x')
8588 e9b137c2 bellard
                        goto graphic_error;
8589 e9b137c2 bellard
                    p++;
8590 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
8591 e9b137c2 bellard
                    if (h <= 0)
8592 e9b137c2 bellard
                        goto graphic_error;
8593 e9b137c2 bellard
                    if (*p == 'x') {
8594 e9b137c2 bellard
                        p++;
8595 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
8596 5fafdf24 ths
                        if (depth != 8 && depth != 15 && depth != 16 &&
8597 e9b137c2 bellard
                            depth != 24 && depth != 32)
8598 e9b137c2 bellard
                            goto graphic_error;
8599 e9b137c2 bellard
                    } else if (*p == '\0') {
8600 e9b137c2 bellard
                        depth = graphic_depth;
8601 e9b137c2 bellard
                    } else {
8602 e9b137c2 bellard
                        goto graphic_error;
8603 e9b137c2 bellard
                    }
8604 3b46e624 ths
8605 e9b137c2 bellard
                    graphic_width = w;
8606 e9b137c2 bellard
                    graphic_height = h;
8607 e9b137c2 bellard
                    graphic_depth = depth;
8608 e9b137c2 bellard
                }
8609 e9b137c2 bellard
                break;
8610 20d8a3ed ths
            case QEMU_OPTION_echr:
8611 20d8a3ed ths
                {
8612 20d8a3ed ths
                    char *r;
8613 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
8614 20d8a3ed ths
                    if (r == optarg)
8615 20d8a3ed ths
                        printf("Bad argument to echr\n");
8616 20d8a3ed ths
                    break;
8617 20d8a3ed ths
                }
8618 82c643ff bellard
            case QEMU_OPTION_monitor:
8619 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
8620 82c643ff bellard
                break;
8621 82c643ff bellard
            case QEMU_OPTION_serial:
8622 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
8623 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
8624 8d11df9e bellard
                    exit(1);
8625 8d11df9e bellard
                }
8626 5fafdf24 ths
                pstrcpy(serial_devices[serial_device_index],
8627 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
8628 8d11df9e bellard
                serial_device_index++;
8629 82c643ff bellard
                break;
8630 6508fe59 bellard
            case QEMU_OPTION_parallel:
8631 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
8632 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
8633 6508fe59 bellard
                    exit(1);
8634 6508fe59 bellard
                }
8635 5fafdf24 ths
                pstrcpy(parallel_devices[parallel_device_index],
8636 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
8637 6508fe59 bellard
                parallel_device_index++;
8638 6508fe59 bellard
                break;
8639 d63d307f bellard
            case QEMU_OPTION_loadvm:
8640 d63d307f bellard
                loadvm = optarg;
8641 d63d307f bellard
                break;
8642 d63d307f bellard
            case QEMU_OPTION_full_screen:
8643 d63d307f bellard
                full_screen = 1;
8644 d63d307f bellard
                break;
8645 667accab ths
#ifdef CONFIG_SDL
8646 43523e93 ths
            case QEMU_OPTION_no_frame:
8647 43523e93 ths
                no_frame = 1;
8648 43523e93 ths
                break;
8649 3780e197 ths
            case QEMU_OPTION_alt_grab:
8650 3780e197 ths
                alt_grab = 1;
8651 3780e197 ths
                break;
8652 667accab ths
            case QEMU_OPTION_no_quit:
8653 667accab ths
                no_quit = 1;
8654 667accab ths
                break;
8655 667accab ths
#endif
8656 f7cce898 bellard
            case QEMU_OPTION_pidfile:
8657 93815bc2 ths
                pid_file = optarg;
8658 f7cce898 bellard
                break;
8659 a09db21f bellard
#ifdef TARGET_I386
8660 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
8661 a09db21f bellard
                win2k_install_hack = 1;
8662 a09db21f bellard
                break;
8663 a09db21f bellard
#endif
8664 d993e026 bellard
#ifdef USE_KQEMU
8665 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
8666 d993e026 bellard
                kqemu_allowed = 0;
8667 d993e026 bellard
                break;
8668 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
8669 89bfc105 bellard
                kqemu_allowed = 2;
8670 89bfc105 bellard
                break;
8671 d993e026 bellard
#endif
8672 bb36d470 bellard
            case QEMU_OPTION_usb:
8673 bb36d470 bellard
                usb_enabled = 1;
8674 bb36d470 bellard
                break;
8675 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
8676 a594cfbf bellard
                usb_enabled = 1;
8677 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
8678 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
8679 a594cfbf bellard
                    exit(1);
8680 a594cfbf bellard
                }
8681 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
8682 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
8683 a594cfbf bellard
                        optarg);
8684 a594cfbf bellard
                usb_devices_index++;
8685 a594cfbf bellard
                break;
8686 6a00d601 bellard
            case QEMU_OPTION_smp:
8687 6a00d601 bellard
                smp_cpus = atoi(optarg);
8688 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
8689 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
8690 6a00d601 bellard
                    exit(1);
8691 6a00d601 bellard
                }
8692 6a00d601 bellard
                break;
8693 24236869 bellard
            case QEMU_OPTION_vnc:
8694 73fc9742 ths
                vnc_display = optarg;
8695 24236869 bellard
                break;
8696 6515b203 bellard
            case QEMU_OPTION_no_acpi:
8697 6515b203 bellard
                acpi_enabled = 0;
8698 6515b203 bellard
                break;
8699 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
8700 d1beab82 bellard
                no_reboot = 1;
8701 d1beab82 bellard
                break;
8702 9467cd46 balrog
            case QEMU_OPTION_show_cursor:
8703 9467cd46 balrog
                cursor_hide = 0;
8704 9467cd46 balrog
                break;
8705 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
8706 71e3ceb8 ths
                daemonize = 1;
8707 71e3ceb8 ths
                break;
8708 9ae02555 ths
            case QEMU_OPTION_option_rom:
8709 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
8710 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
8711 9ae02555 ths
                    exit(1);
8712 9ae02555 ths
                }
8713 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
8714 9ae02555 ths
                nb_option_roms++;
8715 9ae02555 ths
                break;
8716 8e71621f pbrook
            case QEMU_OPTION_semihosting:
8717 8e71621f pbrook
                semihosting_enabled = 1;
8718 8e71621f pbrook
                break;
8719 c35734b2 ths
            case QEMU_OPTION_name:
8720 c35734b2 ths
                qemu_name = optarg;
8721 c35734b2 ths
                break;
8722 66508601 blueswir1
#ifdef TARGET_SPARC
8723 66508601 blueswir1
            case QEMU_OPTION_prom_env:
8724 66508601 blueswir1
                if (nb_prom_envs >= MAX_PROM_ENVS) {
8725 66508601 blueswir1
                    fprintf(stderr, "Too many prom variables\n");
8726 66508601 blueswir1
                    exit(1);
8727 66508601 blueswir1
                }
8728 66508601 blueswir1
                prom_envs[nb_prom_envs] = optarg;
8729 66508601 blueswir1
                nb_prom_envs++;
8730 66508601 blueswir1
                break;
8731 66508601 blueswir1
#endif
8732 2b8f2d41 balrog
#ifdef TARGET_ARM
8733 2b8f2d41 balrog
            case QEMU_OPTION_old_param:
8734 2b8f2d41 balrog
                old_param = 1;
8735 05ebd537 ths
                break;
8736 2b8f2d41 balrog
#endif
8737 f3dcfada ths
            case QEMU_OPTION_clock:
8738 f3dcfada ths
                configure_alarms(optarg);
8739 f3dcfada ths
                break;
8740 7e0af5d0 bellard
            case QEMU_OPTION_startdate:
8741 7e0af5d0 bellard
                {
8742 7e0af5d0 bellard
                    struct tm tm;
8743 f6503059 balrog
                    time_t rtc_start_date;
8744 7e0af5d0 bellard
                    if (!strcmp(optarg, "now")) {
8745 f6503059 balrog
                        rtc_date_offset = -1;
8746 7e0af5d0 bellard
                    } else {
8747 7e0af5d0 bellard
                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8748 7e0af5d0 bellard
                               &tm.tm_year,
8749 7e0af5d0 bellard
                               &tm.tm_mon,
8750 7e0af5d0 bellard
                               &tm.tm_mday,
8751 7e0af5d0 bellard
                               &tm.tm_hour,
8752 7e0af5d0 bellard
                               &tm.tm_min,
8753 7e0af5d0 bellard
                               &tm.tm_sec) == 6) {
8754 7e0af5d0 bellard
                            /* OK */
8755 7e0af5d0 bellard
                        } else if (sscanf(optarg, "%d-%d-%d",
8756 7e0af5d0 bellard
                                          &tm.tm_year,
8757 7e0af5d0 bellard
                                          &tm.tm_mon,
8758 7e0af5d0 bellard
                                          &tm.tm_mday) == 3) {
8759 7e0af5d0 bellard
                            tm.tm_hour = 0;
8760 7e0af5d0 bellard
                            tm.tm_min = 0;
8761 7e0af5d0 bellard
                            tm.tm_sec = 0;
8762 7e0af5d0 bellard
                        } else {
8763 7e0af5d0 bellard
                            goto date_fail;
8764 7e0af5d0 bellard
                        }
8765 7e0af5d0 bellard
                        tm.tm_year -= 1900;
8766 7e0af5d0 bellard
                        tm.tm_mon--;
8767 3c6b2088 bellard
                        rtc_start_date = mktimegm(&tm);
8768 7e0af5d0 bellard
                        if (rtc_start_date == -1) {
8769 7e0af5d0 bellard
                        date_fail:
8770 7e0af5d0 bellard
                            fprintf(stderr, "Invalid date format. Valid format are:\n"
8771 7e0af5d0 bellard
                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8772 7e0af5d0 bellard
                            exit(1);
8773 7e0af5d0 bellard
                        }
8774 f6503059 balrog
                        rtc_date_offset = time(NULL) - rtc_start_date;
8775 7e0af5d0 bellard
                    }
8776 7e0af5d0 bellard
                }
8777 7e0af5d0 bellard
                break;
8778 cd6f1169 bellard
            }
8779 0824d6fc bellard
        }
8780 0824d6fc bellard
    }
8781 330d0414 bellard
8782 71e3ceb8 ths
#ifndef _WIN32
8783 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
8784 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
8785 71e3ceb8 ths
        daemonize = 0;
8786 71e3ceb8 ths
    }
8787 71e3ceb8 ths
8788 71e3ceb8 ths
    if (daemonize) {
8789 71e3ceb8 ths
        pid_t pid;
8790 71e3ceb8 ths
8791 71e3ceb8 ths
        if (pipe(fds) == -1)
8792 71e3ceb8 ths
            exit(1);
8793 71e3ceb8 ths
8794 71e3ceb8 ths
        pid = fork();
8795 71e3ceb8 ths
        if (pid > 0) {
8796 71e3ceb8 ths
            uint8_t status;
8797 71e3ceb8 ths
            ssize_t len;
8798 71e3ceb8 ths
8799 71e3ceb8 ths
            close(fds[1]);
8800 71e3ceb8 ths
8801 71e3ceb8 ths
        again:
8802 93815bc2 ths
            len = read(fds[0], &status, 1);
8803 93815bc2 ths
            if (len == -1 && (errno == EINTR))
8804 93815bc2 ths
                goto again;
8805 93815bc2 ths
8806 93815bc2 ths
            if (len != 1)
8807 93815bc2 ths
                exit(1);
8808 93815bc2 ths
            else if (status == 1) {
8809 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
8810 93815bc2 ths
                exit(1);
8811 93815bc2 ths
            } else
8812 93815bc2 ths
                exit(0);
8813 71e3ceb8 ths
        } else if (pid < 0)
8814 93815bc2 ths
            exit(1);
8815 71e3ceb8 ths
8816 71e3ceb8 ths
        setsid();
8817 71e3ceb8 ths
8818 71e3ceb8 ths
        pid = fork();
8819 71e3ceb8 ths
        if (pid > 0)
8820 71e3ceb8 ths
            exit(0);
8821 71e3ceb8 ths
        else if (pid < 0)
8822 71e3ceb8 ths
            exit(1);
8823 71e3ceb8 ths
8824 71e3ceb8 ths
        umask(027);
8825 71e3ceb8 ths
        chdir("/");
8826 71e3ceb8 ths
8827 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
8828 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
8829 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
8830 71e3ceb8 ths
    }
8831 71e3ceb8 ths
#endif
8832 71e3ceb8 ths
8833 aa26bb2d ths
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
8834 93815bc2 ths
        if (daemonize) {
8835 93815bc2 ths
            uint8_t status = 1;
8836 93815bc2 ths
            write(fds[1], &status, 1);
8837 93815bc2 ths
        } else
8838 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
8839 93815bc2 ths
        exit(1);
8840 93815bc2 ths
    }
8841 93815bc2 ths
8842 ff3fbb30 bellard
#ifdef USE_KQEMU
8843 ff3fbb30 bellard
    if (smp_cpus > 1)
8844 ff3fbb30 bellard
        kqemu_allowed = 0;
8845 ff3fbb30 bellard
#endif
8846 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
8847 7317b8ca balrog
    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
8848 6c41b272 balrog
8849 28c5af54 j_mayer
    /* XXX: this should not be: some embedded targets just have flash */
8850 28c5af54 j_mayer
    if (!linux_boot && net_boot == 0 &&
8851 e4bcb14c ths
        nb_drives_opt == 0)
8852 15f82208 ths
        help(1);
8853 0824d6fc bellard
8854 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
8855 28c5af54 j_mayer
    if (!boot_devices[0]) {
8856 e4bcb14c ths
        boot_devices = "cad";
8857 96d30e48 ths
    }
8858 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
8859 3b46e624 ths
8860 634fce96 pbrook
    init_timers();
8861 634fce96 pbrook
    init_timer_alarm();
8862 83f64091 bellard
    qemu_aio_init();
8863 634fce96 pbrook
8864 fd1dff4b bellard
#ifdef _WIN32
8865 fd1dff4b bellard
    socket_init();
8866 fd1dff4b bellard
#endif
8867 fd1dff4b bellard
8868 7c9d8e07 bellard
    /* init network clients */
8869 7c9d8e07 bellard
    if (nb_net_clients == 0) {
8870 7c9d8e07 bellard
        /* if no clients, we use a default config */
8871 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
8872 7c9d8e07 bellard
                "nic");
8873 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
8874 7c9d8e07 bellard
                "user");
8875 7c9d8e07 bellard
        nb_net_clients = 2;
8876 c20709aa bellard
    }
8877 c20709aa bellard
8878 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
8879 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
8880 7c9d8e07 bellard
            exit(1);
8881 702c651c bellard
    }
8882 833c7174 blueswir1
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8883 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8884 833c7174 blueswir1
            continue;
8885 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0) {
8886 833c7174 blueswir1
            fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
8887 833c7174 blueswir1
            exit(1);
8888 833c7174 blueswir1
        }
8889 833c7174 blueswir1
        if (vlan->nb_host_devs == 0)
8890 833c7174 blueswir1
            fprintf(stderr,
8891 833c7174 blueswir1
                    "Warning: vlan %d is not connected to host network\n",
8892 833c7174 blueswir1
                    vlan->id);
8893 833c7174 blueswir1
    }
8894 f1510b2c bellard
8895 eec85c2a ths
#ifdef TARGET_I386
8896 ed494d87 balrog
    /* XXX: this should be moved in the PC machine instantiation code */
8897 28c5af54 j_mayer
    if (net_boot != 0) {
8898 28c5af54 j_mayer
        int netroms = 0;
8899 28c5af54 j_mayer
        for (i = 0; i < nb_nics && i < 4; i++) {
8900 eec85c2a ths
            const char *model = nd_table[i].model;
8901 eec85c2a ths
            char buf[1024];
8902 28c5af54 j_mayer
            if (net_boot & (1 << i)) {
8903 28c5af54 j_mayer
                if (model == NULL)
8904 28c5af54 j_mayer
                    model = "ne2k_pci";
8905 28c5af54 j_mayer
                snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8906 28c5af54 j_mayer
                if (get_image_size(buf) > 0) {
8907 28c5af54 j_mayer
                    if (nb_option_roms >= MAX_OPTION_ROMS) {
8908 28c5af54 j_mayer
                        fprintf(stderr, "Too many option ROMs\n");
8909 28c5af54 j_mayer
                        exit(1);
8910 28c5af54 j_mayer
                    }
8911 28c5af54 j_mayer
                    option_rom[nb_option_roms] = strdup(buf);
8912 28c5af54 j_mayer
                    nb_option_roms++;
8913 28c5af54 j_mayer
                    netroms++;
8914 28c5af54 j_mayer
                }
8915 28c5af54 j_mayer
            }
8916 eec85c2a ths
        }
8917 28c5af54 j_mayer
        if (netroms == 0) {
8918 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
8919 eec85c2a ths
            exit(1);
8920 eec85c2a ths
        }
8921 eec85c2a ths
    }
8922 eec85c2a ths
#endif
8923 eec85c2a ths
8924 0824d6fc bellard
    /* init the memory */
8925 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
8926 9ae02555 ths
8927 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
8928 7f7f9873 bellard
    if (!phys_ram_base) {
8929 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
8930 0824d6fc bellard
        exit(1);
8931 0824d6fc bellard
    }
8932 0824d6fc bellard
8933 5905b2e5 bellard
    bdrv_init();
8934 c4b1fcc0 bellard
8935 e4bcb14c ths
    /* we always create the cdrom drive, even if no disk is there */
8936 c4b1fcc0 bellard
8937 e4bcb14c ths
    if (nb_drives_opt < MAX_DRIVES)
8938 609497ab balrog
        drive_add(NULL, CDROM_ALIAS);
8939 c4b1fcc0 bellard
8940 9d413d1d balrog
    /* we always create at least one floppy */
8941 33e3963e bellard
8942 e4bcb14c ths
    if (nb_drives_opt < MAX_DRIVES)
8943 609497ab balrog
        drive_add(NULL, FD_ALIAS, 0);
8944 86f55663 j_mayer
8945 9d413d1d balrog
    /* we always create one sd slot, even if no card is in it */
8946 9d413d1d balrog
8947 9d413d1d balrog
    if (nb_drives_opt < MAX_DRIVES)
8948 609497ab balrog
        drive_add(NULL, SD_ALIAS);
8949 9d413d1d balrog
8950 e4bcb14c ths
    /* open the virtual block devices */
8951 e4bcb14c ths
8952 e4bcb14c ths
    for(i = 0; i < nb_drives_opt; i++)
8953 609497ab balrog
        if (drive_init(&drives_opt[i], snapshot, machine) == -1)
8954 e4bcb14c ths
            exit(1);
8955 3e3d5815 balrog
8956 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
8957 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
8958 8a7ddc38 bellard
8959 330d0414 bellard
    init_ioports();
8960 0824d6fc bellard
8961 313aa567 bellard
    /* terminal init */
8962 740733bb ths
    memset(&display_state, 0, sizeof(display_state));
8963 a20dd508 bellard
    if (nographic) {
8964 4d3b6f6e balrog
        if (curses) {
8965 4d3b6f6e balrog
            fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
8966 4d3b6f6e balrog
            exit(1);
8967 4d3b6f6e balrog
        }
8968 2ff89790 ths
        /* nearly nothing to do */
8969 2ff89790 ths
        dumb_display_init(ds);
8970 73fc9742 ths
    } else if (vnc_display != NULL) {
8971 71cab5ca ths
        vnc_display_init(ds);
8972 71cab5ca ths
        if (vnc_display_open(ds, vnc_display) < 0)
8973 71cab5ca ths
            exit(1);
8974 4d3b6f6e balrog
    } else
8975 4d3b6f6e balrog
#if defined(CONFIG_CURSES)
8976 4d3b6f6e balrog
    if (curses) {
8977 4d3b6f6e balrog
        curses_display_init(ds, full_screen);
8978 4d3b6f6e balrog
    } else
8979 4d3b6f6e balrog
#endif
8980 4d3b6f6e balrog
    {
8981 5b0753e0 bellard
#if defined(CONFIG_SDL)
8982 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
8983 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
8984 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
8985 67276f53 pbrook
#else
8986 67276f53 pbrook
        dumb_display_init(ds);
8987 313aa567 bellard
#endif
8988 313aa567 bellard
    }
8989 0824d6fc bellard
8990 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
8991 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
8992 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
8993 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
8994 20d8a3ed ths
                monitor_device[0] = '\0';
8995 20d8a3ed ths
                break;
8996 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
8997 20d8a3ed ths
                monitor_device[0] = '\0';
8998 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
8999 20d8a3ed ths
                break;
9000 20d8a3ed ths
            }
9001 20d8a3ed ths
        }
9002 20d8a3ed ths
    }
9003 20d8a3ed ths
    if (monitor_device[0] != '\0') {
9004 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
9005 20d8a3ed ths
        if (!monitor_hd) {
9006 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
9007 20d8a3ed ths
            exit(1);
9008 20d8a3ed ths
        }
9009 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
9010 82c643ff bellard
    }
9011 82c643ff bellard
9012 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
9013 c03b0f0f bellard
        const char *devname = serial_devices[i];
9014 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
9015 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
9016 8d11df9e bellard
            if (!serial_hds[i]) {
9017 5fafdf24 ths
                fprintf(stderr, "qemu: could not open serial device '%s'\n",
9018 c03b0f0f bellard
                        devname);
9019 8d11df9e bellard
                exit(1);
9020 8d11df9e bellard
            }
9021 af3a9031 ths
            if (strstart(devname, "vc", 0))
9022 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
9023 8d11df9e bellard
        }
9024 82c643ff bellard
    }
9025 82c643ff bellard
9026 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
9027 c03b0f0f bellard
        const char *devname = parallel_devices[i];
9028 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
9029 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
9030 6508fe59 bellard
            if (!parallel_hds[i]) {
9031 5fafdf24 ths
                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
9032 c03b0f0f bellard
                        devname);
9033 6508fe59 bellard
                exit(1);
9034 6508fe59 bellard
            }
9035 af3a9031 ths
            if (strstart(devname, "vc", 0))
9036 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
9037 6508fe59 bellard
        }
9038 6508fe59 bellard
    }
9039 6508fe59 bellard
9040 b881c2c6 blueswir1
    machine->init(ram_size, vga_ram_size, boot_devices, ds,
9041 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
9042 73332e5c bellard
9043 0d92ed30 pbrook
    /* init USB devices */
9044 0d92ed30 pbrook
    if (usb_enabled) {
9045 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
9046 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
9047 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
9048 0d92ed30 pbrook
                        usb_devices[i]);
9049 0d92ed30 pbrook
            }
9050 0d92ed30 pbrook
        }
9051 0d92ed30 pbrook
    }
9052 0d92ed30 pbrook
9053 740733bb ths
    if (display_state.dpy_refresh) {
9054 740733bb ths
        display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
9055 740733bb ths
        qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
9056 740733bb ths
    }
9057 7f7f9873 bellard
9058 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
9059 b4608c04 bellard
    if (use_gdbstub) {
9060 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
9061 c636bb66 bellard
           accordingly. */
9062 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
9063 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
9064 c636bb66 bellard
                    gdbstub_port);
9065 8a7ddc38 bellard
            exit(1);
9066 8a7ddc38 bellard
        }
9067 45669e00 balrog
    }
9068 67b915a5 bellard
#endif
9069 45669e00 balrog
9070 d63d307f bellard
    if (loadvm)
9071 faea38e7 bellard
        do_loadvm(loadvm);
9072 d63d307f bellard
9073 67b915a5 bellard
    {
9074 5905b2e5 bellard
        /* XXX: simplify init */
9075 5905b2e5 bellard
        read_passwords();
9076 3c07f8e8 pbrook
        if (autostart) {
9077 5905b2e5 bellard
            vm_start();
9078 5905b2e5 bellard
        }
9079 0824d6fc bellard
    }
9080 ffd843bc ths
9081 71e3ceb8 ths
    if (daemonize) {
9082 71e3ceb8 ths
        uint8_t status = 0;
9083 71e3ceb8 ths
        ssize_t len;
9084 71e3ceb8 ths
        int fd;
9085 71e3ceb8 ths
9086 71e3ceb8 ths
    again1:
9087 71e3ceb8 ths
        len = write(fds[1], &status, 1);
9088 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
9089 71e3ceb8 ths
            goto again1;
9090 71e3ceb8 ths
9091 71e3ceb8 ths
        if (len != 1)
9092 71e3ceb8 ths
            exit(1);
9093 71e3ceb8 ths
9094 aeb30be6 balrog
        TFR(fd = open("/dev/null", O_RDWR));
9095 71e3ceb8 ths
        if (fd == -1)
9096 71e3ceb8 ths
            exit(1);
9097 71e3ceb8 ths
9098 71e3ceb8 ths
        dup2(fd, 0);
9099 71e3ceb8 ths
        dup2(fd, 1);
9100 71e3ceb8 ths
        dup2(fd, 2);
9101 71e3ceb8 ths
9102 71e3ceb8 ths
        close(fd);
9103 71e3ceb8 ths
    }
9104 71e3ceb8 ths
9105 8a7ddc38 bellard
    main_loop();
9106 40c3bac3 bellard
    quit_timers();
9107 b46a8906 ths
9108 7d294b61 ths
#if !defined(_WIN32)
9109 b46a8906 ths
    /* close network clients */
9110 b46a8906 ths
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
9111 b46a8906 ths
        VLANClientState *vc;
9112 b46a8906 ths
9113 7d294b61 ths
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
9114 b46a8906 ths
            if (vc->fd_read == tap_receive) {
9115 b46a8906 ths
                char ifname[64];
9116 b46a8906 ths
                TAPState *s = vc->opaque;
9117 b46a8906 ths
9118 b46a8906 ths
                if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
9119 b46a8906 ths
                    s->down_script[0])
9120 b46a8906 ths
                    launch_script(s->down_script, ifname, s->fd);
9121 b46a8906 ths
            }
9122 4fddf62a ths
        }
9123 7d294b61 ths
    }
9124 7d294b61 ths
#endif
9125 0824d6fc bellard
    return 0;
9126 0824d6fc bellard
}