Statistics
| Branch: | Revision:

root / vl.c @ 5fafdf24

History | View | Annotate | Download (216.8 kB)

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

6412 c88676f8 bellard
            /* find if the memory block is available on a virtual
6413 c88676f8 bellard
               block device */
6414 c88676f8 bellard
            sector_num = -1;
6415 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
6416 c88676f8 bellard
                if (bs_table[j]) {
6417 5fafdf24 ths
                    sector_num = bdrv_hash_find(bs_table[j],
6418 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6419 c88676f8 bellard
                    if (sector_num >= 0)
6420 c88676f8 bellard
                        break;
6421 c88676f8 bellard
                }
6422 c88676f8 bellard
            }
6423 c88676f8 bellard
            if (j == MAX_DISKS)
6424 c88676f8 bellard
                goto normal_compress;
6425 c88676f8 bellard
            buf[0] = 1;
6426 c88676f8 bellard
            buf[1] = j;
6427 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
6428 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
6429 5fafdf24 ths
        } else
6430 c88676f8 bellard
#endif
6431 c88676f8 bellard
        {
6432 c88676f8 bellard
            //        normal_compress:
6433 c88676f8 bellard
            buf[0] = 0;
6434 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
6435 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6436 c88676f8 bellard
        }
6437 8a7ddc38 bellard
    }
6438 c88676f8 bellard
    ram_compress_close(s);
6439 8a7ddc38 bellard
}
6440 8a7ddc38 bellard
6441 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
6442 8a7ddc38 bellard
{
6443 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
6444 c88676f8 bellard
    uint8_t buf[10];
6445 c88676f8 bellard
    int i;
6446 8a7ddc38 bellard
6447 c88676f8 bellard
    if (version_id == 1)
6448 c88676f8 bellard
        return ram_load_v1(f, opaque);
6449 c88676f8 bellard
    if (version_id != 2)
6450 8a7ddc38 bellard
        return -EINVAL;
6451 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6452 8a7ddc38 bellard
        return -EINVAL;
6453 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
6454 c88676f8 bellard
        return -EINVAL;
6455 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6456 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
6457 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
6458 c88676f8 bellard
            goto error;
6459 c88676f8 bellard
        }
6460 c88676f8 bellard
        if (buf[0] == 0) {
6461 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
6462 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
6463 c88676f8 bellard
                goto error;
6464 c88676f8 bellard
            }
6465 5fafdf24 ths
        } else
6466 c88676f8 bellard
#if 0
6467 c88676f8 bellard
        if (buf[0] == 1) {
6468 c88676f8 bellard
            int bs_index;
6469 c88676f8 bellard
            int64_t sector_num;
6470 c88676f8 bellard

6471 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
6472 c88676f8 bellard
            bs_index = buf[1];
6473 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
6474 c88676f8 bellard
            if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
6475 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
6476 c88676f8 bellard
                goto error;
6477 c88676f8 bellard
            }
6478 5fafdf24 ths
            if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i,
6479 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
6480 5fafdf24 ths
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
6481 c88676f8 bellard
                        bs_index, sector_num);
6482 c88676f8 bellard
                goto error;
6483 c88676f8 bellard
            }
6484 5fafdf24 ths
        } else
6485 c88676f8 bellard
#endif
6486 c88676f8 bellard
        {
6487 c88676f8 bellard
        error:
6488 c88676f8 bellard
            printf("Error block header\n");
6489 c88676f8 bellard
            return -EINVAL;
6490 c88676f8 bellard
        }
6491 8a7ddc38 bellard
    }
6492 c88676f8 bellard
    ram_decompress_close(s);
6493 8a7ddc38 bellard
    return 0;
6494 8a7ddc38 bellard
}
6495 8a7ddc38 bellard
6496 8a7ddc38 bellard
/***********************************************************/
6497 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
6498 83f64091 bellard
6499 83f64091 bellard
struct QEMUBH {
6500 83f64091 bellard
    QEMUBHFunc *cb;
6501 83f64091 bellard
    void *opaque;
6502 83f64091 bellard
    int scheduled;
6503 83f64091 bellard
    QEMUBH *next;
6504 83f64091 bellard
};
6505 83f64091 bellard
6506 83f64091 bellard
static QEMUBH *first_bh = NULL;
6507 83f64091 bellard
6508 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
6509 83f64091 bellard
{
6510 83f64091 bellard
    QEMUBH *bh;
6511 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
6512 83f64091 bellard
    if (!bh)
6513 83f64091 bellard
        return NULL;
6514 83f64091 bellard
    bh->cb = cb;
6515 83f64091 bellard
    bh->opaque = opaque;
6516 83f64091 bellard
    return bh;
6517 83f64091 bellard
}
6518 83f64091 bellard
6519 6eb5733a bellard
int qemu_bh_poll(void)
6520 83f64091 bellard
{
6521 83f64091 bellard
    QEMUBH *bh, **pbh;
6522 6eb5733a bellard
    int ret;
6523 83f64091 bellard
6524 6eb5733a bellard
    ret = 0;
6525 83f64091 bellard
    for(;;) {
6526 83f64091 bellard
        pbh = &first_bh;
6527 83f64091 bellard
        bh = *pbh;
6528 83f64091 bellard
        if (!bh)
6529 83f64091 bellard
            break;
6530 6eb5733a bellard
        ret = 1;
6531 83f64091 bellard
        *pbh = bh->next;
6532 83f64091 bellard
        bh->scheduled = 0;
6533 83f64091 bellard
        bh->cb(bh->opaque);
6534 83f64091 bellard
    }
6535 6eb5733a bellard
    return ret;
6536 83f64091 bellard
}
6537 83f64091 bellard
6538 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
6539 83f64091 bellard
{
6540 83f64091 bellard
    CPUState *env = cpu_single_env;
6541 83f64091 bellard
    if (bh->scheduled)
6542 83f64091 bellard
        return;
6543 83f64091 bellard
    bh->scheduled = 1;
6544 83f64091 bellard
    bh->next = first_bh;
6545 83f64091 bellard
    first_bh = bh;
6546 83f64091 bellard
6547 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
6548 83f64091 bellard
    if (env) {
6549 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
6550 83f64091 bellard
    }
6551 83f64091 bellard
}
6552 83f64091 bellard
6553 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
6554 83f64091 bellard
{
6555 83f64091 bellard
    QEMUBH **pbh;
6556 83f64091 bellard
    if (bh->scheduled) {
6557 83f64091 bellard
        pbh = &first_bh;
6558 83f64091 bellard
        while (*pbh != bh)
6559 83f64091 bellard
            pbh = &(*pbh)->next;
6560 83f64091 bellard
        *pbh = bh->next;
6561 83f64091 bellard
        bh->scheduled = 0;
6562 83f64091 bellard
    }
6563 83f64091 bellard
}
6564 83f64091 bellard
6565 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
6566 83f64091 bellard
{
6567 83f64091 bellard
    qemu_bh_cancel(bh);
6568 83f64091 bellard
    qemu_free(bh);
6569 83f64091 bellard
}
6570 83f64091 bellard
6571 83f64091 bellard
/***********************************************************/
6572 cc1daa40 bellard
/* machine registration */
6573 cc1daa40 bellard
6574 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
6575 cc1daa40 bellard
6576 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
6577 cc1daa40 bellard
{
6578 cc1daa40 bellard
    QEMUMachine **pm;
6579 cc1daa40 bellard
    pm = &first_machine;
6580 cc1daa40 bellard
    while (*pm != NULL)
6581 cc1daa40 bellard
        pm = &(*pm)->next;
6582 cc1daa40 bellard
    m->next = NULL;
6583 cc1daa40 bellard
    *pm = m;
6584 cc1daa40 bellard
    return 0;
6585 cc1daa40 bellard
}
6586 cc1daa40 bellard
6587 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
6588 cc1daa40 bellard
{
6589 cc1daa40 bellard
    QEMUMachine *m;
6590 cc1daa40 bellard
6591 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
6592 cc1daa40 bellard
        if (!strcmp(m->name, name))
6593 cc1daa40 bellard
            return m;
6594 cc1daa40 bellard
    }
6595 cc1daa40 bellard
    return NULL;
6596 cc1daa40 bellard
}
6597 cc1daa40 bellard
6598 cc1daa40 bellard
/***********************************************************/
6599 8a7ddc38 bellard
/* main execution loop */
6600 8a7ddc38 bellard
6601 8a7ddc38 bellard
void gui_update(void *opaque)
6602 8a7ddc38 bellard
{
6603 740733bb ths
    DisplayState *ds = opaque;
6604 740733bb ths
    ds->dpy_refresh(ds);
6605 740733bb ths
    qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
6606 8a7ddc38 bellard
}
6607 8a7ddc38 bellard
6608 0bd48850 bellard
struct vm_change_state_entry {
6609 0bd48850 bellard
    VMChangeStateHandler *cb;
6610 0bd48850 bellard
    void *opaque;
6611 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
6612 0bd48850 bellard
};
6613 0bd48850 bellard
6614 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
6615 0bd48850 bellard
6616 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
6617 0bd48850 bellard
                                                     void *opaque)
6618 0bd48850 bellard
{
6619 0bd48850 bellard
    VMChangeStateEntry *e;
6620 0bd48850 bellard
6621 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
6622 0bd48850 bellard
    if (!e)
6623 0bd48850 bellard
        return NULL;
6624 0bd48850 bellard
6625 0bd48850 bellard
    e->cb = cb;
6626 0bd48850 bellard
    e->opaque = opaque;
6627 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
6628 0bd48850 bellard
    return e;
6629 0bd48850 bellard
}
6630 0bd48850 bellard
6631 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
6632 0bd48850 bellard
{
6633 0bd48850 bellard
    LIST_REMOVE (e, entries);
6634 0bd48850 bellard
    qemu_free (e);
6635 0bd48850 bellard
}
6636 0bd48850 bellard
6637 0bd48850 bellard
static void vm_state_notify(int running)
6638 0bd48850 bellard
{
6639 0bd48850 bellard
    VMChangeStateEntry *e;
6640 0bd48850 bellard
6641 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
6642 0bd48850 bellard
        e->cb(e->opaque, running);
6643 0bd48850 bellard
    }
