Statistics
| Branch: | Revision:

root / vl.c @ cf7a2fe2

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