Statistics
| Branch: | Revision:

root / vl.c @ 231c6586

History | View | Annotate | Download (216.8 kB)

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

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

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