6644 0bd48850 bellard
}
6645 0bd48850 bellard
6646 8a7ddc38 bellard
/* XXX: support several handlers */
6647 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
6648 0bd48850 bellard
static void *vm_stop_opaque;
6649 8a7ddc38 bellard
6650 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
6651 8a7ddc38 bellard
{
6652 8a7ddc38 bellard
    vm_stop_cb = cb;
6653 8a7ddc38 bellard
    vm_stop_opaque = opaque;
6654 8a7ddc38 bellard
    return 0;
6655 8a7ddc38 bellard
}
6656 8a7ddc38 bellard
6657 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
6658 8a7ddc38 bellard
{
6659 8a7ddc38 bellard
    vm_stop_cb = NULL;
6660 8a7ddc38 bellard
}
6661 8a7ddc38 bellard
6662 8a7ddc38 bellard
void vm_start(void)
6663 8a7ddc38 bellard
{
6664 8a7ddc38 bellard
    if (!vm_running) {
6665 8a7ddc38 bellard
        cpu_enable_ticks();
6666 8a7ddc38 bellard
        vm_running = 1;
6667 0bd48850 bellard
        vm_state_notify(1);
6668 efe75411 ths
        qemu_rearm_alarm_timer(alarm_timer);
6669 8a7ddc38 bellard
    }
6670 8a7ddc38 bellard
}
6671 8a7ddc38 bellard
6672 5fafdf24 ths
void vm_stop(int reason)
6673 8a7ddc38 bellard
{
6674 8a7ddc38 bellard
    if (vm_running) {
6675 8a7ddc38 bellard
        cpu_disable_ticks();
6676 8a7ddc38 bellard
        vm_running = 0;
6677 8a7ddc38 bellard
        if (reason != 0) {
6678 8a7ddc38 bellard
            if (vm_stop_cb) {
6679 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
6680 8a7ddc38 bellard
            }
6681 34865134 bellard
        }
6682 0bd48850 bellard
        vm_state_notify(0);
6683 8a7ddc38 bellard
    }
6684 8a7ddc38 bellard
}
6685 8a7ddc38 bellard
6686 bb0c6722 bellard
/* reset/shutdown handler */
6687 bb0c6722 bellard
6688 bb0c6722 bellard
typedef struct QEMUResetEntry {
6689 bb0c6722 bellard
    QEMUResetHandler *func;
6690 bb0c6722 bellard
    void *opaque;
6691 bb0c6722 bellard
    struct QEMUResetEntry *next;
6692 bb0c6722 bellard
} QEMUResetEntry;
6693 bb0c6722 bellard
6694 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
6695 bb0c6722 bellard
static int reset_requested;
6696 bb0c6722 bellard
static int shutdown_requested;
6697 3475187d bellard
static int powerdown_requested;
6698 bb0c6722 bellard
6699 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
6700 bb0c6722 bellard
{
6701 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
6702 bb0c6722 bellard
6703 bb0c6722 bellard
    pre = &first_reset_entry;
6704 bb0c6722 bellard
    while (*pre != NULL)
6705 bb0c6722 bellard
        pre = &(*pre)->next;
6706 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
6707 bb0c6722 bellard
    re->func = func;
6708 bb0c6722 bellard
    re->opaque = opaque;
6709 bb0c6722 bellard
    re->next = NULL;
6710 bb0c6722 bellard
    *pre = re;
6711 bb0c6722 bellard
}
6712 bb0c6722 bellard
6713 52f61fde ths
static void qemu_system_reset(void)
6714 bb0c6722 bellard
{
6715 bb0c6722 bellard
    QEMUResetEntry *re;
6716 bb0c6722 bellard
6717 bb0c6722 bellard
    /* reset all devices */
6718 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
6719 bb0c6722 bellard
        re->func(re->opaque);
6720 bb0c6722 bellard
    }
6721 bb0c6722 bellard
}
6722 bb0c6722 bellard
6723 bb0c6722 bellard
void qemu_system_reset_request(void)
6724 bb0c6722 bellard
{
6725 d1beab82 bellard
    if (no_reboot) {
6726 d1beab82 bellard
        shutdown_requested = 1;
6727 d1beab82 bellard
    } else {
6728 d1beab82 bellard
        reset_requested = 1;
6729 d1beab82 bellard
    }
6730 6a00d601 bellard
    if (cpu_single_env)
6731 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6732 bb0c6722 bellard
}
6733 bb0c6722 bellard
6734 bb0c6722 bellard
void qemu_system_shutdown_request(void)
6735 bb0c6722 bellard
{
6736 bb0c6722 bellard
    shutdown_requested = 1;
6737 6a00d601 bellard
    if (cpu_single_env)
6738 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6739 bb0c6722 bellard
}
6740 bb0c6722 bellard
6741 3475187d bellard
void qemu_system_powerdown_request(void)
6742 3475187d bellard
{
6743 3475187d bellard
    powerdown_requested = 1;
6744 6a00d601 bellard
    if (cpu_single_env)
6745 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6746 bb0c6722 bellard
}
6747 bb0c6722 bellard
6748 5905b2e5 bellard
void main_loop_wait(int timeout)
6749 8a7ddc38 bellard
{
6750 cafffd40 ths
    IOHandlerRecord *ioh;
6751 e035649e bellard
    fd_set rfds, wfds, xfds;
6752 877cf882 ths
    int ret, nfds;
6753 877cf882 ths
#ifdef _WIN32
6754 877cf882 ths
    int ret2, i;
6755 877cf882 ths
#endif
6756 fd1dff4b bellard
    struct timeval tv;
6757 f331110f bellard
    PollingEntry *pe;
6758 f331110f bellard
6759 c4b1fcc0 bellard
6760 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
6761 f331110f bellard
    ret = 0;
6762 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
6763 f331110f bellard
        ret |= pe->func(pe->opaque);
6764 f331110f bellard
    }
6765 38e205a2 bellard
#ifdef _WIN32
6766 e6b1e558 ths
    if (ret == 0) {
6767 a18e524a bellard
        int err;
6768 a18e524a bellard
        WaitObjects *w = &wait_objects;
6769 5fafdf24 ths
       
6770 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
6771 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
6772 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
6773 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
6774 5fafdf24 ths
               
6775 5fafdf24 ths
            /* Check for additional signaled events */
6776 e6b1e558 ths
            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
6777 5fafdf24 ths
                               
6778 e6b1e558 ths
                /* Check if event is signaled */
6779 e6b1e558 ths
                ret2 = WaitForSingleObject(w->events[i], 0);
6780 e6b1e558 ths
                if(ret2 == WAIT_OBJECT_0) {
6781 e6b1e558 ths
                    if (w->func[i])
6782 e6b1e558 ths
                        w->func[i](w->opaque[i]);
6783 e6b1e558 ths
                } else if (ret2 == WAIT_TIMEOUT) {
6784 e6b1e558 ths
                } else {
6785 e6b1e558 ths
                    err = GetLastError();
6786 e6b1e558 ths
                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
6787 5fafdf24 ths
                }               
6788 5fafdf24 ths
            }                
6789 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
6790 a18e524a bellard
        } else {
6791 a18e524a bellard
            err = GetLastError();
6792 e6b1e558 ths
            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
6793 a18e524a bellard
        }
6794 f331110f bellard
    }
6795 fd1dff4b bellard
#endif
6796 fd1dff4b bellard
    /* poll any events */
6797 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
6798 fd1dff4b bellard
    nfds = -1;
6799 fd1dff4b bellard
    FD_ZERO(&rfds);
6800 fd1dff4b bellard
    FD_ZERO(&wfds);
6801 e035649e bellard
    FD_ZERO(&xfds);
6802 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6803 cafffd40 ths
        if (ioh->deleted)
6804 cafffd40 ths
            continue;
6805 fd1dff4b bellard
        if (ioh->fd_read &&
6806 fd1dff4b bellard
            (!ioh->fd_read_poll ||
6807 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
6808 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
6809 fd1dff4b bellard
            if (ioh->fd > nfds)
6810 fd1dff4b bellard
                nfds = ioh->fd;
6811 fd1dff4b bellard
        }
6812 fd1dff4b bellard
        if (ioh->fd_write) {
6813 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
6814 fd1dff4b bellard
            if (ioh->fd > nfds)
6815 fd1dff4b bellard
                nfds = ioh->fd;
6816 fd1dff4b bellard
        }
6817 fd1dff4b bellard
    }
6818 5fafdf24 ths
   
6819 fd1dff4b bellard
    tv.tv_sec = 0;
6820 fd1dff4b bellard
#ifdef _WIN32
6821 fd1dff4b bellard
    tv.tv_usec = 0;
6822 38e205a2 bellard
#else
6823 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
6824 fd1dff4b bellard
#endif
6825 e035649e bellard
#if defined(CONFIG_SLIRP)
6826 e035649e bellard
    if (slirp_inited) {
6827 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
6828 e035649e bellard
    }
6829 e035649e bellard
#endif
6830 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
6831 fd1dff4b bellard
    if (ret > 0) {
6832 cafffd40 ths
        IOHandlerRecord **pioh;
6833 cafffd40 ths
6834 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6835 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
6836 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
6837 7c9d8e07 bellard
            }
6838 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
6839 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
6840 c4b1fcc0 bellard
            }
6841 b4608c04 bellard
        }
6842 cafffd40 ths
6843 cafffd40 ths
        /* remove deleted IO handlers */
6844 cafffd40 ths
        pioh = &first_io_handler;
6845 cafffd40 ths
        while (*pioh) {
6846 cafffd40 ths
            ioh = *pioh;
6847 cafffd40 ths
            if (ioh->deleted) {
6848 cafffd40 ths
                *pioh = ioh->next;
6849 cafffd40 ths
                qemu_free(ioh);
6850 5fafdf24 ths
            } else
6851 cafffd40 ths
                pioh = &ioh->next;
6852 cafffd40 ths
        }
6853 fd1dff4b bellard
    }
6854 c20709aa bellard
#if defined(CONFIG_SLIRP)
6855 fd1dff4b bellard
    if (slirp_inited) {
6856 e035649e bellard
        if (ret < 0) {
6857 e035649e bellard
            FD_ZERO(&rfds);
6858 e035649e bellard
            FD_ZERO(&wfds);
6859 e035649e bellard
            FD_ZERO(&xfds);
6860 c20709aa bellard
        }
6861 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
6862 fd1dff4b bellard
    }
6863 c20709aa bellard
#endif
6864 83f64091 bellard
    qemu_aio_poll();
6865 c20709aa bellard
6866 fd1dff4b bellard
    if (vm_running) {
6867 5fafdf24 ths
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
6868 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
6869 fd1dff4b bellard
        /* run dma transfers, if any */
6870 fd1dff4b bellard
        DMA_run();
6871 fd1dff4b bellard
    }
6872 423f0742 pbrook
6873 fd1dff4b bellard
    /* real time timers */
6874 5fafdf24 ths
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
6875 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
6876 423f0742 pbrook
6877 423f0742 pbrook
    /* Check bottom-halves last in case any of the earlier events triggered
6878 423f0742 pbrook
       them.  */
6879 423f0742 pbrook
    qemu_bh_poll();
6880 5fafdf24 ths
   
6881 5905b2e5 bellard
}
6882 5905b2e5 bellard
6883 6a00d601 bellard
static CPUState *cur_cpu;
6884 6a00d601 bellard
6885 5905b2e5 bellard
int main_loop(void)
6886 5905b2e5 bellard
{
6887 5905b2e5 bellard
    int ret, timeout;
6888 89bfc105 bellard
#ifdef CONFIG_PROFILER
6889 89bfc105 bellard
    int64_t ti;
6890 89bfc105 bellard
#endif
6891 6a00d601 bellard
    CPUState *env;
6892 5905b2e5 bellard
6893 6a00d601 bellard
    cur_cpu = first_cpu;
6894 5905b2e5 bellard
    for(;;) {
6895 5905b2e5 bellard
        if (vm_running) {
6896 15a76449 bellard
6897 15a76449 bellard
            env = cur_cpu;
6898 15a76449 bellard
            for(;;) {
6899 15a76449 bellard
                /* get next cpu */
6900 15a76449 bellard
                env = env->next_cpu;
6901 15a76449 bellard
                if (!env)
6902 15a76449 bellard
                    env = first_cpu;
6903 89bfc105 bellard
#ifdef CONFIG_PROFILER
6904 89bfc105 bellard
                ti = profile_getclock();
6905 89bfc105 bellard
#endif
6906 6a00d601 bellard
                ret = cpu_exec(env);
6907 89bfc105 bellard
#ifdef CONFIG_PROFILER
6908 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
6909 89bfc105 bellard
#endif
6910 bd967e05 pbrook
                if (ret == EXCP_HLT) {
6911 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
6912 bd967e05 pbrook
                    cur_cpu = env;
6913 bd967e05 pbrook
                    continue;
6914 bd967e05 pbrook
                }
6915 15a76449 bellard
                if (ret != EXCP_HALTED)
6916 15a76449 bellard
                    break;
6917 15a76449 bellard
                /* all CPUs are halted ? */
6918 bd967e05 pbrook
                if (env == cur_cpu)
6919 15a76449 bellard
                    break;
6920 15a76449 bellard
            }
6921 15a76449 bellard
            cur_cpu = env;
6922 15a76449 bellard
6923 5905b2e5 bellard
            if (shutdown_requested) {
6924 3475187d bellard
                ret = EXCP_INTERRUPT;
6925 5905b2e5 bellard
                break;
6926 5905b2e5 bellard
            }
6927 5905b2e5 bellard
            if (reset_requested) {
6928 5905b2e5 bellard
                reset_requested = 0;
6929 5905b2e5 bellard
                qemu_system_reset();
6930 3475187d bellard
                ret = EXCP_INTERRUPT;
6931 3475187d bellard
            }
6932 3475187d bellard
            if (powerdown_requested) {
6933 3475187d bellard
                powerdown_requested = 0;
6934 3475187d bellard
                qemu_system_powerdown();
6935 3475187d bellard
                ret = EXCP_INTERRUPT;
6936 5905b2e5 bellard
            }
6937 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
6938 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
6939 5905b2e5 bellard
            }
6940 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
6941 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
6942 bd967e05 pbrook
            if (ret == EXCP_HALTED)
6943 5905b2e5 bellard
                timeout = 10;
6944 5905b2e5 bellard
            else
6945 5905b2e5 bellard
                timeout = 0;
6946 5905b2e5 bellard
        } else {
6947 5905b2e5 bellard
            timeout = 10;
6948 5905b2e5 bellard
        }
6949 89bfc105 bellard
#ifdef CONFIG_PROFILER
6950 89bfc105 bellard
        ti = profile_getclock();
6951 89bfc105 bellard
#endif
6952 5905b2e5 bellard
        main_loop_wait(timeout);
6953 89bfc105 bellard
#ifdef CONFIG_PROFILER
6954 89bfc105 bellard
        dev_time += profile_getclock() - ti;
6955 89bfc105 bellard
#endif
6956 b4608c04 bellard
    }
6957 34865134 bellard
    cpu_disable_ticks();
6958 34865134 bellard
    return ret;
6959 b4608c04 bellard
}
6960 b4608c04 bellard
6961 15f82208 ths
static void help(int exitcode)
6962 0824d6fc bellard
{
6963 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
6964 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
6965 0824d6fc bellard
           "\n"
6966 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
6967 fc01f7e7 bellard
           "\n"
6968 a20dd508 bellard
           "Standard options:\n"
6969 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
6970 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
6971 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
6972 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
6973 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
6974 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
6975 3e3d5815 balrog
           "-mtdblock file  use 'file' as on-board Flash memory image\n"
6976 a1bb27b1 pbrook
           "-sd file        use 'file' as SecureDigital card image\n"
6977 86f55663 j_mayer
           "-pflash file    use 'file' as a parallel flash image\n"
6978 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
6979 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
6980 667accab ths
#ifdef CONFIG_SDL
6981 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
6982 3780e197 ths
           "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
6983 667accab ths
           "-no-quit        disable SDL window close capability\n"
6984 667accab ths
#endif
6985 52ca8d6a bellard
#ifdef TARGET_I386
6986 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
6987 52ca8d6a bellard
#endif
6988 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
6989 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
6990 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
6991 a171fe39 balrog
           "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"
6992 4ca0074c bellard
#ifndef _WIN32
6993 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
6994 4ca0074c bellard
#endif
6995 1d14ffa9 bellard
#ifdef HAS_AUDIO
6996 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
6997 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
6998 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
6999 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
7000 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
7001 1d14ffa9 bellard
#endif
7002 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
7003 d63d307f bellard
           "-full-screen    start in full screen\n"
7004 a09db21f bellard
#ifdef TARGET_I386
7005 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
7006 a09db21f bellard
#endif
7007 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
7008 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
7009 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7010 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
7011 bb0c6722 bellard
#endif
7012 c35734b2 ths
           "-name string    set the name of the guest\n"
7013 c4b1fcc0 bellard
           "\n"
7014 c4b1fcc0 bellard
           "Network options:\n"
7015 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
7016 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
7017 c20709aa bellard
#ifdef CONFIG_SLIRP
7018 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
7019 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
7020 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
7021 7c9d8e07 bellard
#endif
7022 7fb843f8 bellard
#ifdef _WIN32
7023 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
7024 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
7025 7fb843f8 bellard
#else
7026 7c9d8e07 bellard
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
7027 7c9d8e07 bellard
           "                connect the host TAP network interface to VLAN 'n' and use\n"
7028 7c9d8e07 bellard
           "                the network script 'file' (default=%s);\n"
7029 6a1cbf68 ths
           "                use 'script=no' to disable script execution;\n"
7030 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
7031 7fb843f8 bellard
#endif
7032 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
7033 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
7034 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7035 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
7036 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
7037 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
7038 7c9d8e07 bellard
           "\n"
7039 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
7040 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
7041 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
7042 7c9d8e07 bellard
#ifndef _WIN32
7043 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
7044 c94c8d64 bellard
#endif
7045 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
7046 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
7047 c20709aa bellard
#endif
7048 a20dd508 bellard
           "\n"
7049 c4b1fcc0 bellard
           "Linux boot specific:\n"
7050 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
7051 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
7052 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
7053 fc01f7e7 bellard
           "\n"
7054 330d0414 bellard
           "Debug/Expert options:\n"
7055 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
7056 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
7057 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
7058 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
7059 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
7060 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
7061 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
7062 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
7063 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
7064 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
7065 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
7066 d993e026 bellard
#ifdef USE_KQEMU
7067 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
7068 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
7069 d993e026 bellard
#endif
7070 77fef8c1 bellard
#ifdef USE_CODE_COPY
7071 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
7072 77fef8c1 bellard
#endif
7073 bb0c6722 bellard
#ifdef TARGET_I386
7074 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
7075 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
7076 6515b203 bellard
           "-no-acpi        disable ACPI\n"
7077 bb0c6722 bellard
#endif
7078 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
7079 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
7080 24236869 bellard
           "-vnc display    start a VNC server on display\n"
7081 71e3ceb8 ths
#ifndef _WIN32
7082 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
7083 71e3ceb8 ths
#endif
7084 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
7085 66508601 blueswir1
#ifdef TARGET_SPARC
7086 66508601 blueswir1
           "-prom-env variable=value  set OpenBIOS nvram variables\n"
7087 66508601 blueswir1
#endif
7088 f3dcfada ths
           "-clock          force the use of the given methods for timer alarm.\n"
7089 f3dcfada ths
           "                To see what timers are available use -clock help\n"
7090 0824d6fc bellard
           "\n"
7091 82c643ff bellard
           "During emulation, the following keys are useful:\n"
7092 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
7093 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
7094 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
7095 82c643ff bellard
           "\n"
7096 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
7097 82c643ff bellard
           ,
7098 0db63474 bellard
           "qemu",
7099 a00bad7e bellard
           DEFAULT_RAM_SIZE,
7100 7c9d8e07 bellard
#ifndef _WIN32
7101 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
7102 7c9d8e07 bellard
#endif
7103 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
7104 6e44ba7f bellard
           "/tmp/qemu.log");
7105 15f82208 ths
    exit(exitcode);
7106 0824d6fc bellard
}
7107 0824d6fc bellard
7108 cd6f1169 bellard
#define HAS_ARG 0x0001
7109 cd6f1169 bellard
7110 cd6f1169 bellard
enum {
7111 cd6f1169 bellard
    QEMU_OPTION_h,
7112 cd6f1169 bellard
7113 cc1daa40 bellard
    QEMU_OPTION_M,
7114 94fc95cd j_mayer
    QEMU_OPTION_cpu,
7115 cd6f1169 bellard
    QEMU_OPTION_fda,
7116 cd6f1169 bellard
    QEMU_OPTION_fdb,
7117 cd6f1169 bellard
    QEMU_OPTION_hda,
7118 cd6f1169 bellard
    QEMU_OPTION_hdb,
7119 cd6f1169 bellard
    QEMU_OPTION_hdc,
7120 cd6f1169 bellard
    QEMU_OPTION_hdd,
7121 cd6f1169 bellard
    QEMU_OPTION_cdrom,
7122 3e3d5815 balrog
    QEMU_OPTION_mtdblock,
7123 a1bb27b1 pbrook
    QEMU_OPTION_sd,
7124 86f55663 j_mayer
    QEMU_OPTION_pflash,
7125 cd6f1169 bellard
    QEMU_OPTION_boot,
7126 cd6f1169 bellard
    QEMU_OPTION_snapshot,
7127 52ca8d6a bellard
#ifdef TARGET_I386
7128 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
7129 52ca8d6a bellard
#endif
7130 cd6f1169 bellard
    QEMU_OPTION_m,
7131 cd6f1169 bellard
    QEMU_OPTION_nographic,
7132 a171fe39 balrog
    QEMU_OPTION_portrait,
7133 1d14ffa9 bellard
#ifdef HAS_AUDIO
7134 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
7135 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
7136 1d14ffa9 bellard
#endif
7137 cd6f1169 bellard
7138 7c9d8e07 bellard
    QEMU_OPTION_net,
7139 c7f74643 bellard
    QEMU_OPTION_tftp,
7140 47d5d01a ths
    QEMU_OPTION_bootp,
7141 9d728e8c bellard
    QEMU_OPTION_smb,
7142 9bf05444 bellard
    QEMU_OPTION_redir,
7143 cd6f1169 bellard
7144 cd6f1169 bellard
    QEMU_OPTION_kernel,
7145 cd6f1169 bellard
    QEMU_OPTION_append,
7146 cd6f1169 bellard
    QEMU_OPTION_initrd,
7147 cd6f1169 bellard
7148 cd6f1169 bellard
    QEMU_OPTION_S,
7149 cd6f1169 bellard
    QEMU_OPTION_s,
7150 cd6f1169 bellard
    QEMU_OPTION_p,
7151 cd6f1169 bellard
    QEMU_OPTION_d,
7152 cd6f1169 bellard
    QEMU_OPTION_hdachs,
7153 cd6f1169 bellard
    QEMU_OPTION_L,
7154 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
7155 3d11d0eb bellard
    QEMU_OPTION_k,
7156 ee22c2f7 bellard
    QEMU_OPTION_localtime,
7157 1f04275e bellard
    QEMU_OPTION_cirrusvga,
7158 d34cab9f ths
    QEMU_OPTION_vmsvga,
7159 e9b137c2 bellard
    QEMU_OPTION_g,
7160 1bfe856e bellard
    QEMU_OPTION_std_vga,
7161 20d8a3ed ths
    QEMU_OPTION_echr,
7162 82c643ff bellard
    QEMU_OPTION_monitor,
7163 82c643ff bellard
    QEMU_OPTION_serial,
7164 6508fe59 bellard
    QEMU_OPTION_parallel,
7165 d63d307f bellard
    QEMU_OPTION_loadvm,
7166 d63d307f bellard
    QEMU_OPTION_full_screen,
7167 43523e93 ths
    QEMU_OPTION_no_frame,
7168 3780e197 ths
    QEMU_OPTION_alt_grab,
7169 667accab ths
    QEMU_OPTION_no_quit,
7170 f7cce898 bellard
    QEMU_OPTION_pidfile,
7171 d993e026 bellard
    QEMU_OPTION_no_kqemu,
7172 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
7173 a09db21f bellard
    QEMU_OPTION_win2k_hack,
7174 bb36d470 bellard
    QEMU_OPTION_usb,
7175 a594cfbf bellard
    QEMU_OPTION_usbdevice,
7176 6a00d601 bellard
    QEMU_OPTION_smp,
7177 24236869 bellard
    QEMU_OPTION_vnc,
7178 6515b203 bellard
    QEMU_OPTION_no_acpi,
7179 d1beab82 bellard
    QEMU_OPTION_no_reboot,
7180 9467cd46 balrog
    QEMU_OPTION_show_cursor,
7181 71e3ceb8 ths
    QEMU_OPTION_daemonize,
7182 9ae02555 ths
    QEMU_OPTION_option_rom,
7183 c35734b2 ths
    QEMU_OPTION_semihosting,
7184 c35734b2 ths
    QEMU_OPTION_name,
7185 66508601 blueswir1
    QEMU_OPTION_prom_env,
7186 2b8f2d41 balrog
    QEMU_OPTION_old_param,
7187 f3dcfada ths
    QEMU_OPTION_clock,
7188 cd6f1169 bellard
};
7189 cd6f1169 bellard
7190 cd6f1169 bellard
typedef struct QEMUOption {
7191 cd6f1169 bellard
    const char *name;
7192 cd6f1169 bellard
    int flags;
7193 cd6f1169 bellard
    int index;
7194 cd6f1169 bellard
} QEMUOption;
7195 cd6f1169 bellard
7196 cd6f1169 bellard
const QEMUOption qemu_options[] = {
7197 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
7198 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
7199 cd6f1169 bellard
7200 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
7201 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
7202 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
7203 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7204 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
7205 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7206 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7207 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
7208 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
7209 3e3d5815 balrog
    { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
7210 a1bb27b1 pbrook
    { "sd", HAS_ARG, QEMU_OPTION_sd },
7211 86f55663 j_mayer
    { "pflash", HAS_ARG, QEMU_OPTION_pflash },
7212 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
7213 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
7214 52ca8d6a bellard
#ifdef TARGET_I386
7215 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7216 52ca8d6a bellard
#endif
7217 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
7218 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
7219 a171fe39 balrog
    { "portrait", 0, QEMU_OPTION_portrait },
7220 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
7221 1d14ffa9 bellard
#ifdef HAS_AUDIO
7222 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
7223 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7224 1d14ffa9 bellard
#endif
7225 cd6f1169 bellard
7226 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
7227 158156d1 bellard
#ifdef CONFIG_SLIRP
7228 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
7229 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
7230 c94c8d64 bellard
#ifndef _WIN32
7231 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
7232 c94c8d64 bellard
#endif
7233 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
7234 158156d1 bellard
#endif
7235 cd6f1169 bellard
7236 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7237 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
7238 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7239 cd6f1169 bellard
7240 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
7241 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
7242 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
7243 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
7244 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7245 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
7246 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
7247 d993e026 bellard
#ifdef USE_KQEMU
7248 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
7249 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
7250 d993e026 bellard
#endif
7251 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7252 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
7253 77d4bc34 bellard
#endif
7254 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
7255 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
7256 8b6e0729 balrog
    { "echr", HAS_ARG, QEMU_OPTION_echr },
7257 8b6e0729 balrog
    { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7258 8b6e0729 balrog
    { "serial", HAS_ARG, QEMU_OPTION_serial },
7259 8b6e0729 balrog
    { "parallel", HAS_ARG, QEMU_OPTION_parallel },
7260 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7261 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
7262 667accab ths
#ifdef CONFIG_SDL
7263 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
7264 3780e197 ths
    { "alt-grab", 0, QEMU_OPTION_alt_grab },
7265 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
7266 667accab ths
#endif
7267 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
7268 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
7269 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
7270 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
7271 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
7272 96d30e48 ths
7273 1f04275e bellard
    /* temporary options */
7274 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
7275 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
7276 d34cab9f ths
    { "vmwarevga", 0, QEMU_OPTION_vmsvga },
7277 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
7278 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
7279 9467cd46 balrog
    { "show-cursor", 0, QEMU_OPTION_show_cursor },
7280 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
7281 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
7282 a87295e8 pbrook
#if defined(TARGET_ARM) || defined(TARGET_M68K)
7283 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
7284 8e71621f pbrook
#endif
7285 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
7286 66508601 blueswir1
#if defined(TARGET_SPARC)
7287 66508601 blueswir1
    { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
7288 66508601 blueswir1
#endif
7289 2b8f2d41 balrog
#if defined(TARGET_ARM)
7290 2b8f2d41 balrog
    { "old-param", 0, QEMU_OPTION_old_param },
7291 2b8f2d41 balrog
#endif
7292 f3dcfada ths
    { "clock", HAS_ARG, QEMU_OPTION_clock },
7293 cd6f1169 bellard
    { NULL },
7294 fc01f7e7 bellard
};
7295 fc01f7e7 bellard
7296 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
7297 77fef8c1 bellard
7298 77fef8c1 bellard
/* this stack is only used during signal handling */
7299 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
7300 77fef8c1 bellard
7301 77fef8c1 bellard
static uint8_t *signal_stack;
7302 77fef8c1 bellard
7303 77fef8c1 bellard
#endif
7304 77fef8c1 bellard
7305 5905b2e5 bellard
/* password input */
7306 5905b2e5 bellard
7307 2bac6019 balrog
int qemu_key_check(BlockDriverState *bs, const char *name)
7308 2bac6019 balrog
{
7309 2bac6019 balrog
    char password[256];
7310 2bac6019 balrog
    int i;
7311 2bac6019 balrog
7312 2bac6019 balrog
    if (!bdrv_is_encrypted(bs))
7313 2bac6019 balrog
        return 0;
7314 2bac6019 balrog
7315 2bac6019 balrog
    term_printf("%s is encrypted.\n", name);
7316 2bac6019 balrog
    for(i = 0; i < 3; i++) {
7317 2bac6019 balrog
        monitor_readline("Password: ", 1, password, sizeof(password));
7318 2bac6019 balrog
        if (bdrv_set_key(bs, password) == 0)
7319 2bac6019 balrog
            return 0;
7320 2bac6019 balrog
        term_printf("invalid password\n");
7321 2bac6019 balrog
    }
7322 2bac6019 balrog
    return -EPERM;
7323 2bac6019 balrog
}
7324 2bac6019 balrog
7325 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
7326 5905b2e5 bellard
{
7327 5905b2e5 bellard
    BlockDriverState *bs;
7328 5905b2e5 bellard
7329 5905b2e5 bellard
    if (index < 4) {
7330 5905b2e5 bellard
        bs = bs_table[index];
7331 5905b2e5 bellard
    } else if (index < 6) {
7332 5905b2e5 bellard
        bs = fd_table[index - 4];
7333 5905b2e5 bellard
    } else {
7334 5905b2e5 bellard
        bs = NULL;
7335 5905b2e5 bellard
    }
7336 5905b2e5 bellard
    return bs;
7337 5905b2e5 bellard
}
7338 5905b2e5 bellard
7339 5905b2e5 bellard
static void read_passwords(void)
7340 5905b2e5 bellard
{
7341 5905b2e5 bellard
    BlockDriverState *bs;
7342 2bac6019 balrog
    int i;
7343 5905b2e5 bellard
7344 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
7345 5905b2e5 bellard
        bs = get_bdrv(i);
7346 2bac6019 balrog
        if (bs)
7347 2bac6019 balrog
            qemu_key_check(bs, bdrv_get_device_name(bs));
7348 5905b2e5 bellard
    }
7349 5905b2e5 bellard
}
7350 5905b2e5 bellard
7351 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
7352 cc1daa40 bellard
void register_machines(void)
7353 cc1daa40 bellard
{
7354 cc1daa40 bellard
#if defined(TARGET_I386)
7355 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
7356 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
7357 cc1daa40 bellard
#elif defined(TARGET_PPC)
7358 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
7359 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
7360 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
7361 1a6c0886 j_mayer
    qemu_register_machine(&ref405ep_machine);
7362 1a6c0886 j_mayer
    qemu_register_machine(&taihu_machine);
7363 6af0bf9c bellard
#elif defined(TARGET_MIPS)
7364 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
7365 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
7366 ad6fe1d2 ths
    qemu_register_machine(&mips_pica61_machine);
7367 cc1daa40 bellard
#elif defined(TARGET_SPARC)
7368 3475187d bellard
#ifdef TARGET_SPARC64
7369 3475187d bellard
    qemu_register_machine(&sun4u_machine);
7370 3475187d bellard
#else
7371 36cd9210 blueswir1
    qemu_register_machine(&ss5_machine);
7372 e0353fe2 blueswir1
    qemu_register_machine(&ss10_machine);
7373 cc1daa40 bellard
#endif
7374 b5ff1b31 bellard
#elif defined(TARGET_ARM)
7375 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
7376 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
7377 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
7378 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
7379 b00052e4 balrog
    qemu_register_machine(&akitapda_machine);
7380 b00052e4 balrog
    qemu_register_machine(&spitzpda_machine);
7381 b00052e4 balrog
    qemu_register_machine(&borzoipda_machine);
7382 b00052e4 balrog
    qemu_register_machine(&terrierpda_machine);
7383 c3d2689d balrog
    qemu_register_machine(&palmte_machine);
7384 27c7ca7e bellard
#elif defined(TARGET_SH4)
7385 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
7386 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
7387 eddf68a6 j_mayer
    /* XXX: TODO */
7388 0633879f pbrook
#elif defined(TARGET_M68K)
7389 20dcee94 pbrook
    qemu_register_machine(&mcf5208evb_machine);
7390 0633879f pbrook
    qemu_register_machine(&an5206_machine);
7391 b5ff1b31 bellard
#else
7392 b5ff1b31 bellard
#error unsupported CPU
7393 3475187d bellard
#endif
7394 cc1daa40 bellard
}
7395 cc1daa40 bellard
7396 1d14ffa9 bellard
#ifdef HAS_AUDIO
7397 6a36d84e bellard
struct soundhw soundhw[] = {
7398 b00052e4 balrog
#ifdef HAS_AUDIO_CHOICE
7399 fd06c375 bellard
#ifdef TARGET_I386
7400 fd06c375 bellard
    {
7401 fd06c375 bellard
        "pcspk",
7402 fd06c375 bellard
        "PC speaker",
7403 fd06c375 bellard
        0,
7404 fd06c375 bellard
        1,
7405 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
7406 fd06c375 bellard
    },
7407 fd06c375 bellard
#endif
7408 6a36d84e bellard
    {
7409 6a36d84e bellard
        "sb16",
7410 6a36d84e bellard
        "Creative Sound Blaster 16",
7411 6a36d84e bellard
        0,
7412 6a36d84e bellard
        1,
7413 6a36d84e bellard
        { .init_isa = SB16_init }
7414 6a36d84e bellard
    },
7415 6a36d84e bellard
7416 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
7417 6a36d84e bellard
    {
7418 6a36d84e bellard
        "adlib",
7419 1d14ffa9 bellard
#ifdef HAS_YMF262
7420 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
7421 1d14ffa9 bellard
#else
7422 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
7423 1d14ffa9 bellard
#endif
7424 6a36d84e bellard
        0,
7425 6a36d84e bellard
        1,
7426 6a36d84e bellard
        { .init_isa = Adlib_init }
7427 6a36d84e bellard
    },
7428 1d14ffa9 bellard
#endif
7429 6a36d84e bellard
7430 1d14ffa9 bellard
#ifdef CONFIG_GUS
7431 6a36d84e bellard
    {
7432 6a36d84e bellard
        "gus",
7433 6a36d84e bellard
        "Gravis Ultrasound GF1",
7434 6a36d84e bellard
        0,
7435 6a36d84e bellard
        1,
7436 6a36d84e bellard
        { .init_isa = GUS_init }
7437 6a36d84e bellard
    },
7438 1d14ffa9 bellard
#endif
7439 6a36d84e bellard
7440 6a36d84e bellard
    {
7441 6a36d84e bellard
        "es1370",
7442 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
7443 6a36d84e bellard
        0,
7444 6a36d84e bellard
        0,
7445 6a36d84e bellard
        { .init_pci = es1370_init }
7446 6a36d84e bellard
    },
7447 b00052e4 balrog
#endif
7448 6a36d84e bellard
7449 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
7450 6a36d84e bellard
};
7451 6a36d84e bellard
7452 6a36d84e bellard
static void select_soundhw (const char *optarg)
7453 6a36d84e bellard
{
7454 6a36d84e bellard
    struct soundhw *c;
7455 6a36d84e bellard
7456 6a36d84e bellard
    if (*optarg == '?') {
7457 6a36d84e bellard
    show_valid_cards:
7458 6a36d84e bellard
7459 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
7460 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
7461 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
7462 6a36d84e bellard
        }
7463 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
7464 1d14ffa9 bellard
        exit (*optarg != '?');
7465 1d14ffa9 bellard
    }
7466 1d14ffa9 bellard
    else {
7467 6a36d84e bellard
        size_t l;
7468 1d14ffa9 bellard
        const char *p;
7469 1d14ffa9 bellard
        char *e;
7470 1d14ffa9 bellard
        int bad_card = 0;
7471 1d14ffa9 bellard
7472 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
7473 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7474 6a36d84e bellard
                c->enabled = 1;
7475 6a36d84e bellard
            }
7476 6a36d84e bellard
            return;
7477 6a36d84e bellard
        }
7478 1d14ffa9 bellard
7479 6a36d84e bellard
        p = optarg;
7480 1d14ffa9 bellard
        while (*p) {
7481 1d14ffa9 bellard
            e = strchr (p, ',');
7482 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
7483 6a36d84e bellard
7484 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7485 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
7486 6a36d84e bellard
                    c->enabled = 1;
7487 1d14ffa9 bellard
                    break;
7488 1d14ffa9 bellard
                }
7489 1d14ffa9 bellard
            }
7490 6a36d84e bellard
7491 6a36d84e bellard
            if (!c->name) {
7492 1d14ffa9 bellard
                if (l > 80) {
7493 1d14ffa9 bellard
                    fprintf (stderr,
7494 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
7495 1d14ffa9 bellard
                }
7496 1d14ffa9 bellard
                else {
7497 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
7498 1d14ffa9 bellard
                             (int) l, p);
7499 1d14ffa9 bellard
                }
7500 1d14ffa9 bellard
                bad_card = 1;
7501 1d14ffa9 bellard
            }
7502 1d14ffa9 bellard
            p += l + (e != NULL);
7503 1d14ffa9 bellard
        }
7504 1d14ffa9 bellard
7505 1d14ffa9 bellard
        if (bad_card)
7506 1d14ffa9 bellard
            goto show_valid_cards;
7507 1d14ffa9 bellard
    }
7508 1d14ffa9 bellard
}
7509 1d14ffa9 bellard
#endif
7510 1d14ffa9 bellard
7511 3587d7e6 bellard
#ifdef _WIN32
7512 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
7513 3587d7e6 bellard
{
7514 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
7515 3587d7e6 bellard
    return TRUE;
7516 3587d7e6 bellard
}
7517 3587d7e6 bellard
#endif
7518 3587d7e6 bellard
7519 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
7520 c20709aa bellard
7521 0824d6fc bellard
int main(int argc, char **argv)
7522 0824d6fc bellard
{
7523 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7524 cfc3475a pbrook
    int use_gdbstub;
7525 cfc3475a pbrook
    const char *gdbstub_port;
7526 67b915a5 bellard
#endif
7527 86f55663 j_mayer
    int i, cdrom_index, pflash_index;
7528 1ccde1cb bellard
    int snapshot, linux_boot;
7529 7f7f9873 bellard
    const char *initrd_filename;
7530 96d30e48 ths
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
7531 86f55663 j_mayer
    const char *pflash_filename[MAX_PFLASH];
7532 a1bb27b1 pbrook
    const char *sd_filename;
7533 3e3d5815 balrog
    const char *mtd_filename;
7534 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
7535 313aa567 bellard
    DisplayState *ds = &display_state;
7536 46d4767d bellard
    int cyls, heads, secs, translation;
7537 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
7538 7c9d8e07 bellard
    int nb_net_clients;
7539 cd6f1169 bellard
    int optind;
7540 cd6f1169 bellard
    const char *r, *optarg;
7541 82c643ff bellard
    CharDriverState *monitor_hd;
7542 82c643ff bellard
    char monitor_device[128];
7543 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
7544 8d11df9e bellard
    int serial_device_index;
7545 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
7546 6508fe59 bellard
    int parallel_device_index;
7547 d63d307f bellard
    const char *loadvm = NULL;
7548 cc1daa40 bellard
    QEMUMachine *machine;
7549 94fc95cd j_mayer
    const char *cpu_model;
7550 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
7551 a594cfbf bellard
    int usb_devices_index;
7552 71e3ceb8 ths
    int fds[2];
7553 93815bc2 ths
    const char *pid_file = NULL;
7554 833c7174 blueswir1
    VLANState *vlan;
7555 0bd48850 bellard
7556 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
7557 be995c27 bellard
#ifndef _WIN32
7558 be995c27 bellard
    {
7559 be995c27 bellard
        struct sigaction act;
7560 be995c27 bellard
        sigfillset(&act.sa_mask);
7561 be995c27 bellard
        act.sa_flags = 0;
7562 be995c27 bellard
        act.sa_handler = SIG_IGN;
7563 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
7564 be995c27 bellard
    }
7565 3587d7e6 bellard
#else
7566 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
7567 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
7568 a8e5ac33 bellard
       QEMU to run on a single CPU */
7569 a8e5ac33 bellard
    {
7570 a8e5ac33 bellard
        HANDLE h;
7571 a8e5ac33 bellard
        DWORD mask, smask;
7572 a8e5ac33 bellard
        int i;
7573 a8e5ac33 bellard
        h = GetCurrentProcess();
7574 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
7575 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
7576 a8e5ac33 bellard
                if (mask & (1 << i))
7577 a8e5ac33 bellard
                    break;
7578 a8e5ac33 bellard
            }
7579 a8e5ac33 bellard
            if (i != 32) {
7580 a8e5ac33 bellard
                mask = 1 << i;
7581 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
7582 a8e5ac33 bellard
            }
7583 a8e5ac33 bellard
        }
7584 a8e5ac33 bellard
    }
7585 67b915a5 bellard
#endif
7586 be995c27 bellard
7587 cc1daa40 bellard
    register_machines();
7588 cc1daa40 bellard
    machine = first_machine;
7589 94fc95cd j_mayer
    cpu_model = NULL;
7590 fc01f7e7 bellard
    initrd_filename = NULL;
7591 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
7592 c45886db bellard
        fd_filename[i] = NULL;
7593 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++)
7594 96d30e48 ths
        hd_filename[i] = NULL;
7595 86f55663 j_mayer
    for(i = 0; i < MAX_PFLASH; i++)
7596 86f55663 j_mayer
        pflash_filename[i] = NULL;
7597 86f55663 j_mayer
    pflash_index = 0;
7598 a1bb27b1 pbrook
    sd_filename = NULL;
7599 3e3d5815 balrog
    mtd_filename = NULL;
7600 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
7601 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
7602 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7603 b4608c04 bellard
    use_gdbstub = 0;
7604 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
7605 67b915a5 bellard
#endif
7606 33e3963e bellard
    snapshot = 0;
7607 a20dd508 bellard
    nographic = 0;
7608 a20dd508 bellard
    kernel_filename = NULL;
7609 a20dd508 bellard
    kernel_cmdline = "";
7610 cc1daa40 bellard
#ifdef TARGET_PPC
7611 cc1daa40 bellard
    cdrom_index = 1;
7612 cc1daa40 bellard
#else
7613 cc1daa40 bellard
    cdrom_index = 2;
7614 cc1daa40 bellard
#endif
7615 c4b1fcc0 bellard
    cyls = heads = secs = 0;
7616 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
7617 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
7618 c4b1fcc0 bellard
7619 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
7620 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
7621 8d11df9e bellard
        serial_devices[i][0] = '\0';
7622 8d11df9e bellard
    serial_device_index = 0;
7623 5fafdf24 ths
   
7624 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
7625 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
7626 6508fe59 bellard
        parallel_devices[i][0] = '\0';
7627 6508fe59 bellard
    parallel_device_index = 0;
7628 5fafdf24 ths
   
7629 a594cfbf bellard
    usb_devices_index = 0;
7630 5fafdf24 ths
   
7631 7c9d8e07 bellard
    nb_net_clients = 0;
7632 7c9d8e07 bellard
7633 7c9d8e07 bellard
    nb_nics = 0;
7634 702c651c bellard
    /* default mac address of the first network interface */
7635 5fafdf24 ths
   
7636 cd6f1169 bellard
    optind = 1;
7637 0824d6fc bellard
    for(;;) {
7638 cd6f1169 bellard
        if (optind >= argc)
7639 0824d6fc bellard
            break;
7640 cd6f1169 bellard
        r = argv[optind];
7641 cd6f1169 bellard
        if (r[0] != '-') {
7642 96d30e48 ths
            hd_filename[0] = argv[optind++];
7643 cd6f1169 bellard
        } else {
7644 cd6f1169 bellard
            const QEMUOption *popt;
7645 cd6f1169 bellard
7646 cd6f1169 bellard
            optind++;
7647 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
7648 dff5efc8 pbrook
            if (r[1] == '-')
7649 dff5efc8 pbrook
                r++;
7650 cd6f1169 bellard
            popt = qemu_options;
7651 cd6f1169 bellard
            for(;;) {
7652 cd6f1169 bellard
                if (!popt->name) {
7653 5fafdf24 ths
                    fprintf(stderr, "%s: invalid option -- '%s'\n",
7654 cd6f1169 bellard
                            argv[0], r);
7655 cd6f1169 bellard
                    exit(1);
7656 cd6f1169 bellard
                }
7657 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
7658 cd6f1169 bellard
                    break;
7659 cd6f1169 bellard
                popt++;
7660 cd6f1169 bellard
            }
7661 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
7662 cd6f1169 bellard
                if (optind >= argc) {
7663 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
7664 cd6f1169 bellard
                            argv[0], r);
7665 cd6f1169 bellard
                    exit(1);
7666 cd6f1169 bellard
                }
7667 cd6f1169 bellard
                optarg = argv[optind++];
7668 cd6f1169 bellard
            } else {
7669 cd6f1169 bellard
                optarg = NULL;
7670 cd6f1169 bellard
            }
7671 cd6f1169 bellard
7672 cd6f1169 bellard
            switch(popt->index) {
7673 cc1daa40 bellard
            case QEMU_OPTION_M:
7674 cc1daa40 bellard
                machine = find_machine(optarg);
7675 cc1daa40 bellard
                if (!machine) {
7676 cc1daa40 bellard
                    QEMUMachine *m;
7677 cc1daa40 bellard
                    printf("Supported machines are:\n");
7678 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
7679 cc1daa40 bellard
                        printf("%-10s %s%s\n",
7680 5fafdf24 ths
                               m->name, m->desc,
7681 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
7682 cc1daa40 bellard
                    }
7683 15f82208 ths
                    exit(*optarg != '?');
7684 cc1daa40 bellard
                }
7685 cc1daa40 bellard
                break;
7686 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
7687 94fc95cd j_mayer
                /* hw initialization will check this */
7688 15f82208 ths
                if (*optarg == '?') {
7689 94fc95cd j_mayer
#if defined(TARGET_PPC)
7690 94fc95cd j_mayer
                    ppc_cpu_list(stdout, &fprintf);
7691 5adb4839 pbrook
#elif defined(TARGET_ARM)
7692 5adb4839 pbrook
                    arm_cpu_list();
7693 33d68b5f ths
#elif defined(TARGET_MIPS)
7694 33d68b5f ths
                    mips_cpu_list(stdout, &fprintf);
7695 62724a37 blueswir1
#elif defined(TARGET_SPARC)
7696 62724a37 blueswir1
                    sparc_cpu_list(stdout, &fprintf);
7697 94fc95cd j_mayer
#endif
7698 15f82208 ths
                    exit(0);
7699 94fc95cd j_mayer
                } else {
7700 94fc95cd j_mayer
                    cpu_model = optarg;
7701 94fc95cd j_mayer
                }
7702 94fc95cd j_mayer
                break;
7703 cd6f1169 bellard
            case QEMU_OPTION_initrd:
7704 fc01f7e7 bellard
                initrd_filename = optarg;
7705 fc01f7e7 bellard
                break;
7706 cd6f1169 bellard
            case QEMU_OPTION_hda:
7707 cd6f1169 bellard
            case QEMU_OPTION_hdb:
7708 cc1daa40 bellard
            case QEMU_OPTION_hdc:
7709 cc1daa40 bellard
            case QEMU_OPTION_hdd:
7710 cc1daa40 bellard
                {
7711 cc1daa40 bellard
                    int hd_index;
7712 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
7713 96d30e48 ths
                    hd_filename[hd_index] = optarg;
7714 96d30e48 ths
                    if (hd_index == cdrom_index)
7715 96d30e48 ths
                        cdrom_index = -1;
7716 cc1daa40 bellard
                }
7717 fc01f7e7 bellard
                break;
7718 3e3d5815 balrog
            case QEMU_OPTION_mtdblock:
7719 3e3d5815 balrog
                mtd_filename = optarg;
7720 3e3d5815 balrog
                break;
7721 a1bb27b1 pbrook
            case QEMU_OPTION_sd:
7722 a1bb27b1 pbrook
                sd_filename = optarg;
7723 a1bb27b1 pbrook
                break;
7724 86f55663 j_mayer
            case QEMU_OPTION_pflash:
7725 86f55663 j_mayer
                if (pflash_index >= MAX_PFLASH) {
7726 86f55663 j_mayer
                    fprintf(stderr, "qemu: too many parallel flash images\n");
7727 86f55663 j_mayer
                    exit(1);
7728 86f55663 j_mayer
                }
7729 86f55663 j_mayer
                pflash_filename[pflash_index++] = optarg;
7730 86f55663 j_mayer
                break;
7731 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
7732 33e3963e bellard
                snapshot = 1;
7733 33e3963e bellard
                break;
7734 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
7735 330d0414 bellard
                {
7736 330d0414 bellard
                    const char *p;
7737 330d0414 bellard
                    p = optarg;
7738 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
7739 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
7740 46d4767d bellard
                        goto chs_fail;
7741 330d0414 bellard
                    if (*p != ',')
7742 330d0414 bellard
                        goto chs_fail;
7743 330d0414 bellard
                    p++;
7744 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
7745 46d4767d bellard
                    if (heads < 1 || heads > 16)
7746 46d4767d bellard
                        goto chs_fail;
7747 330d0414 bellard
                    if (*p != ',')
7748 330d0414 bellard
                        goto chs_fail;
7749 330d0414 bellard
                    p++;
7750 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
7751 46d4767d bellard
                    if (secs < 1 || secs > 63)
7752 46d4767d bellard
                        goto chs_fail;
7753 46d4767d bellard
                    if (*p == ',') {
7754 46d4767d bellard
                        p++;
7755 46d4767d bellard
                        if (!strcmp(p, "none"))
7756 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
7757 46d4767d bellard
                        else if (!strcmp(p, "lba"))
7758 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
7759 46d4767d bellard
                        else if (!strcmp(p, "auto"))
7760 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
7761 46d4767d bellard
                        else
7762 46d4767d bellard
                            goto chs_fail;
7763 46d4767d bellard
                    } else if (*p != '\0') {
7764 c4b1fcc0 bellard
                    chs_fail:
7765 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
7766 46d4767d bellard
                        exit(1);
7767 c4b1fcc0 bellard
                    }
7768 330d0414 bellard
                }
7769 330d0414 bellard
                break;
7770 cd6f1169 bellard
            case QEMU_OPTION_nographic:
7771 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
7772 a39437aa ths
                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
7773 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
7774 a20dd508 bellard
                nographic = 1;
7775 a20dd508 bellard
                break;
7776 a171fe39 balrog
            case QEMU_OPTION_portrait:
7777 a171fe39 balrog
                graphic_rotate = 1;
7778 a171fe39 balrog
                break;
7779 cd6f1169 bellard
            case QEMU_OPTION_kernel:
7780 a20dd508 bellard
                kernel_filename = optarg;
7781 a20dd508 bellard
                break;
7782 cd6f1169 bellard
            case QEMU_OPTION_append:
7783 a20dd508 bellard
                kernel_cmdline = optarg;
7784 313aa567 bellard
                break;
7785 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
7786 96d30e48 ths
                if (cdrom_index >= 0) {
7787 96d30e48 ths
                    hd_filename[cdrom_index] = optarg;
7788 fa1fb14c ths
                }
7789 36b486bb bellard
                break;
7790 cd6f1169 bellard
            case QEMU_OPTION_boot:
7791 36b486bb bellard
                boot_device = optarg[0];
7792 5fafdf24 ths
                if (boot_device != 'a' &&
7793 eec85c2a ths
#if defined(TARGET_SPARC) || defined(TARGET_I386)
7794 6f7e9aec bellard
                    // Network boot
7795 6f7e9aec bellard
                    boot_device != 'n' &&
7796 6f7e9aec bellard
#endif
7797 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
7798 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
7799 36b486bb bellard
                    exit(1);
7800 36b486bb bellard
                }
7801 36b486bb bellard
                break;
7802 cd6f1169 bellard
            case QEMU_OPTION_fda:
7803 c45886db bellard
                fd_filename[0] = optarg;
7804 c45886db bellard
                break;
7805 cd6f1169 bellard
            case QEMU_OPTION_fdb:
7806 c45886db bellard
                fd_filename[1] = optarg;
7807 c45886db bellard
                break;
7808 52ca8d6a bellard
#ifdef TARGET_I386
7809 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
7810 52ca8d6a bellard
                fd_bootchk = 0;
7811 52ca8d6a bellard
                break;
7812 52ca8d6a bellard
#endif
7813 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
7814 77fef8c1 bellard
                code_copy_enabled = 0;
7815 77fef8c1 bellard
                break;
7816 7c9d8e07 bellard
            case QEMU_OPTION_net:
7817 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
7818 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
7819 c4b1fcc0 bellard
                    exit(1);
7820 c4b1fcc0 bellard
                }
7821 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
7822 7c9d8e07 bellard
                        sizeof(net_clients[0]),
7823 7c9d8e07 bellard
                        optarg);
7824 7c9d8e07 bellard
                nb_net_clients++;
7825 702c651c bellard
                break;
7826 c7f74643 bellard
#ifdef CONFIG_SLIRP
7827 c7f74643 bellard
            case QEMU_OPTION_tftp:
7828 c7f74643 bellard
                tftp_prefix = optarg;
7829 9bf05444 bellard
                break;
7830 47d5d01a ths
            case QEMU_OPTION_bootp:
7831 47d5d01a ths
                bootp_filename = optarg;
7832 47d5d01a ths
                break;
7833 c94c8d64 bellard
#ifndef _WIN32
7834 9d728e8c bellard
            case QEMU_OPTION_smb:
7835 9d728e8c bellard
                net_slirp_smb(optarg);
7836 9d728e8c bellard
                break;
7837 c94c8d64 bellard
#endif
7838 9bf05444 bellard
            case QEMU_OPTION_redir:
7839 5fafdf24 ths
                net_slirp_redir(optarg);               
7840 9bf05444 bellard
                break;
7841 c7f74643 bellard
#endif
7842 1d14ffa9 bellard
#ifdef HAS_AUDIO
7843 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
7844 1d14ffa9 bellard
                AUD_help ();
7845 1d14ffa9 bellard
                exit (0);
7846 1d14ffa9 bellard
                break;
7847 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
7848 1d14ffa9 bellard
                select_soundhw (optarg);
7849 1d14ffa9 bellard
                break;
7850 1d14ffa9 bellard
#endif
7851 cd6f1169 bellard
            case QEMU_OPTION_h:
7852 15f82208 ths
                help(0);
7853 cd6f1169 bellard
                break;
7854 cd6f1169 bellard
            case QEMU_OPTION_m:
7855 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
7856 cd6f1169 bellard
                if (ram_size <= 0)
7857 15f82208 ths
                    help(1);
7858 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
7859 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
7860 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
7861 cd6f1169 bellard
                    exit(1);
7862 cd6f1169 bellard
                }
7863 cd6f1169 bellard
                break;
7864 cd6f1169 bellard
            case QEMU_OPTION_d:
7865 cd6f1169 bellard
                {
7866 cd6f1169 bellard
                    int mask;
7867 cd6f1169 bellard
                    CPULogItem *item;
7868 5fafdf24 ths
                   
7869 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
7870 cd6f1169 bellard
                    if (!mask) {
7871 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
7872 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
7873 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
7874 f193c797 bellard
                    }
7875 f193c797 bellard
                    exit(1);
7876 cd6f1169 bellard
                    }
7877 cd6f1169 bellard
                    cpu_set_log(mask);
7878 f193c797 bellard
                }
7879 cd6f1169 bellard
                break;
7880 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7881 cd6f1169 bellard
            case QEMU_OPTION_s:
7882 cd6f1169 bellard
                use_gdbstub = 1;
7883 cd6f1169 bellard
                break;
7884 cd6f1169 bellard
            case QEMU_OPTION_p:
7885 cfc3475a pbrook
                gdbstub_port = optarg;
7886 cd6f1169 bellard
                break;
7887 67b915a5 bellard
#endif
7888 cd6f1169 bellard
            case QEMU_OPTION_L:
7889 cd6f1169 bellard
                bios_dir = optarg;
7890 cd6f1169 bellard
                break;
7891 cd6f1169 bellard
            case QEMU_OPTION_S:
7892 3c07f8e8 pbrook
                autostart = 0;
7893 cd6f1169 bellard
                break;
7894 3d11d0eb bellard
            case QEMU_OPTION_k:
7895 3d11d0eb bellard
                keyboard_layout = optarg;
7896 3d11d0eb bellard
                break;
7897 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
7898 ee22c2f7 bellard
                rtc_utc = 0;
7899 ee22c2f7 bellard
                break;
7900 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
7901 1f04275e bellard
                cirrus_vga_enabled = 1;
7902 d34cab9f ths
                vmsvga_enabled = 0;
7903 d34cab9f ths
                break;
7904 d34cab9f ths
            case QEMU_OPTION_vmsvga:
7905 d34cab9f ths
                cirrus_vga_enabled = 0;
7906 d34cab9f ths
                vmsvga_enabled = 1;
7907 1f04275e bellard
                break;
7908 1bfe856e bellard
            case QEMU_OPTION_std_vga:
7909 1bfe856e bellard
                cirrus_vga_enabled = 0;
7910 d34cab9f ths
                vmsvga_enabled = 0;
7911 1bfe856e bellard
                break;
7912 e9b137c2 bellard
            case QEMU_OPTION_g:
7913 e9b137c2 bellard
                {
7914 e9b137c2 bellard
                    const char *p;
7915 e9b137c2 bellard
                    int w, h, depth;
7916 e9b137c2 bellard
                    p = optarg;
7917 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
7918 e9b137c2 bellard
                    if (w <= 0) {
7919 e9b137c2 bellard
                    graphic_error:
7920 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
7921 e9b137c2 bellard
                        exit(1);
7922 e9b137c2 bellard
                    }
7923 e9b137c2 bellard
                    if (*p != 'x')
7924 e9b137c2 bellard
                        goto graphic_error;
7925 e9b137c2 bellard
                    p++;
7926 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
7927 e9b137c2 bellard
                    if (h <= 0)
7928 e9b137c2 bellard
                        goto graphic_error;
7929 e9b137c2 bellard
                    if (*p == 'x') {
7930 e9b137c2 bellard
                        p++;
7931 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
7932 5fafdf24 ths
                        if (depth != 8 && depth != 15 && depth != 16 &&
7933 e9b137c2 bellard
                            depth != 24 && depth != 32)
7934 e9b137c2 bellard
                            goto graphic_error;
7935 e9b137c2 bellard
                    } else if (*p == '\0') {
7936 e9b137c2 bellard
                        depth = graphic_depth;
7937 e9b137c2 bellard
                    } else {
7938 e9b137c2 bellard
                        goto graphic_error;
7939 e9b137c2 bellard
                    }
7940 5fafdf24 ths
                   
7941 e9b137c2 bellard
                    graphic_width = w;
7942 e9b137c2 bellard
                    graphic_height = h;
7943 e9b137c2 bellard
                    graphic_depth = depth;
7944 e9b137c2 bellard
                }
7945 e9b137c2 bellard
                break;
7946 20d8a3ed ths
            case QEMU_OPTION_echr:
7947 20d8a3ed ths
                {
7948 20d8a3ed ths
                    char *r;
7949 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
7950 20d8a3ed ths
                    if (r == optarg)
7951 20d8a3ed ths
                        printf("Bad argument to echr\n");
7952 20d8a3ed ths
                    break;
7953 20d8a3ed ths
                }
7954 82c643ff bellard
            case QEMU_OPTION_monitor:
7955 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
7956 82c643ff bellard
                break;
7957 82c643ff bellard
            case QEMU_OPTION_serial:
7958 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
7959 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
7960 8d11df9e bellard
                    exit(1);
7961 8d11df9e bellard
                }
7962 5fafdf24 ths
                pstrcpy(serial_devices[serial_device_index],
7963 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
7964 8d11df9e bellard
                serial_device_index++;
7965 82c643ff bellard
                break;
7966 6508fe59 bellard
            case QEMU_OPTION_parallel:
7967 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
7968 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
7969 6508fe59 bellard
                    exit(1);
7970 6508fe59 bellard
                }
7971 5fafdf24 ths
                pstrcpy(parallel_devices[parallel_device_index],
7972 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
7973 6508fe59 bellard
                parallel_device_index++;
7974 6508fe59 bellard
                break;
7975 d63d307f bellard
            case QEMU_OPTION_loadvm:
7976 d63d307f bellard
                loadvm = optarg;
7977 d63d307f bellard
                break;
7978 d63d307f bellard
            case QEMU_OPTION_full_screen:
7979 d63d307f bellard
                full_screen = 1;
7980 d63d307f bellard
                break;
7981 667accab ths
#ifdef CONFIG_SDL
7982 43523e93 ths
            case QEMU_OPTION_no_frame:
7983 43523e93 ths
                no_frame = 1;
7984 43523e93 ths
                break;
7985 3780e197 ths
            case QEMU_OPTION_alt_grab:
7986 3780e197 ths
                alt_grab = 1;
7987 3780e197 ths
                break;
7988 667accab ths
            case QEMU_OPTION_no_quit:
7989 667accab ths
                no_quit = 1;
7990 667accab ths
                break;
7991 667accab ths
#endif
7992 f7cce898 bellard
            case QEMU_OPTION_pidfile:
7993 93815bc2 ths
                pid_file = optarg;
7994 f7cce898 bellard
                break;
7995 a09db21f bellard
#ifdef TARGET_I386
7996 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
7997 a09db21f bellard
                win2k_install_hack = 1;
7998 a09db21f bellard
                break;
7999 a09db21f bellard
#endif
8000 d993e026 bellard
#ifdef USE_KQEMU
8001 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
8002 d993e026 bellard
                kqemu_allowed = 0;
8003 d993e026 bellard
                break;
8004 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
8005 89bfc105 bellard
                kqemu_allowed = 2;
8006 89bfc105 bellard
                break;
8007 d993e026 bellard
#endif
8008 bb36d470 bellard
            case QEMU_OPTION_usb:
8009 bb36d470 bellard
                usb_enabled = 1;
8010 bb36d470 bellard
                break;
8011 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
8012 a594cfbf bellard
                usb_enabled = 1;
8013 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
8014 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
8015 a594cfbf bellard
                    exit(1);
8016 a594cfbf bellard
                }
8017 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
8018 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
8019 a594cfbf bellard
                        optarg);
8020 a594cfbf bellard
                usb_devices_index++;
8021 a594cfbf bellard
                break;
8022 6a00d601 bellard
            case QEMU_OPTION_smp:
8023 6a00d601 bellard
                smp_cpus = atoi(optarg);
8024 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
8025 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
8026 6a00d601 bellard
                    exit(1);
8027 6a00d601 bellard
                }
8028 6a00d601 bellard
                break;
8029 24236869 bellard
            case QEMU_OPTION_vnc:
8030 73fc9742 ths
                vnc_display = optarg;
8031 24236869 bellard
                break;
8032 6515b203 bellard
            case QEMU_OPTION_no_acpi:
8033 6515b203 bellard
                acpi_enabled = 0;
8034 6515b203 bellard
                break;
8035 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
8036 d1beab82 bellard
                no_reboot = 1;
8037 d1beab82 bellard
                break;
8038 9467cd46 balrog
            case QEMU_OPTION_show_cursor:
8039 9467cd46 balrog
                cursor_hide = 0;
8040 9467cd46 balrog
                break;
8041 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
8042 71e3ceb8 ths
                daemonize = 1;
8043 71e3ceb8 ths
                break;
8044 9ae02555 ths
            case QEMU_OPTION_option_rom:
8045 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
8046 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
8047 9ae02555 ths
                    exit(1);
8048 9ae02555 ths
                }
8049 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
8050 9ae02555 ths
                nb_option_roms++;
8051 9ae02555 ths
                break;
8052 8e71621f pbrook
            case QEMU_OPTION_semihosting:
8053 8e71621f pbrook
                semihosting_enabled = 1;
8054 8e71621f pbrook
                break;
8055 c35734b2 ths
            case QEMU_OPTION_name:
8056 c35734b2 ths
                qemu_name = optarg;
8057 c35734b2 ths
                break;
8058 66508601 blueswir1
#ifdef TARGET_SPARC
8059 66508601 blueswir1
            case QEMU_OPTION_prom_env:
8060 66508601 blueswir1
                if (nb_prom_envs >= MAX_PROM_ENVS) {
8061 66508601 blueswir1
                    fprintf(stderr, "Too many prom variables\n");
8062 66508601 blueswir1
                    exit(1);
8063 66508601 blueswir1
                }
8064 66508601 blueswir1
                prom_envs[nb_prom_envs] = optarg;
8065 66508601 blueswir1
                nb_prom_envs++;
8066 66508601 blueswir1
                break;
8067 66508601 blueswir1
#endif
8068 2b8f2d41 balrog
#ifdef TARGET_ARM
8069 2b8f2d41 balrog
            case QEMU_OPTION_old_param:
8070 2b8f2d41 balrog
                old_param = 1;
8071 2b8f2d41 balrog
#endif
8072 f3dcfada ths
            case QEMU_OPTION_clock:
8073 f3dcfada ths
                configure_alarms(optarg);
8074 f3dcfada ths
                break;
8075 cd6f1169 bellard
            }
8076 0824d6fc bellard
        }
8077 0824d6fc bellard
    }
8078 330d0414 bellard
8079 71e3ceb8 ths
#ifndef _WIN32
8080 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
8081 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
8082 71e3ceb8 ths
        daemonize = 0;
8083 71e3ceb8 ths
    }
8084 71e3ceb8 ths
8085 71e3ceb8 ths
    if (daemonize) {
8086 71e3ceb8 ths
        pid_t pid;
8087 71e3ceb8 ths
8088 71e3ceb8 ths
        if (pipe(fds) == -1)
8089 71e3ceb8 ths
            exit(1);
8090 71e3ceb8 ths
8091 71e3ceb8 ths
        pid = fork();
8092 71e3ceb8 ths
        if (pid > 0) {
8093 71e3ceb8 ths
            uint8_t status;
8094 71e3ceb8 ths
            ssize_t len;
8095 71e3ceb8 ths
8096 71e3ceb8 ths
            close(fds[1]);
8097 71e3ceb8 ths
8098 71e3ceb8 ths
        again:
8099 93815bc2 ths
            len = read(fds[0], &status, 1);
8100 93815bc2 ths
            if (len == -1 && (errno == EINTR))
8101 93815bc2 ths
                goto again;
8102 93815bc2 ths
8103 93815bc2 ths
            if (len != 1)
8104 93815bc2 ths
                exit(1);
8105 93815bc2 ths
            else if (status == 1) {
8106 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
8107 93815bc2 ths
                exit(1);
8108 93815bc2 ths
            } else
8109 93815bc2 ths
                exit(0);
8110 71e3ceb8 ths
        } else if (pid < 0)
8111 93815bc2 ths
            exit(1);
8112 71e3ceb8 ths
8113 71e3ceb8 ths
        setsid();
8114 71e3ceb8 ths
8115 71e3ceb8 ths
        pid = fork();
8116 71e3ceb8 ths
        if (pid > 0)
8117 71e3ceb8 ths
            exit(0);
8118 71e3ceb8 ths
        else if (pid < 0)
8119 71e3ceb8 ths
            exit(1);
8120 71e3ceb8 ths
8121 71e3ceb8 ths
        umask(027);
8122 71e3ceb8 ths
        chdir("/");
8123 71e3ceb8 ths
8124 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
8125 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
8126 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
8127 71e3ceb8 ths
    }
8128 71e3ceb8 ths
#endif
8129 71e3ceb8 ths
8130 aa26bb2d ths
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
8131 93815bc2 ths
        if (daemonize) {
8132 93815bc2 ths
            uint8_t status = 1;
8133 93815bc2 ths
            write(fds[1], &status, 1);
8134 93815bc2 ths
        } else
8135 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
8136 93815bc2 ths
        exit(1);
8137 93815bc2 ths
    }
8138 93815bc2 ths
8139 ff3fbb30 bellard
#ifdef USE_KQEMU
8140 ff3fbb30 bellard
    if (smp_cpus > 1)
8141 ff3fbb30 bellard
        kqemu_allowed = 0;
8142 ff3fbb30 bellard
#endif
8143 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
8144 42550fde ths
8145 42550fde ths
    if (!linux_boot &&
8146 d84fe7ae ths
        boot_device != 'n' &&
8147 5fafdf24 ths
        hd_filename[0] == '\0' &&
8148 96d30e48 ths
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
8149 c45886db bellard
        fd_filename[0] == '\0')
8150 15f82208 ths
        help(1);
8151 0824d6fc bellard
8152 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
8153 96d30e48 ths
    if (hd_filename[0] == '\0' && boot_device == 'c') {
8154 96d30e48 ths
        if (fd_filename[0] != '\0')
8155 96d30e48 ths
            boot_device = 'a';
8156 96d30e48 ths
        else
8157 96d30e48 ths
            boot_device = 'd';
8158 96d30e48 ths
    }
8159 96d30e48 ths
8160 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
8161 5fafdf24 ths
   
8162 634fce96 pbrook
    init_timers();
8163 634fce96 pbrook
    init_timer_alarm();
8164 83f64091 bellard
    qemu_aio_init();
8165 634fce96 pbrook
8166 fd1dff4b bellard
#ifdef _WIN32
8167 fd1dff4b bellard
    socket_init();
8168 fd1dff4b bellard
#endif
8169 fd1dff4b bellard
8170 7c9d8e07 bellard
    /* init network clients */
8171 7c9d8e07 bellard
    if (nb_net_clients == 0) {
8172 7c9d8e07 bellard
        /* if no clients, we use a default config */
8173 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
8174 7c9d8e07 bellard
                "nic");
8175 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
8176 7c9d8e07 bellard
                "user");
8177 7c9d8e07 bellard
        nb_net_clients = 2;
8178 c20709aa bellard
    }
8179 c20709aa bellard
8180 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
8181 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
8182 7c9d8e07 bellard
            exit(1);
8183 702c651c bellard
    }
8184 833c7174 blueswir1
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8185 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8186 833c7174 blueswir1
            continue;
8187 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0) {
8188 833c7174 blueswir1
            fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
8189 833c7174 blueswir1
            exit(1);
8190 833c7174 blueswir1
        }
8191 833c7174 blueswir1
        if (vlan->nb_host_devs == 0)
8192 833c7174 blueswir1
            fprintf(stderr,
8193 833c7174 blueswir1
                    "Warning: vlan %d is not connected to host network\n",
8194 833c7174 blueswir1
                    vlan->id);
8195 833c7174 blueswir1
    }
8196 f1510b2c bellard
8197 eec85c2a ths
#ifdef TARGET_I386
8198 eec85c2a ths
    if (boot_device == 'n') {
8199 eec85c2a ths
        for (i = 0; i < nb_nics; i++) {
8200 eec85c2a ths
            const char *model = nd_table[i].model;
8201 eec85c2a ths
            char buf[1024];
8202 eec85c2a ths
            if (model == NULL)
8203 eec85c2a ths
                model = "ne2k_pci";
8204 eec85c2a ths
            snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8205 eec85c2a ths
            if (get_image_size(buf) > 0) {
8206 eec85c2a ths
                option_rom[nb_option_roms] = strdup(buf);
8207 eec85c2a ths
                nb_option_roms++;
8208 eec85c2a ths
                break;
8209 eec85c2a ths
            }
8210 eec85c2a ths
        }
8211 eec85c2a ths
        if (i == nb_nics) {
8212 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
8213 eec85c2a ths
            exit(1);
8214 eec85c2a ths
        }
8215 eec85c2a ths
    }
8216 eec85c2a ths
#endif
8217 eec85c2a ths
8218 0824d6fc bellard
    /* init the memory */
8219 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
8220 9ae02555 ths
8221 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
8222 7f7f9873 bellard
    if (!phys_ram_base) {
8223 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
8224 0824d6fc bellard
        exit(1);
8225 0824d6fc bellard
    }
8226 0824d6fc bellard
8227 96d30e48 ths
    /* we always create the cdrom drive, even if no disk is there */
8228 5905b2e5 bellard
    bdrv_init();
8229 96d30e48 ths
    if (cdrom_index >= 0) {
8230 96d30e48 ths
        bs_table[cdrom_index] = bdrv_new("cdrom");
8231 96d30e48 ths
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
8232 c4b1fcc0 bellard
    }
8233 c4b1fcc0 bellard
8234 96d30e48 ths
    /* open the virtual block devices */
8235 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++) {
8236 96d30e48 ths
        if (hd_filename[i]) {
8237 96d30e48 ths
            if (!bs_table[i]) {
8238 96d30e48 ths
                char buf[64];
8239 96d30e48 ths
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
8240 96d30e48 ths
                bs_table[i] = bdrv_new(buf);
8241 96d30e48 ths
            }
8242 96d30e48 ths
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8243 96d30e48 ths
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
8244 96d30e48 ths
                        hd_filename[i]);
8245 96d30e48 ths
                exit(1);
8246 96d30e48 ths
            }
8247 96d30e48 ths
            if (i == 0 && cyls != 0) {
8248 96d30e48 ths
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
8249 96d30e48 ths
                bdrv_set_translation_hint(bs_table[i], translation);
8250 96d30e48 ths
            }
8251 96d30e48 ths
        }
8252 c4b1fcc0 bellard
    }
8253 c4b1fcc0 bellard
8254 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
8255 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
8256 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
8257 c4b1fcc0 bellard
8258 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
8259 c4b1fcc0 bellard
        if (fd_filename[i]) {
8260 c4b1fcc0 bellard
            if (!fd_table[i]) {
8261 c4b1fcc0 bellard
                char buf[64];
8262 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
8263 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
8264 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
8265 c4b1fcc0 bellard
            }
8266 a1bb27b1 pbrook
            if (fd_filename[i][0] != '\0') {
8267 83f64091 bellard
                if (bdrv_open(fd_table[i], fd_filename[i],
8268 83f64091 bellard
                              snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8269 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
8270 c4b1fcc0 bellard
                            fd_filename[i]);
8271 c4b1fcc0 bellard
                    exit(1);
8272 c4b1fcc0 bellard
                }
8273 c4b1fcc0 bellard
            }
8274 33e3963e bellard
        }
8275 33e3963e bellard
    }
8276 33e3963e bellard
8277 2bac6019 balrog
    /* Open the virtual parallel flash block devices */
8278 86f55663 j_mayer
    for(i = 0; i < MAX_PFLASH; i++) {
8279 86f55663 j_mayer
        if (pflash_filename[i]) {
8280 86f55663 j_mayer
            if (!pflash_table[i]) {
8281 86f55663 j_mayer
                char buf[64];
8282 86f55663 j_mayer
                snprintf(buf, sizeof(buf), "fl%c", i + 'a');
8283 86f55663 j_mayer
                pflash_table[i] = bdrv_new(buf);
8284 86f55663 j_mayer
            }
8285 86f55663 j_mayer
            if (bdrv_open(pflash_table[i], pflash_filename[i],
8286 86f55663 j_mayer
                          snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8287 86f55663 j_mayer
                fprintf(stderr, "qemu: could not open flash image '%s'\n",
8288 86f55663 j_mayer
                        pflash_filename[i]);
8289 86f55663 j_mayer
                exit(1);
8290 86f55663 j_mayer
            }
8291 86f55663 j_mayer
        }
8292 86f55663 j_mayer
    }
8293 86f55663 j_mayer
8294 a1bb27b1 pbrook
    sd_bdrv = bdrv_new ("sd");
8295 a1bb27b1 pbrook
    /* FIXME: This isn't really a floppy, but it's a reasonable
8296 a1bb27b1 pbrook
       approximation.  */
8297 a1bb27b1 pbrook
    bdrv_set_type_hint(sd_bdrv, BDRV_TYPE_FLOPPY);
8298 a1bb27b1 pbrook
    if (sd_filename) {
8299 a1bb27b1 pbrook
        if (bdrv_open(sd_bdrv, sd_filename,
8300 a1bb27b1 pbrook
                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
8301 a1bb27b1 pbrook
            fprintf(stderr, "qemu: could not open SD card image %s\n",
8302 a1bb27b1 pbrook
                    sd_filename);
8303 2bac6019 balrog
        } else
8304 a171fe39 balrog
            qemu_key_check(sd_bdrv, sd_filename);
8305 a1bb27b1 pbrook
    }
8306 a1bb27b1 pbrook
8307 3e3d5815 balrog
    if (mtd_filename) {
8308 3e3d5815 balrog
        mtd_bdrv = bdrv_new ("mtd");
8309 3e3d5815 balrog
        if (bdrv_open(mtd_bdrv, mtd_filename,
8310 3e3d5815 balrog
                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0 ||
8311 3e3d5815 balrog
            qemu_key_check(mtd_bdrv, mtd_filename)) {
8312 3e3d5815 balrog
            fprintf(stderr, "qemu: could not open Flash image %s\n",
8313 3e3d5815 balrog
                    mtd_filename);
8314 3e3d5815 balrog
            bdrv_delete(mtd_bdrv);
8315 3e3d5815 balrog
            mtd_bdrv = 0;
8316 3e3d5815 balrog
        }
8317 3e3d5815 balrog
    }
8318 3e3d5815 balrog
8319 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
8320 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
8321 8a7ddc38 bellard
8322 330d0414 bellard
    init_ioports();
8323 0824d6fc bellard
8324 313aa567 bellard
    /* terminal init */
8325 740733bb ths
    memset(&display_state, 0, sizeof(display_state));
8326 a20dd508 bellard
    if (nographic) {
8327 2ff89790 ths
        /* nearly nothing to do */
8328 2ff89790 ths
        dumb_display_init(ds);
8329 73fc9742 ths
    } else if (vnc_display != NULL) {
8330 71cab5ca ths
        vnc_display_init(ds);
8331 71cab5ca ths
        if (vnc_display_open(ds, vnc_display) < 0)
8332 71cab5ca ths
            exit(1);
8333 313aa567 bellard
    } else {
8334 5b0753e0 bellard
#if defined(CONFIG_SDL)
8335 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
8336 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
8337 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
8338 313aa567 bellard
#endif
8339 313aa567 bellard
    }
8340 0824d6fc bellard
8341 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
8342 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
8343 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
8344 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
8345 20d8a3ed ths
                monitor_device[0] = '\0';
8346 20d8a3ed ths
                break;
8347 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
8348 20d8a3ed ths
                monitor_device[0] = '\0';
8349 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
8350 20d8a3ed ths
                break;
8351 20d8a3ed ths
            }
8352 20d8a3ed ths
        }
8353 20d8a3ed ths
    }
8354 20d8a3ed ths
    if (monitor_device[0] != '\0') {
8355 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
8356 20d8a3ed ths
        if (!monitor_hd) {
8357 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
8358 20d8a3ed ths
            exit(1);
8359 20d8a3ed ths
        }
8360 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
8361 82c643ff bellard
    }
8362 82c643ff bellard
8363 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
8364 c03b0f0f bellard
        const char *devname = serial_devices[i];
8365 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8366 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
8367 8d11df9e bellard
            if (!serial_hds[i]) {
8368 5fafdf24 ths
                fprintf(stderr, "qemu: could not open serial device '%s'\n",
8369 c03b0f0f bellard
                        devname);
8370 8d11df9e bellard
                exit(1);
8371 8d11df9e bellard
            }
8372 af3a9031 ths
            if (strstart(devname, "vc", 0))
8373 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
8374 8d11df9e bellard
        }
8375 82c643ff bellard
    }
8376 82c643ff bellard
8377 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
8378 c03b0f0f bellard
        const char *devname = parallel_devices[i];
8379 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8380 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
8381 6508fe59 bellard
            if (!parallel_hds[i]) {
8382 5fafdf24 ths
                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
8383 c03b0f0f bellard
                        devname);
8384 6508fe59 bellard
                exit(1);
8385 6508fe59 bellard
            }
8386 af3a9031 ths
            if (strstart(devname, "vc", 0))
8387 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
8388 6508fe59 bellard
        }
8389 6508fe59 bellard
    }
8390 6508fe59 bellard
8391 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
8392 cc1daa40 bellard
                  ds, fd_filename, snapshot,
8393 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
8394 73332e5c bellard
8395 0d92ed30 pbrook
    /* init USB devices */
8396 0d92ed30 pbrook
    if (usb_enabled) {
8397 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
8398 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
8399 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
8400 0d92ed30 pbrook
                        usb_devices[i]);
8401 0d92ed30 pbrook
            }
8402 0d92ed30 pbrook
        }
8403 0d92ed30 pbrook
    }
8404 0d92ed30 pbrook
8405 740733bb ths
    if (display_state.dpy_refresh) {
8406 740733bb ths
        display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
8407 740733bb ths
        qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
8408 740733bb ths
    }
8409 7f7f9873 bellard
8410 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8411 b4608c04 bellard
    if (use_gdbstub) {
8412 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
8413 c636bb66 bellard
           accordingly. */
8414 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
8415 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
8416 c636bb66 bellard
                    gdbstub_port);
8417 8a7ddc38 bellard
            exit(1);
8418 8a7ddc38 bellard
        }
8419 45669e00 balrog
    }
8420 67b915a5 bellard
#endif
8421 45669e00 balrog
8422 d63d307f bellard
    if (loadvm)
8423 faea38e7 bellard
        do_loadvm(loadvm);
8424 d63d307f bellard
8425 67b915a5 bellard
    {
8426 5905b2e5 bellard
        /* XXX: simplify init */
8427 5905b2e5 bellard
        read_passwords();
8428 3c07f8e8 pbrook
        if (autostart) {
8429 5905b2e5 bellard
            vm_start();
8430 5905b2e5 bellard
        }
8431 0824d6fc bellard
    }
8432 ffd843bc ths
8433 71e3ceb8 ths
    if (daemonize) {
8434 71e3ceb8 ths
        uint8_t status = 0;
8435 71e3ceb8 ths
        ssize_t len;
8436 71e3ceb8 ths
        int fd;
8437 71e3ceb8 ths
8438 71e3ceb8 ths
    again1:
8439 71e3ceb8 ths
        len = write(fds[1], &status, 1);
8440 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
8441 71e3ceb8 ths
            goto again1;
8442 71e3ceb8 ths
8443 71e3ceb8 ths
        if (len != 1)
8444 71e3ceb8 ths
            exit(1);
8445 71e3ceb8 ths
8446 aeb30be6 balrog
        TFR(fd = open("/dev/null", O_RDWR));
8447 71e3ceb8 ths
        if (fd == -1)
8448 71e3ceb8 ths
            exit(1);
8449 71e3ceb8 ths
8450 71e3ceb8 ths
        dup2(fd, 0);
8451 71e3ceb8 ths
        dup2(fd, 1);
8452 71e3ceb8 ths
        dup2(fd, 2);
8453 71e3ceb8 ths
8454 71e3ceb8 ths
        close(fd);
8455 71e3ceb8 ths
    }
8456 71e3ceb8 ths
8457 8a7ddc38 bellard
    main_loop();
8458 40c3bac3 bellard
    quit_timers();
8459 0824d6fc bellard
    return 0;
8460 0824d6fc bellard
}