Statistics
| Branch: | Revision:

root / vl.c @ efe75411

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 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t);
833 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
834 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
835 efe75411 ths
836 c8994013 ths
#ifdef __linux__
837 c8994013 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 efe75411 ths
    {"dynticks", ALARM_FLAG_DYNTICKS, dynticks_start_timer,
851 efe75411 ths
     dynticks_stop_timer, dynticks_rearm_timer, NULL},
852 c8994013 ths
#ifdef __linux__
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 829309c7 bellard
#endif /* !defined(__linux__) */
1303 829309c7 bellard
1304 efe75411 ths
static int dynticks_start_timer(struct qemu_alarm_timer *t)
1305 efe75411 ths
{
1306 efe75411 ths
    struct sigevent ev;
1307 efe75411 ths
    timer_t host_timer;
1308 efe75411 ths
    struct sigaction act;
1309 efe75411 ths
1310 efe75411 ths
    sigfillset(&act.sa_mask);
1311 efe75411 ths
    act.sa_flags = 0;
1312 efe75411 ths
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
1313 efe75411 ths
    act.sa_flags |= SA_ONSTACK;
1314 efe75411 ths
#endif
1315 efe75411 ths
    act.sa_handler = host_alarm_handler;
1316 efe75411 ths
1317 efe75411 ths
    sigaction(SIGALRM, &act, NULL);
1318 efe75411 ths
1319 efe75411 ths
    ev.sigev_value.sival_int = 0;
1320 efe75411 ths
    ev.sigev_notify = SIGEV_SIGNAL;
1321 efe75411 ths
    ev.sigev_signo = SIGALRM;
1322 efe75411 ths
1323 efe75411 ths
    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
1324 efe75411 ths
        perror("timer_create");
1325 efe75411 ths
1326 efe75411 ths
        /* disable dynticks */
1327 efe75411 ths
        fprintf(stderr, "Dynamic Ticks disabled\n");
1328 efe75411 ths
1329 efe75411 ths
        return -1;
1330 efe75411 ths
    }
1331 efe75411 ths
1332 efe75411 ths
    t->priv = (void *)host_timer;
1333 efe75411 ths
1334 efe75411 ths
    return 0;
1335 efe75411 ths
}
1336 efe75411 ths
1337 efe75411 ths
static void dynticks_stop_timer(struct qemu_alarm_timer *t)
1338 efe75411 ths
{
1339 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1340 efe75411 ths
1341 efe75411 ths
    timer_delete(host_timer);
1342 efe75411 ths
}
1343 efe75411 ths
1344 efe75411 ths
static void dynticks_rearm_timer(struct qemu_alarm_timer *t)
1345 efe75411 ths
{
1346 efe75411 ths
    timer_t host_timer = (timer_t)t->priv;
1347 efe75411 ths
    struct itimerspec timeout;
1348 efe75411 ths
    int64_t nearest_delta_us = INT64_MAX;
1349 efe75411 ths
    int64_t current_us;
1350 efe75411 ths
1351 efe75411 ths
    if (!active_timers[QEMU_TIMER_REALTIME] &&
1352 efe75411 ths
                !active_timers[QEMU_TIMER_VIRTUAL])
1353 efe75411 ths
            return;
1354 efe75411 ths
1355 efe75411 ths
    nearest_delta_us = qemu_next_deadline();
1356 efe75411 ths
1357 efe75411 ths
    /* check whether a timer is already running */
1358 efe75411 ths
    if (timer_gettime(host_timer, &timeout)) {
1359 efe75411 ths
        perror("gettime");
1360 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1361 efe75411 ths
        exit(1);
1362 efe75411 ths
    }
1363 efe75411 ths
    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;
1364 efe75411 ths
    if (current_us && current_us <= nearest_delta_us)
1365 efe75411 ths
        return;
1366 efe75411 ths
1367 efe75411 ths
    timeout.it_interval.tv_sec = 0;
1368 efe75411 ths
    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
1369 efe75411 ths
    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;
1370 efe75411 ths
    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;
1371 efe75411 ths
    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
1372 efe75411 ths
        perror("settime");
1373 efe75411 ths
        fprintf(stderr, "Internal timer error: aborting\n");
1374 efe75411 ths
        exit(1);
1375 efe75411 ths
    }
1376 efe75411 ths
}
1377 efe75411 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
        printf("trying %s...\n", t->name);
1514 c8994013 ths
1515 c8994013 ths
        err = t->start(t);
1516 c8994013 ths
        if (!err)
1517 c8994013 ths
            break;
1518 67b915a5 bellard
    }
1519 fd872598 bellard
1520 c8994013 ths
    if (err) {
1521 c8994013 ths
        fprintf(stderr, "Unable to find any suitable alarm timer.\n");
1522 c8994013 ths
        fprintf(stderr, "Terminating\n");
1523 c8994013 ths
        exit(1);
1524 67b915a5 bellard
    }
1525 c8994013 ths
1526 c8994013 ths
    alarm_timer = t;
1527 8a7ddc38 bellard
}
1528 8a7ddc38 bellard
1529 40c3bac3 bellard
void quit_timers(void)
1530 40c3bac3 bellard
{
1531 c8994013 ths
    alarm_timer->stop(alarm_timer);
1532 c8994013 ths
    alarm_timer = NULL;
1533 40c3bac3 bellard
}
1534 40c3bac3 bellard
1535 c4b1fcc0 bellard
/***********************************************************/
1536 82c643ff bellard
/* character device */
1537 313aa567 bellard
1538 e5b0bc44 pbrook
static void qemu_chr_event(CharDriverState *s, int event)
1539 e5b0bc44 pbrook
{
1540 e5b0bc44 pbrook
    if (!s->chr_event)
1541 e5b0bc44 pbrook
        return;
1542 e5b0bc44 pbrook
    s->chr_event(s->handler_opaque, event);
1543 e5b0bc44 pbrook
}
1544 e5b0bc44 pbrook
1545 86e94dea ths
static void qemu_chr_reset_bh(void *opaque)
1546 86e94dea ths
{
1547 86e94dea ths
    CharDriverState *s = opaque;
1548 e5b0bc44 pbrook
    qemu_chr_event(s, CHR_EVENT_RESET);
1549 86e94dea ths
    qemu_bh_delete(s->bh);
1550 86e94dea ths
    s->bh = NULL;
1551 86e94dea ths
}
1552 86e94dea ths
1553 86e94dea ths
void qemu_chr_reset(CharDriverState *s)
1554 86e94dea ths
{
1555 86e94dea ths
    if (s->bh == NULL) {
1556 86e94dea ths
        s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1557 86e94dea ths
        qemu_bh_schedule(s->bh);
1558 86e94dea ths
    }
1559 86e94dea ths
}
1560 86e94dea ths
1561 82c643ff bellard
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
1562 82c643ff bellard
{
1563 82c643ff bellard
    return s->chr_write(s, buf, len);
1564 82c643ff bellard
}
1565 67b915a5 bellard
1566 e57a8c0e bellard
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
1567 f8d179e3 bellard
{
1568 e57a8c0e bellard
    if (!s->chr_ioctl)
1569 e57a8c0e bellard
        return -ENOTSUP;
1570 e57a8c0e bellard
    return s->chr_ioctl(s, cmd, arg);
1571 f8d179e3 bellard
}
1572 f8d179e3 bellard
1573 e5b0bc44 pbrook
int qemu_chr_can_read(CharDriverState *s)
1574 e5b0bc44 pbrook
{
1575 e5b0bc44 pbrook
    if (!s->chr_can_read)
1576 e5b0bc44 pbrook
        return 0;
1577 e5b0bc44 pbrook
    return s->chr_can_read(s->handler_opaque);
1578 e5b0bc44 pbrook
}
1579 e5b0bc44 pbrook
1580 e5b0bc44 pbrook
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1581 e5b0bc44 pbrook
{
1582 e5b0bc44 pbrook
    s->chr_read(s->handler_opaque, buf, len);
1583 e5b0bc44 pbrook
}
1584 e5b0bc44 pbrook
1585 e5b0bc44 pbrook
1586 82c643ff bellard
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1587 67b915a5 bellard
{
1588 82c643ff bellard
    char buf[4096];
1589 82c643ff bellard
    va_list ap;
1590 82c643ff bellard
    va_start(ap, fmt);
1591 82c643ff bellard
    vsnprintf(buf, sizeof(buf), fmt, ap);
1592 82c643ff bellard
    qemu_chr_write(s, buf, strlen(buf));
1593 82c643ff bellard
    va_end(ap);
1594 67b915a5 bellard
}
1595 67b915a5 bellard
1596 5905b2e5 bellard
void qemu_chr_send_event(CharDriverState *s, int event)
1597 5905b2e5 bellard
{
1598 5905b2e5 bellard
    if (s->chr_send_event)
1599 5905b2e5 bellard
        s->chr_send_event(s, event);
1600 5905b2e5 bellard
}
1601 5905b2e5 bellard
1602 e5b0bc44 pbrook
void qemu_chr_add_handlers(CharDriverState *s, 
1603 e5b0bc44 pbrook
                           IOCanRWHandler *fd_can_read, 
1604 e5b0bc44 pbrook
                           IOReadHandler *fd_read,
1605 e5b0bc44 pbrook
                           IOEventHandler *fd_event,
1606 e5b0bc44 pbrook
                           void *opaque)
1607 82c643ff bellard
{
1608 e5b0bc44 pbrook
    s->chr_can_read = fd_can_read;
1609 e5b0bc44 pbrook
    s->chr_read = fd_read;
1610 e5b0bc44 pbrook
    s->chr_event = fd_event;
1611 e5b0bc44 pbrook
    s->handler_opaque = opaque;
1612 e5b0bc44 pbrook
    if (s->chr_update_read_handler)
1613 e5b0bc44 pbrook
        s->chr_update_read_handler(s);
1614 82c643ff bellard
}
1615 82c643ff bellard
             
1616 82c643ff bellard
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1617 313aa567 bellard
{
1618 82c643ff bellard
    return len;
1619 82c643ff bellard
}
1620 82c643ff bellard
1621 52f61fde ths
static CharDriverState *qemu_chr_open_null(void)
1622 82c643ff bellard
{
1623 82c643ff bellard
    CharDriverState *chr;
1624 82c643ff bellard
1625 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1626 82c643ff bellard
    if (!chr)
1627 82c643ff bellard
        return NULL;
1628 82c643ff bellard
    chr->chr_write = null_chr_write;
1629 82c643ff bellard
    return chr;
1630 82c643ff bellard
}
1631 82c643ff bellard
1632 20d8a3ed ths
/* MUX driver for serial I/O splitting */
1633 20d8a3ed ths
static int term_timestamps;
1634 20d8a3ed ths
static int64_t term_timestamps_start;
1635 9c1de612 ths
#define MAX_MUX 4
1636 20d8a3ed ths
typedef struct {
1637 20d8a3ed ths
    IOCanRWHandler *chr_can_read[MAX_MUX];
1638 20d8a3ed ths
    IOReadHandler *chr_read[MAX_MUX];
1639 20d8a3ed ths
    IOEventHandler *chr_event[MAX_MUX];
1640 20d8a3ed ths
    void *ext_opaque[MAX_MUX];
1641 20d8a3ed ths
    CharDriverState *drv;
1642 20d8a3ed ths
    int mux_cnt;
1643 20d8a3ed ths
    int term_got_escape;
1644 20d8a3ed ths
    int max_size;
1645 20d8a3ed ths
} MuxDriver;
1646 20d8a3ed ths
1647 20d8a3ed ths
1648 20d8a3ed ths
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1649 20d8a3ed ths
{
1650 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1651 20d8a3ed ths
    int ret;
1652 20d8a3ed ths
    if (!term_timestamps) {
1653 20d8a3ed ths
        ret = d->drv->chr_write(d->drv, buf, len);
1654 20d8a3ed ths
    } else {
1655 20d8a3ed ths
        int i;
1656 20d8a3ed ths
1657 20d8a3ed ths
        ret = 0;
1658 20d8a3ed ths
        for(i = 0; i < len; i++) {
1659 20d8a3ed ths
            ret += d->drv->chr_write(d->drv, buf+i, 1);
1660 20d8a3ed ths
            if (buf[i] == '\n') {
1661 20d8a3ed ths
                char buf1[64];
1662 20d8a3ed ths
                int64_t ti;
1663 20d8a3ed ths
                int secs;
1664 20d8a3ed ths
1665 20d8a3ed ths
                ti = get_clock();
1666 20d8a3ed ths
                if (term_timestamps_start == -1)
1667 20d8a3ed ths
                    term_timestamps_start = ti;
1668 20d8a3ed ths
                ti -= term_timestamps_start;
1669 20d8a3ed ths
                secs = ti / 1000000000;
1670 20d8a3ed ths
                snprintf(buf1, sizeof(buf1),
1671 20d8a3ed ths
                         "[%02d:%02d:%02d.%03d] ",
1672 20d8a3ed ths
                         secs / 3600,
1673 20d8a3ed ths
                         (secs / 60) % 60,
1674 20d8a3ed ths
                         secs % 60,
1675 20d8a3ed ths
                         (int)((ti / 1000000) % 1000));
1676 20d8a3ed ths
                d->drv->chr_write(d->drv, buf1, strlen(buf1));
1677 20d8a3ed ths
            }
1678 20d8a3ed ths
        }
1679 20d8a3ed ths
    }
1680 20d8a3ed ths
    return ret;
1681 20d8a3ed ths
}
1682 20d8a3ed ths
1683 20d8a3ed ths
static char *mux_help[] = {
1684 20d8a3ed ths
    "% h    print this help\n\r",
1685 20d8a3ed ths
    "% x    exit emulator\n\r",
1686 20d8a3ed ths
    "% s    save disk data back to file (if -snapshot)\n\r",
1687 20d8a3ed ths
    "% t    toggle console timestamps\n\r"
1688 20d8a3ed ths
    "% b    send break (magic sysrq)\n\r",
1689 20d8a3ed ths
    "% c    switch between console and monitor\n\r",
1690 20d8a3ed ths
    "% %  sends %\n\r",
1691 20d8a3ed ths
    NULL
1692 20d8a3ed ths
};
1693 20d8a3ed ths
1694 20d8a3ed ths
static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1695 20d8a3ed ths
static void mux_print_help(CharDriverState *chr)
1696 20d8a3ed ths
{
1697 20d8a3ed ths
    int i, j;
1698 20d8a3ed ths
    char ebuf[15] = "Escape-Char";
1699 20d8a3ed ths
    char cbuf[50] = "\n\r";
1700 20d8a3ed ths
1701 20d8a3ed ths
    if (term_escape_char > 0 && term_escape_char < 26) {
1702 20d8a3ed ths
        sprintf(cbuf,"\n\r");
1703 20d8a3ed ths
        sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
1704 20d8a3ed ths
    } else {
1705 20d8a3ed ths
        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char);
1706 20d8a3ed ths
    }
1707 20d8a3ed ths
    chr->chr_write(chr, cbuf, strlen(cbuf));
1708 20d8a3ed ths
    for (i = 0; mux_help[i] != NULL; i++) {
1709 20d8a3ed ths
        for (j=0; mux_help[i][j] != '\0'; j++) {
1710 20d8a3ed ths
            if (mux_help[i][j] == '%')
1711 20d8a3ed ths
                chr->chr_write(chr, ebuf, strlen(ebuf));
1712 20d8a3ed ths
            else
1713 20d8a3ed ths
                chr->chr_write(chr, &mux_help[i][j], 1);
1714 20d8a3ed ths
        }
1715 20d8a3ed ths
    }
1716 20d8a3ed ths
}
1717 20d8a3ed ths
1718 20d8a3ed ths
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1719 20d8a3ed ths
{
1720 20d8a3ed ths
    if (d->term_got_escape) {
1721 20d8a3ed ths
        d->term_got_escape = 0;
1722 20d8a3ed ths
        if (ch == term_escape_char)
1723 20d8a3ed ths
            goto send_char;
1724 20d8a3ed ths
        switch(ch) {
1725 20d8a3ed ths
        case '?':
1726 20d8a3ed ths
        case 'h':
1727 20d8a3ed ths
            mux_print_help(chr);
1728 20d8a3ed ths
            break;
1729 20d8a3ed ths
        case 'x':
1730 20d8a3ed ths
            {
1731 20d8a3ed ths
                 char *term =  "QEMU: Terminated\n\r";
1732 20d8a3ed ths
                 chr->chr_write(chr,term,strlen(term));
1733 20d8a3ed ths
                 exit(0);
1734 20d8a3ed ths
                 break;
1735 20d8a3ed ths
            }
1736 20d8a3ed ths
        case 's':
1737 20d8a3ed ths
            {
1738 20d8a3ed ths
                int i;
1739 20d8a3ed ths
                for (i = 0; i < MAX_DISKS; i++) {
1740 20d8a3ed ths
                    if (bs_table[i])
1741 20d8a3ed ths
                        bdrv_commit(bs_table[i]);
1742 20d8a3ed ths
                }
1743 2dc7b602 balrog
                if (mtd_bdrv)
1744 2dc7b602 balrog
                    bdrv_commit(mtd_bdrv);
1745 20d8a3ed ths
            }
1746 20d8a3ed ths
            break;
1747 20d8a3ed ths
        case 'b':
1748 36ddb83b balrog
            qemu_chr_event(chr, CHR_EVENT_BREAK);
1749 20d8a3ed ths
            break;
1750 20d8a3ed ths
        case 'c':
1751 20d8a3ed ths
            /* Switch to the next registered device */
1752 20d8a3ed ths
            chr->focus++;
1753 20d8a3ed ths
            if (chr->focus >= d->mux_cnt)
1754 20d8a3ed ths
                chr->focus = 0;
1755 20d8a3ed ths
            break;
1756 20d8a3ed ths
       case 't':
1757 20d8a3ed ths
           term_timestamps = !term_timestamps;
1758 20d8a3ed ths
           term_timestamps_start = -1;
1759 20d8a3ed ths
           break;
1760 20d8a3ed ths
        }
1761 20d8a3ed ths
    } else if (ch == term_escape_char) {
1762 20d8a3ed ths
        d->term_got_escape = 1;
1763 20d8a3ed ths
    } else {
1764 20d8a3ed ths
    send_char:
1765 20d8a3ed ths
        return 1;
1766 20d8a3ed ths
    }
1767 20d8a3ed ths
    return 0;
1768 20d8a3ed ths
}
1769 20d8a3ed ths
1770 20d8a3ed ths
static int mux_chr_can_read(void *opaque)
1771 20d8a3ed ths
{
1772 20d8a3ed ths
    CharDriverState *chr = opaque;
1773 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1774 20d8a3ed ths
    if (d->chr_can_read[chr->focus])
1775 20d8a3ed ths
       return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
1776 20d8a3ed ths
    return 0;
1777 20d8a3ed ths
}
1778 20d8a3ed ths
1779 20d8a3ed ths
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1780 20d8a3ed ths
{
1781 20d8a3ed ths
    CharDriverState *chr = opaque;
1782 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1783 20d8a3ed ths
    int i;
1784 20d8a3ed ths
    for(i = 0; i < size; i++)
1785 20d8a3ed ths
        if (mux_proc_byte(chr, d, buf[i]))
1786 20d8a3ed ths
            d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
1787 20d8a3ed ths
}
1788 20d8a3ed ths
1789 20d8a3ed ths
static void mux_chr_event(void *opaque, int event)
1790 20d8a3ed ths
{
1791 20d8a3ed ths
    CharDriverState *chr = opaque;
1792 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1793 20d8a3ed ths
    int i;
1794 20d8a3ed ths
1795 20d8a3ed ths
    /* Send the event to all registered listeners */
1796 20d8a3ed ths
    for (i = 0; i < d->mux_cnt; i++)
1797 20d8a3ed ths
        if (d->chr_event[i])
1798 20d8a3ed ths
            d->chr_event[i](d->ext_opaque[i], event);
1799 20d8a3ed ths
}
1800 20d8a3ed ths
1801 20d8a3ed ths
static void mux_chr_update_read_handler(CharDriverState *chr)
1802 20d8a3ed ths
{
1803 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1804 20d8a3ed ths
1805 20d8a3ed ths
    if (d->mux_cnt >= MAX_MUX) {
1806 20d8a3ed ths
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
1807 20d8a3ed ths
        return;
1808 20d8a3ed ths
    }
1809 20d8a3ed ths
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
1810 20d8a3ed ths
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
1811 20d8a3ed ths
    d->chr_read[d->mux_cnt] = chr->chr_read;
1812 20d8a3ed ths
    d->chr_event[d->mux_cnt] = chr->chr_event;
1813 20d8a3ed ths
    /* Fix up the real driver with mux routines */
1814 20d8a3ed ths
    if (d->mux_cnt == 0) {
1815 20d8a3ed ths
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
1816 20d8a3ed ths
                              mux_chr_event, chr);
1817 20d8a3ed ths
    }
1818 20d8a3ed ths
    chr->focus = d->mux_cnt;
1819 20d8a3ed ths
    d->mux_cnt++;
1820 20d8a3ed ths
}
1821 20d8a3ed ths
1822 20d8a3ed ths
CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
1823 20d8a3ed ths
{
1824 20d8a3ed ths
    CharDriverState *chr;
1825 20d8a3ed ths
    MuxDriver *d;
1826 20d8a3ed ths
1827 20d8a3ed ths
    chr = qemu_mallocz(sizeof(CharDriverState));
1828 20d8a3ed ths
    if (!chr)
1829 20d8a3ed ths
        return NULL;
1830 20d8a3ed ths
    d = qemu_mallocz(sizeof(MuxDriver));
1831 20d8a3ed ths
    if (!d) {
1832 20d8a3ed ths
        free(chr);
1833 20d8a3ed ths
        return NULL;
1834 20d8a3ed ths
    }
1835 20d8a3ed ths
1836 20d8a3ed ths
    chr->opaque = d;
1837 20d8a3ed ths
    d->drv = drv;
1838 20d8a3ed ths
    chr->focus = -1;
1839 20d8a3ed ths
    chr->chr_write = mux_chr_write;
1840 20d8a3ed ths
    chr->chr_update_read_handler = mux_chr_update_read_handler;
1841 20d8a3ed ths
    return chr;
1842 20d8a3ed ths
}
1843 20d8a3ed ths
1844 20d8a3ed ths
1845 fd1dff4b bellard
#ifdef _WIN32
1846 82c643ff bellard
1847 fd1dff4b bellard
static void socket_cleanup(void)
1848 fd1dff4b bellard
{
1849 fd1dff4b bellard
    WSACleanup();
1850 fd1dff4b bellard
}
1851 82c643ff bellard
1852 fd1dff4b bellard
static int socket_init(void)
1853 fd1dff4b bellard
{
1854 fd1dff4b bellard
    WSADATA Data;
1855 fd1dff4b bellard
    int ret, err;
1856 fd1dff4b bellard
1857 fd1dff4b bellard
    ret = WSAStartup(MAKEWORD(2,2), &Data);
1858 fd1dff4b bellard
    if (ret != 0) {
1859 fd1dff4b bellard
        err = WSAGetLastError();
1860 fd1dff4b bellard
        fprintf(stderr, "WSAStartup: %d\n", err);
1861 fd1dff4b bellard
        return -1;
1862 fd1dff4b bellard
    }
1863 fd1dff4b bellard
    atexit(socket_cleanup);
1864 fd1dff4b bellard
    return 0;
1865 fd1dff4b bellard
}
1866 fd1dff4b bellard
1867 fd1dff4b bellard
static int send_all(int fd, const uint8_t *buf, int len1)
1868 fd1dff4b bellard
{
1869 fd1dff4b bellard
    int ret, len;
1870 fd1dff4b bellard
    
1871 fd1dff4b bellard
    len = len1;
1872 fd1dff4b bellard
    while (len > 0) {
1873 fd1dff4b bellard
        ret = send(fd, buf, len, 0);
1874 fd1dff4b bellard
        if (ret < 0) {
1875 fd1dff4b bellard
            int errno;
1876 fd1dff4b bellard
            errno = WSAGetLastError();
1877 fd1dff4b bellard
            if (errno != WSAEWOULDBLOCK) {
1878 fd1dff4b bellard
                return -1;
1879 fd1dff4b bellard
            }
1880 fd1dff4b bellard
        } else if (ret == 0) {
1881 fd1dff4b bellard
            break;
1882 fd1dff4b bellard
        } else {
1883 fd1dff4b bellard
            buf += ret;
1884 fd1dff4b bellard
            len -= ret;
1885 fd1dff4b bellard
        }
1886 fd1dff4b bellard
    }
1887 fd1dff4b bellard
    return len1 - len;
1888 fd1dff4b bellard
}
1889 fd1dff4b bellard
1890 fd1dff4b bellard
void socket_set_nonblock(int fd)
1891 fd1dff4b bellard
{
1892 fd1dff4b bellard
    unsigned long opt = 1;
1893 fd1dff4b bellard
    ioctlsocket(fd, FIONBIO, &opt);
1894 fd1dff4b bellard
}
1895 fd1dff4b bellard
1896 fd1dff4b bellard
#else
1897 fd1dff4b bellard
1898 1d96905d bellard
static int unix_write(int fd, const uint8_t *buf, int len1)
1899 1d96905d bellard
{
1900 1d96905d bellard
    int ret, len;
1901 1d96905d bellard
1902 1d96905d bellard
    len = len1;
1903 1d96905d bellard
    while (len > 0) {
1904 1d96905d bellard
        ret = write(fd, buf, len);
1905 1d96905d bellard
        if (ret < 0) {
1906 1d96905d bellard
            if (errno != EINTR && errno != EAGAIN)
1907 1d96905d bellard
                return -1;
1908 1d96905d bellard
        } else if (ret == 0) {
1909 1d96905d bellard
            break;
1910 1d96905d bellard
        } else {
1911 1d96905d bellard
            buf += ret;
1912 1d96905d bellard
            len -= ret;
1913 1d96905d bellard
        }
1914 1d96905d bellard
    }
1915 1d96905d bellard
    return len1 - len;
1916 1d96905d bellard
}
1917 1d96905d bellard
1918 fd1dff4b bellard
static inline int send_all(int fd, const uint8_t *buf, int len1)
1919 fd1dff4b bellard
{
1920 fd1dff4b bellard
    return unix_write(fd, buf, len1);
1921 fd1dff4b bellard
}
1922 fd1dff4b bellard
1923 fd1dff4b bellard
void socket_set_nonblock(int fd)
1924 fd1dff4b bellard
{
1925 fd1dff4b bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1926 fd1dff4b bellard
}
1927 fd1dff4b bellard
#endif /* !_WIN32 */
1928 fd1dff4b bellard
1929 fd1dff4b bellard
#ifndef _WIN32
1930 fd1dff4b bellard
1931 fd1dff4b bellard
typedef struct {
1932 fd1dff4b bellard
    int fd_in, fd_out;
1933 fd1dff4b bellard
    int max_size;
1934 fd1dff4b bellard
} FDCharDriver;
1935 fd1dff4b bellard
1936 20d8a3ed ths
#define STDIO_MAX_CLIENTS 1
1937 20d8a3ed ths
static int stdio_nb_clients = 0;
1938 fd1dff4b bellard
1939 82c643ff bellard
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1940 82c643ff bellard
{
1941 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1942 1d96905d bellard
    return unix_write(s->fd_out, buf, len);
1943 82c643ff bellard
}
1944 82c643ff bellard
1945 7c9d8e07 bellard
static int fd_chr_read_poll(void *opaque)
1946 7c9d8e07 bellard
{
1947 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1948 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1949 7c9d8e07 bellard
1950 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
1951 7c9d8e07 bellard
    return s->max_size;
1952 7c9d8e07 bellard
}
1953 7c9d8e07 bellard
1954 7c9d8e07 bellard
static void fd_chr_read(void *opaque)
1955 7c9d8e07 bellard
{
1956 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1957 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1958 7c9d8e07 bellard
    int size, len;
1959 7c9d8e07 bellard
    uint8_t buf[1024];
1960 7c9d8e07 bellard
    
1961 7c9d8e07 bellard
    len = sizeof(buf);
1962 7c9d8e07 bellard
    if (len > s->max_size)
1963 7c9d8e07 bellard
        len = s->max_size;
1964 7c9d8e07 bellard
    if (len == 0)
1965 7c9d8e07 bellard
        return;
1966 7c9d8e07 bellard
    size = read(s->fd_in, buf, len);
1967 188157fe pbrook
    if (size == 0) {
1968 188157fe pbrook
        /* FD has been closed. Remove it from the active list.  */
1969 188157fe pbrook
        qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
1970 188157fe pbrook
        return;
1971 188157fe pbrook
    }
1972 7c9d8e07 bellard
    if (size > 0) {
1973 e5b0bc44 pbrook
        qemu_chr_read(chr, buf, size);
1974 7c9d8e07 bellard
    }
1975 7c9d8e07 bellard
}
1976 7c9d8e07 bellard
1977 e5b0bc44 pbrook
static void fd_chr_update_read_handler(CharDriverState *chr)
1978 82c643ff bellard
{
1979 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1980 82c643ff bellard
1981 f8d179e3 bellard
    if (s->fd_in >= 0) {
1982 f8d179e3 bellard
        if (nographic && s->fd_in == 0) {
1983 f8d179e3 bellard
        } else {
1984 7c9d8e07 bellard
            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll, 
1985 7c9d8e07 bellard
                                 fd_chr_read, NULL, chr);
1986 f8d179e3 bellard
        }
1987 82c643ff bellard
    }
1988 82c643ff bellard
}
1989 82c643ff bellard
1990 82c643ff bellard
/* open a character device to a unix fd */
1991 52f61fde ths
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
1992 82c643ff bellard
{
1993 82c643ff bellard
    CharDriverState *chr;
1994 82c643ff bellard
    FDCharDriver *s;
1995 82c643ff bellard
1996 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1997 82c643ff bellard
    if (!chr)
1998 82c643ff bellard
        return NULL;
1999 82c643ff bellard
    s = qemu_mallocz(sizeof(FDCharDriver));
2000 82c643ff bellard
    if (!s) {
2001 82c643ff bellard
        free(chr);
2002 82c643ff bellard
        return NULL;
2003 82c643ff bellard
    }
2004 82c643ff bellard
    s->fd_in = fd_in;
2005 82c643ff bellard
    s->fd_out = fd_out;
2006 82c643ff bellard
    chr->opaque = s;
2007 82c643ff bellard
    chr->chr_write = fd_chr_write;
2008 e5b0bc44 pbrook
    chr->chr_update_read_handler = fd_chr_update_read_handler;
2009 86e94dea ths
2010 86e94dea ths
    qemu_chr_reset(chr);
2011 86e94dea ths
2012 82c643ff bellard
    return chr;
2013 82c643ff bellard
}
2014 82c643ff bellard
2015 52f61fde ths
static CharDriverState *qemu_chr_open_file_out(const char *file_out)
2016 f8d179e3 bellard
{
2017 f8d179e3 bellard
    int fd_out;
2018 f8d179e3 bellard
2019 aeb30be6 balrog
    TFR(fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
2020 f8d179e3 bellard
    if (fd_out < 0)
2021 f8d179e3 bellard
        return NULL;
2022 f8d179e3 bellard
    return qemu_chr_open_fd(-1, fd_out);
2023 f8d179e3 bellard
}
2024 f8d179e3 bellard
2025 52f61fde ths
static CharDriverState *qemu_chr_open_pipe(const char *filename)
2026 f8d179e3 bellard
{
2027 c26c1c4b ths
    int fd_in, fd_out;
2028 c26c1c4b ths
    char filename_in[256], filename_out[256];
2029 c26c1c4b ths
2030 c26c1c4b ths
    snprintf(filename_in, 256, "%s.in", filename);
2031 c26c1c4b ths
    snprintf(filename_out, 256, "%s.out", filename);
2032 aeb30be6 balrog
    TFR(fd_in = open(filename_in, O_RDWR | O_BINARY));
2033 aeb30be6 balrog
    TFR(fd_out = open(filename_out, O_RDWR | O_BINARY));
2034 c26c1c4b ths
    if (fd_in < 0 || fd_out < 0) {
2035 c26c1c4b ths
        if (fd_in >= 0)
2036 c26c1c4b ths
            close(fd_in);
2037 c26c1c4b ths
        if (fd_out >= 0)
2038 c26c1c4b ths
            close(fd_out);
2039 aeb30be6 balrog
        TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
2040 c26c1c4b ths
        if (fd_in < 0)
2041 c26c1c4b ths
            return NULL;
2042 c26c1c4b ths
    }
2043 c26c1c4b ths
    return qemu_chr_open_fd(fd_in, fd_out);
2044 f8d179e3 bellard
}
2045 f8d179e3 bellard
2046 f8d179e3 bellard
2047 82c643ff bellard
/* for STDIO, we handle the case where several clients use it
2048 82c643ff bellard
   (nographic mode) */
2049 82c643ff bellard
2050 aa0bc6b6 bellard
#define TERM_FIFO_MAX_SIZE 1
2051 aa0bc6b6 bellard
2052 aa0bc6b6 bellard
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
2053 1dce7c3c bellard
static int term_fifo_size;
2054 330d0414 bellard
2055 7c9d8e07 bellard
static int stdio_read_poll(void *opaque)
2056 82c643ff bellard
{
2057 20d8a3ed ths
    CharDriverState *chr = opaque;
2058 aa0bc6b6 bellard
2059 20d8a3ed ths
    /* try to flush the queue if needed */
2060 20d8a3ed ths
    if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
2061 20d8a3ed ths
        qemu_chr_read(chr, term_fifo, 1);
2062 20d8a3ed ths
        term_fifo_size = 0;
2063 aa0bc6b6 bellard
    }
2064 20d8a3ed ths
    /* see if we can absorb more chars */
2065 20d8a3ed ths
    if (term_fifo_size == 0)
2066 20d8a3ed ths
        return 1;
2067 20d8a3ed ths
    else
2068 20d8a3ed ths
        return 0;
2069 82c643ff bellard
}
2070 82c643ff bellard
2071 7c9d8e07 bellard
static void stdio_read(void *opaque)
2072 82c643ff bellard
{
2073 7c9d8e07 bellard
    int size;
2074 7c9d8e07 bellard
    uint8_t buf[1];
2075 20d8a3ed ths
    CharDriverState *chr = opaque;
2076 20d8a3ed ths
2077 7c9d8e07 bellard
    size = read(0, buf, 1);
2078 519945df pbrook
    if (size == 0) {
2079 519945df pbrook
        /* stdin has been closed. Remove it from the active list.  */
2080 519945df pbrook
        qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
2081 519945df pbrook
        return;
2082 519945df pbrook
    }
2083 20d8a3ed ths
    if (size > 0) {
2084 20d8a3ed ths
        if (qemu_chr_can_read(chr) > 0) {
2085 20d8a3ed ths
            qemu_chr_read(chr, buf, 1);
2086 20d8a3ed ths
        } else if (term_fifo_size == 0) {
2087 20d8a3ed ths
            term_fifo[term_fifo_size++] = buf[0];
2088 1dce7c3c bellard
        }
2089 1dce7c3c bellard
    }
2090 1dce7c3c bellard
}
2091 1dce7c3c bellard
2092 8d11df9e bellard
/* init terminal so that we can grab keys */
2093 8d11df9e bellard
static struct termios oldtty;
2094 8d11df9e bellard
static int old_fd0_flags;
2095 8d11df9e bellard
2096 8d11df9e bellard
static void term_exit(void)
2097 8d11df9e bellard
{
2098 8d11df9e bellard
    tcsetattr (0, TCSANOW, &oldtty);
2099 8d11df9e bellard
    fcntl(0, F_SETFL, old_fd0_flags);
2100 8d11df9e bellard
}
2101 8d11df9e bellard
2102 8d11df9e bellard
static void term_init(void)
2103 8d11df9e bellard
{
2104 8d11df9e bellard
    struct termios tty;
2105 8d11df9e bellard
2106 8d11df9e bellard
    tcgetattr (0, &tty);
2107 8d11df9e bellard
    oldtty = tty;
2108 8d11df9e bellard
    old_fd0_flags = fcntl(0, F_GETFL);
2109 8d11df9e bellard
2110 8d11df9e bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2111 8d11df9e bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2112 8d11df9e bellard
    tty.c_oflag |= OPOST;
2113 8d11df9e bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
2114 8d11df9e bellard
    /* if graphical mode, we allow Ctrl-C handling */
2115 8d11df9e bellard
    if (nographic)
2116 8d11df9e bellard
        tty.c_lflag &= ~ISIG;
2117 8d11df9e bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
2118 8d11df9e bellard
    tty.c_cflag |= CS8;
2119 8d11df9e bellard
    tty.c_cc[VMIN] = 1;
2120 8d11df9e bellard
    tty.c_cc[VTIME] = 0;
2121 8d11df9e bellard
    
2122 8d11df9e bellard
    tcsetattr (0, TCSANOW, &tty);
2123 8d11df9e bellard
2124 8d11df9e bellard
    atexit(term_exit);
2125 8d11df9e bellard
2126 8d11df9e bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
2127 8d11df9e bellard
}
2128 8d11df9e bellard
2129 52f61fde ths
static CharDriverState *qemu_chr_open_stdio(void)
2130 82c643ff bellard
{
2131 82c643ff bellard
    CharDriverState *chr;
2132 82c643ff bellard
2133 20d8a3ed ths
    if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
2134 20d8a3ed ths
        return NULL;
2135 20d8a3ed ths
    chr = qemu_chr_open_fd(0, 1);
2136 20d8a3ed ths
    qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
2137 20d8a3ed ths
    stdio_nb_clients++;
2138 20d8a3ed ths
    term_init();
2139 20d8a3ed ths
2140 82c643ff bellard
    return chr;
2141 82c643ff bellard
}
2142 82c643ff bellard
2143 aec62507 ths
#if defined(__linux__) || defined(__sun__)
2144 52f61fde ths
static CharDriverState *qemu_chr_open_pty(void)
2145 82c643ff bellard
{
2146 91fc2119 bellard
    struct termios tty;
2147 82c643ff bellard
    char slave_name[1024];
2148 82c643ff bellard
    int master_fd, slave_fd;
2149 82c643ff bellard
    
2150 aec62507 ths
#if defined(__linux__)
2151 82c643ff bellard
    /* Not satisfying */
2152 82c643ff bellard
    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
2153 82c643ff bellard
        return NULL;
2154 82c643ff bellard
    }
2155 aec62507 ths
#endif
2156 91fc2119 bellard
    
2157 91fc2119 bellard
    /* Disabling local echo and line-buffered output */
2158 91fc2119 bellard
    tcgetattr (master_fd, &tty);
2159 91fc2119 bellard
    tty.c_lflag &= ~(ECHO|ICANON|ISIG);
2160 91fc2119 bellard
    tty.c_cc[VMIN] = 1;
2161 91fc2119 bellard
    tty.c_cc[VTIME] = 0;
2162 91fc2119 bellard
    tcsetattr (master_fd, TCSAFLUSH, &tty);
2163 91fc2119 bellard
2164 82c643ff bellard
    fprintf(stderr, "char device redirected to %s\n", slave_name);
2165 82c643ff bellard
    return qemu_chr_open_fd(master_fd, master_fd);
2166 82c643ff bellard
}
2167 f8d179e3 bellard
2168 f8d179e3 bellard
static void tty_serial_init(int fd, int speed, 
2169 f8d179e3 bellard
                            int parity, int data_bits, int stop_bits)
2170 f8d179e3 bellard
{
2171 f8d179e3 bellard
    struct termios tty;
2172 f8d179e3 bellard
    speed_t spd;
2173 f8d179e3 bellard
2174 e57a8c0e bellard
#if 0
2175 e57a8c0e bellard
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n", 
2176 e57a8c0e bellard
           speed, parity, data_bits, stop_bits);
2177 e57a8c0e bellard
#endif
2178 e57a8c0e bellard
    tcgetattr (fd, &tty);
2179 f8d179e3 bellard
2180 f8d179e3 bellard
    switch(speed) {
2181 f8d179e3 bellard
    case 50:
2182 f8d179e3 bellard
        spd = B50;
2183 f8d179e3 bellard
        break;
2184 f8d179e3 bellard
    case 75:
2185 f8d179e3 bellard
        spd = B75;
2186 f8d179e3 bellard
        break;
2187 f8d179e3 bellard
    case 300:
2188 f8d179e3 bellard
        spd = B300;
2189 f8d179e3 bellard
        break;
2190 f8d179e3 bellard
    case 600:
2191 f8d179e3 bellard
        spd = B600;
2192 f8d179e3 bellard
        break;
2193 f8d179e3 bellard
    case 1200:
2194 f8d179e3 bellard
        spd = B1200;
2195 f8d179e3 bellard
        break;
2196 f8d179e3 bellard
    case 2400:
2197 f8d179e3 bellard
        spd = B2400;
2198 f8d179e3 bellard
        break;
2199 f8d179e3 bellard
    case 4800:
2200 f8d179e3 bellard
        spd = B4800;
2201 f8d179e3 bellard
        break;
2202 f8d179e3 bellard
    case 9600:
2203 f8d179e3 bellard
        spd = B9600;
2204 f8d179e3 bellard
        break;
2205 f8d179e3 bellard
    case 19200:
2206 f8d179e3 bellard
        spd = B19200;
2207 f8d179e3 bellard
        break;
2208 f8d179e3 bellard
    case 38400:
2209 f8d179e3 bellard
        spd = B38400;
2210 f8d179e3 bellard
        break;
2211 f8d179e3 bellard
    case 57600:
2212 f8d179e3 bellard
        spd = B57600;
2213 f8d179e3 bellard
        break;
2214 f8d179e3 bellard
    default:
2215 f8d179e3 bellard
    case 115200:
2216 f8d179e3 bellard
        spd = B115200;
2217 f8d179e3 bellard
        break;
2218 f8d179e3 bellard
    }
2219 f8d179e3 bellard
2220 f8d179e3 bellard
    cfsetispeed(&tty, spd);
2221 f8d179e3 bellard
    cfsetospeed(&tty, spd);
2222 f8d179e3 bellard
2223 f8d179e3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
2224 f8d179e3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
2225 f8d179e3 bellard
    tty.c_oflag |= OPOST;
2226 f8d179e3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
2227 094eed6c bellard
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
2228 f8d179e3 bellard
    switch(data_bits) {
2229 f8d179e3 bellard
    default:
2230 f8d179e3 bellard
    case 8:
2231 f8d179e3 bellard
        tty.c_cflag |= CS8;
2232 f8d179e3 bellard
        break;
2233 f8d179e3 bellard
    case 7:
2234 f8d179e3 bellard
        tty.c_cflag |= CS7;
2235 f8d179e3 bellard
        break;
2236 f8d179e3 bellard
    case 6:
2237 f8d179e3 bellard
        tty.c_cflag |= CS6;
2238 f8d179e3 bellard
        break;
2239 f8d179e3 bellard
    case 5:
2240 f8d179e3 bellard
        tty.c_cflag |= CS5;
2241 f8d179e3 bellard
        break;
2242 f8d179e3 bellard
    }
2243 f8d179e3 bellard
    switch(parity) {
2244 f8d179e3 bellard
    default:
2245 f8d179e3 bellard
    case 'N':
2246 f8d179e3 bellard
        break;
2247 f8d179e3 bellard
    case 'E':
2248 f8d179e3 bellard
        tty.c_cflag |= PARENB;
2249 f8d179e3 bellard
        break;
2250 f8d179e3 bellard
    case 'O':
2251 f8d179e3 bellard
        tty.c_cflag |= PARENB | PARODD;
2252 f8d179e3 bellard
        break;
2253 f8d179e3 bellard
    }
2254 094eed6c bellard
    if (stop_bits == 2)
2255 094eed6c bellard
        tty.c_cflag |= CSTOPB;
2256 f8d179e3 bellard
    
2257 f8d179e3 bellard
    tcsetattr (fd, TCSANOW, &tty);
2258 f8d179e3 bellard
}
2259 f8d179e3 bellard
2260 e57a8c0e bellard
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
2261 f8d179e3 bellard
{
2262 f8d179e3 bellard
    FDCharDriver *s = chr->opaque;
2263 e57a8c0e bellard
    
2264 e57a8c0e bellard
    switch(cmd) {
2265 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_PARAMS:
2266 e57a8c0e bellard
        {
2267 e57a8c0e bellard
            QEMUSerialSetParams *ssp = arg;
2268 e57a8c0e bellard
            tty_serial_init(s->fd_in, ssp->speed, ssp->parity, 
2269 e57a8c0e bellard
                            ssp->data_bits, ssp->stop_bits);
2270 e57a8c0e bellard
        }
2271 e57a8c0e bellard
        break;
2272 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_BREAK:
2273 e57a8c0e bellard
        {
2274 e57a8c0e bellard
            int enable = *(int *)arg;
2275 e57a8c0e bellard
            if (enable)
2276 e57a8c0e bellard
                tcsendbreak(s->fd_in, 1);
2277 e57a8c0e bellard
        }
2278 e57a8c0e bellard
        break;
2279 e57a8c0e bellard
    default:
2280 e57a8c0e bellard
        return -ENOTSUP;
2281 e57a8c0e bellard
    }
2282 e57a8c0e bellard
    return 0;
2283 f8d179e3 bellard
}
2284 f8d179e3 bellard
2285 52f61fde ths
static CharDriverState *qemu_chr_open_tty(const char *filename)
2286 f8d179e3 bellard
{
2287 f8d179e3 bellard
    CharDriverState *chr;
2288 f8d179e3 bellard
    int fd;
2289 f8d179e3 bellard
2290 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
2291 f8d179e3 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
2292 f8d179e3 bellard
    tty_serial_init(fd, 115200, 'N', 8, 1);
2293 f8d179e3 bellard
    chr = qemu_chr_open_fd(fd, fd);
2294 aeb30be6 balrog
    if (!chr) {
2295 aeb30be6 balrog
        close(fd);
2296 f8d179e3 bellard
        return NULL;
2297 aeb30be6 balrog
    }
2298 e57a8c0e bellard
    chr->chr_ioctl = tty_serial_ioctl;
2299 86e94dea ths
    qemu_chr_reset(chr);
2300 e57a8c0e bellard
    return chr;
2301 e57a8c0e bellard
}
2302 aec62507 ths
#else  /* ! __linux__ && ! __sun__ */
2303 aec62507 ths
static CharDriverState *qemu_chr_open_pty(void)
2304 aec62507 ths
{
2305 aec62507 ths
    return NULL;
2306 aec62507 ths
}
2307 aec62507 ths
#endif /* __linux__ || __sun__ */
2308 e57a8c0e bellard
2309 aec62507 ths
#if defined(__linux__)
2310 5867c88a ths
typedef struct {
2311 5867c88a ths
    int fd;
2312 5867c88a ths
    int mode;
2313 5867c88a ths
} ParallelCharDriver;
2314 5867c88a ths
2315 5867c88a ths
static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
2316 5867c88a ths
{
2317 5867c88a ths
    if (s->mode != mode) {
2318 5867c88a ths
        int m = mode;
2319 5867c88a ths
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
2320 5867c88a ths
            return 0;
2321 5867c88a ths
        s->mode = mode;
2322 5867c88a ths
    }
2323 5867c88a ths
    return 1;
2324 5867c88a ths
}
2325 5867c88a ths
2326 e57a8c0e bellard
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
2327 e57a8c0e bellard
{
2328 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2329 5867c88a ths
    int fd = drv->fd;
2330 e57a8c0e bellard
    uint8_t b;
2331 e57a8c0e bellard
2332 e57a8c0e bellard
    switch(cmd) {
2333 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_DATA:
2334 e57a8c0e bellard
        if (ioctl(fd, PPRDATA, &b) < 0)
2335 e57a8c0e bellard
            return -ENOTSUP;
2336 e57a8c0e bellard
        *(uint8_t *)arg = b;
2337 e57a8c0e bellard
        break;
2338 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_DATA:
2339 e57a8c0e bellard
        b = *(uint8_t *)arg;
2340 e57a8c0e bellard
        if (ioctl(fd, PPWDATA, &b) < 0)
2341 e57a8c0e bellard
            return -ENOTSUP;
2342 e57a8c0e bellard
        break;
2343 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_CONTROL:
2344 e57a8c0e bellard
        if (ioctl(fd, PPRCONTROL, &b) < 0)
2345 e57a8c0e bellard
            return -ENOTSUP;
2346 5867c88a ths
        /* Linux gives only the lowest bits, and no way to know data
2347 5867c88a ths
           direction! For better compatibility set the fixed upper
2348 5867c88a ths
           bits. */
2349 5867c88a ths
        *(uint8_t *)arg = b | 0xc0;
2350 e57a8c0e bellard
        break;
2351 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_CONTROL:
2352 e57a8c0e bellard
        b = *(uint8_t *)arg;
2353 e57a8c0e bellard
        if (ioctl(fd, PPWCONTROL, &b) < 0)
2354 e57a8c0e bellard
            return -ENOTSUP;
2355 e57a8c0e bellard
        break;
2356 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_STATUS:
2357 e57a8c0e bellard
        if (ioctl(fd, PPRSTATUS, &b) < 0)
2358 e57a8c0e bellard
            return -ENOTSUP;
2359 e57a8c0e bellard
        *(uint8_t *)arg = b;
2360 e57a8c0e bellard
        break;
2361 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ_ADDR:
2362 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2363 5867c88a ths
            struct ParallelIOArg *parg = arg;
2364 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2365 5867c88a ths
            if (n != parg->count) {
2366 5867c88a ths
                return -EIO;
2367 5867c88a ths
            }
2368 5867c88a ths
        }
2369 5867c88a ths
        break;
2370 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ:
2371 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2372 5867c88a ths
            struct ParallelIOArg *parg = arg;
2373 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
2374 5867c88a ths
            if (n != parg->count) {
2375 5867c88a ths
                return -EIO;
2376 5867c88a ths
            }
2377 5867c88a ths
        }
2378 5867c88a ths
        break;
2379 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
2380 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
2381 5867c88a ths
            struct ParallelIOArg *parg = arg;
2382 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2383 5867c88a ths
            if (n != parg->count) {
2384 5867c88a ths
                return -EIO;
2385 5867c88a ths
            }
2386 5867c88a ths
        }
2387 5867c88a ths
        break;
2388 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE:
2389 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
2390 5867c88a ths
            struct ParallelIOArg *parg = arg;
2391 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
2392 5867c88a ths
            if (n != parg->count) {
2393 5867c88a ths
                return -EIO;
2394 5867c88a ths
            }
2395 5867c88a ths
        }
2396 5867c88a ths
        break;
2397 e57a8c0e bellard
    default:
2398 e57a8c0e bellard
        return -ENOTSUP;
2399 e57a8c0e bellard
    }
2400 e57a8c0e bellard
    return 0;
2401 e57a8c0e bellard
}
2402 e57a8c0e bellard
2403 5867c88a ths
static void pp_close(CharDriverState *chr)
2404 5867c88a ths
{
2405 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2406 5867c88a ths
    int fd = drv->fd;
2407 5867c88a ths
2408 5867c88a ths
    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2409 5867c88a ths
    ioctl(fd, PPRELEASE);
2410 5867c88a ths
    close(fd);
2411 5867c88a ths
    qemu_free(drv);
2412 5867c88a ths
}
2413 5867c88a ths
2414 52f61fde ths
static CharDriverState *qemu_chr_open_pp(const char *filename)
2415 e57a8c0e bellard
{
2416 e57a8c0e bellard
    CharDriverState *chr;
2417 5867c88a ths
    ParallelCharDriver *drv;
2418 e57a8c0e bellard
    int fd;
2419 e57a8c0e bellard
2420 aeb30be6 balrog
    TFR(fd = open(filename, O_RDWR));
2421 e57a8c0e bellard
    if (fd < 0)
2422 e57a8c0e bellard
        return NULL;
2423 e57a8c0e bellard
2424 e57a8c0e bellard
    if (ioctl(fd, PPCLAIM) < 0) {
2425 e57a8c0e bellard
        close(fd);
2426 e57a8c0e bellard
        return NULL;
2427 e57a8c0e bellard
    }
2428 e57a8c0e bellard
2429 5867c88a ths
    drv = qemu_mallocz(sizeof(ParallelCharDriver));
2430 5867c88a ths
    if (!drv) {
2431 5867c88a ths
        close(fd);
2432 5867c88a ths
        return NULL;
2433 5867c88a ths
    }
2434 5867c88a ths
    drv->fd = fd;
2435 5867c88a ths
    drv->mode = IEEE1284_MODE_COMPAT;
2436 5867c88a ths
2437 e57a8c0e bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2438 e57a8c0e bellard
    if (!chr) {
2439 5867c88a ths
        qemu_free(drv);
2440 e57a8c0e bellard
        close(fd);
2441 e57a8c0e bellard
        return NULL;
2442 e57a8c0e bellard
    }
2443 e57a8c0e bellard
    chr->chr_write = null_chr_write;
2444 e57a8c0e bellard
    chr->chr_ioctl = pp_ioctl;
2445 5867c88a ths
    chr->chr_close = pp_close;
2446 5867c88a ths
    chr->opaque = drv;
2447 86e94dea ths
2448 86e94dea ths
    qemu_chr_reset(chr);
2449 86e94dea ths
2450 f8d179e3 bellard
    return chr;
2451 f8d179e3 bellard
}
2452 aec62507 ths
#endif /* __linux__ */
2453 f8d179e3 bellard
2454 aec62507 ths
#else /* _WIN32 */
2455 82c643ff bellard
2456 f331110f bellard
typedef struct {
2457 f331110f bellard
    int max_size;
2458 f331110f bellard
    HANDLE hcom, hrecv, hsend;
2459 f331110f bellard
    OVERLAPPED orecv, osend;
2460 f331110f bellard
    BOOL fpipe;
2461 f331110f bellard
    DWORD len;
2462 f331110f bellard
} WinCharState;
2463 f331110f bellard
2464 f331110f bellard
#define NSENDBUF 2048
2465 f331110f bellard
#define NRECVBUF 2048
2466 f331110f bellard
#define MAXCONNECT 1
2467 f331110f bellard
#define NTIMEOUT 5000
2468 f331110f bellard
2469 f331110f bellard
static int win_chr_poll(void *opaque);
2470 f331110f bellard
static int win_chr_pipe_poll(void *opaque);
2471 f331110f bellard
2472 087f4ae0 ths
static void win_chr_close(CharDriverState *chr)
2473 f331110f bellard
{
2474 087f4ae0 ths
    WinCharState *s = chr->opaque;
2475 087f4ae0 ths
2476 f331110f bellard
    if (s->hsend) {
2477 f331110f bellard
        CloseHandle(s->hsend);
2478 f331110f bellard
        s->hsend = NULL;
2479 f331110f bellard
    }
2480 f331110f bellard
    if (s->hrecv) {
2481 f331110f bellard
        CloseHandle(s->hrecv);
2482 f331110f bellard
        s->hrecv = NULL;
2483 f331110f bellard
    }
2484 f331110f bellard
    if (s->hcom) {
2485 f331110f bellard
        CloseHandle(s->hcom);
2486 f331110f bellard
        s->hcom = NULL;
2487 f331110f bellard
    }
2488 f331110f bellard
    if (s->fpipe)
2489 087f4ae0 ths
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
2490 f331110f bellard
    else
2491 087f4ae0 ths
        qemu_del_polling_cb(win_chr_poll, chr);
2492 f331110f bellard
}
2493 f331110f bellard
2494 087f4ae0 ths
static int win_chr_init(CharDriverState *chr, const char *filename)
2495 f331110f bellard
{
2496 f331110f bellard
    WinCharState *s = chr->opaque;
2497 f331110f bellard
    COMMCONFIG comcfg;
2498 f331110f bellard
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2499 f331110f bellard
    COMSTAT comstat;
2500 f331110f bellard
    DWORD size;
2501 f331110f bellard
    DWORD err;
2502 f331110f bellard
    
2503 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2504 f331110f bellard
    if (!s->hsend) {
2505 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2506 f331110f bellard
        goto fail;
2507 f331110f bellard
    }
2508 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2509 f331110f bellard
    if (!s->hrecv) {
2510 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2511 f331110f bellard
        goto fail;
2512 f331110f bellard
    }
2513 f331110f bellard
2514 f331110f bellard
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2515 f331110f bellard
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2516 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2517 f331110f bellard
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2518 f331110f bellard
        s->hcom = NULL;
2519 f331110f bellard
        goto fail;
2520 f331110f bellard
    }
2521 f331110f bellard
    
2522 f331110f bellard
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
2523 f331110f bellard
        fprintf(stderr, "Failed SetupComm\n");
2524 f331110f bellard
        goto fail;
2525 f331110f bellard
    }
2526 f331110f bellard
    
2527 f331110f bellard
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2528 f331110f bellard
    size = sizeof(COMMCONFIG);
2529 f331110f bellard
    GetDefaultCommConfig(filename, &comcfg, &size);
2530 f331110f bellard
    comcfg.dcb.DCBlength = sizeof(DCB);
2531 f331110f bellard
    CommConfigDialog(filename, NULL, &comcfg);
2532 f331110f bellard
2533 f331110f bellard
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
2534 f331110f bellard
        fprintf(stderr, "Failed SetCommState\n");
2535 f331110f bellard
        goto fail;
2536 f331110f bellard
    }
2537 f331110f bellard
2538 f331110f bellard
    if (!SetCommMask(s->hcom, EV_ERR)) {
2539 f331110f bellard
        fprintf(stderr, "Failed SetCommMask\n");
2540 f331110f bellard
        goto fail;
2541 f331110f bellard
    }
2542 f331110f bellard
2543 f331110f bellard
    cto.ReadIntervalTimeout = MAXDWORD;
2544 f331110f bellard
    if (!SetCommTimeouts(s->hcom, &cto)) {
2545 f331110f bellard
        fprintf(stderr, "Failed SetCommTimeouts\n");
2546 f331110f bellard
        goto fail;
2547 f331110f bellard
    }
2548 f331110f bellard
    
2549 f331110f bellard
    if (!ClearCommError(s->hcom, &err, &comstat)) {
2550 f331110f bellard
        fprintf(stderr, "Failed ClearCommError\n");
2551 f331110f bellard
        goto fail;
2552 f331110f bellard
    }
2553 087f4ae0 ths
    qemu_add_polling_cb(win_chr_poll, chr);
2554 f331110f bellard
    return 0;
2555 f331110f bellard
2556 f331110f bellard
 fail:
2557 087f4ae0 ths
    win_chr_close(chr);
2558 f331110f bellard
    return -1;
2559 f331110f bellard
}
2560 f331110f bellard
2561 f331110f bellard
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
2562 f331110f bellard
{
2563 f331110f bellard
    WinCharState *s = chr->opaque;
2564 f331110f bellard
    DWORD len, ret, size, err;
2565 f331110f bellard
2566 f331110f bellard
    len = len1;
2567 f331110f bellard
    ZeroMemory(&s->osend, sizeof(s->osend));
2568 f331110f bellard
    s->osend.hEvent = s->hsend;
2569 f331110f bellard
    while (len > 0) {
2570 f331110f bellard
        if (s->hsend)
2571 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2572 f331110f bellard
        else
2573 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
2574 f331110f bellard
        if (!ret) {
2575 f331110f bellard
            err = GetLastError();
2576 f331110f bellard
            if (err == ERROR_IO_PENDING) {
2577 f331110f bellard
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2578 f331110f bellard
                if (ret) {
2579 f331110f bellard
                    buf += size;
2580 f331110f bellard
                    len -= size;
2581 f331110f bellard
                } else {
2582 f331110f bellard
                    break;
2583 f331110f bellard
                }
2584 f331110f bellard
            } else {
2585 f331110f bellard
                break;
2586 f331110f bellard
            }
2587 f331110f bellard
        } else {
2588 f331110f bellard
            buf += size;
2589 f331110f bellard
            len -= size;
2590 f331110f bellard
        }
2591 f331110f bellard
    }
2592 f331110f bellard
    return len1 - len;
2593 f331110f bellard
}
2594 f331110f bellard
2595 087f4ae0 ths
static int win_chr_read_poll(CharDriverState *chr)
2596 f331110f bellard
{
2597 087f4ae0 ths
    WinCharState *s = chr->opaque;
2598 087f4ae0 ths
2599 087f4ae0 ths
    s->max_size = qemu_chr_can_read(chr);
2600 f331110f bellard
    return s->max_size;
2601 f331110f bellard
}
2602 e5b0bc44 pbrook
2603 087f4ae0 ths
static void win_chr_readfile(CharDriverState *chr)
2604 f331110f bellard
{
2605 087f4ae0 ths
    WinCharState *s = chr->opaque;
2606 f331110f bellard
    int ret, err;
2607 f331110f bellard
    uint8_t buf[1024];
2608 f331110f bellard
    DWORD size;
2609 f331110f bellard
    
2610 f331110f bellard
    ZeroMemory(&s->orecv, sizeof(s->orecv));
2611 f331110f bellard
    s->orecv.hEvent = s->hrecv;
2612 f331110f bellard
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2613 f331110f bellard
    if (!ret) {
2614 f331110f bellard
        err = GetLastError();
2615 f331110f bellard
        if (err == ERROR_IO_PENDING) {
2616 f331110f bellard
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2617 f331110f bellard
        }
2618 f331110f bellard
    }
2619 f331110f bellard
2620 f331110f bellard
    if (size > 0) {
2621 087f4ae0 ths
        qemu_chr_read(chr, buf, size);
2622 f331110f bellard
    }
2623 f331110f bellard
}
2624 f331110f bellard
2625 087f4ae0 ths
static void win_chr_read(CharDriverState *chr)
2626 f331110f bellard
{
2627 087f4ae0 ths
    WinCharState *s = chr->opaque;
2628 087f4ae0 ths
2629 f331110f bellard
    if (s->len > s->max_size)
2630 f331110f bellard
        s->len = s->max_size;
2631 f331110f bellard
    if (s->len == 0)
2632 f331110f bellard
        return;
2633 f331110f bellard
    
2634 087f4ae0 ths
    win_chr_readfile(chr);
2635 f331110f bellard
}
2636 f331110f bellard
2637 f331110f bellard
static int win_chr_poll(void *opaque)
2638 f331110f bellard
{
2639 087f4ae0 ths
    CharDriverState *chr = opaque;
2640 087f4ae0 ths
    WinCharState *s = chr->opaque;
2641 f331110f bellard
    COMSTAT status;
2642 f331110f bellard
    DWORD comerr;
2643 f331110f bellard
    
2644 f331110f bellard
    ClearCommError(s->hcom, &comerr, &status);
2645 f331110f bellard
    if (status.cbInQue > 0) {
2646 f331110f bellard
        s->len = status.cbInQue;
2647 087f4ae0 ths
        win_chr_read_poll(chr);
2648 087f4ae0 ths
        win_chr_read(chr);
2649 f331110f bellard
        return 1;
2650 f331110f bellard
    }
2651 f331110f bellard
    return 0;
2652 f331110f bellard
}
2653 f331110f bellard
2654 52f61fde ths
static CharDriverState *qemu_chr_open_win(const char *filename)
2655 f331110f bellard
{
2656 f331110f bellard
    CharDriverState *chr;
2657 f331110f bellard
    WinCharState *s;
2658 f331110f bellard
    
2659 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2660 f331110f bellard
    if (!chr)
2661 f331110f bellard
        return NULL;
2662 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2663 f331110f bellard
    if (!s) {
2664 f331110f bellard
        free(chr);
2665 f331110f bellard
        return NULL;
2666 f331110f bellard
    }
2667 f331110f bellard
    chr->opaque = s;
2668 f331110f bellard
    chr->chr_write = win_chr_write;
2669 f331110f bellard
    chr->chr_close = win_chr_close;
2670 f331110f bellard
2671 087f4ae0 ths
    if (win_chr_init(chr, filename) < 0) {
2672 f331110f bellard
        free(s);
2673 f331110f bellard
        free(chr);
2674 f331110f bellard
        return NULL;
2675 f331110f bellard
    }
2676 86e94dea ths
    qemu_chr_reset(chr);
2677 f331110f bellard
    return chr;
2678 f331110f bellard
}
2679 f331110f bellard
2680 f331110f bellard
static int win_chr_pipe_poll(void *opaque)
2681 f331110f bellard
{
2682 087f4ae0 ths
    CharDriverState *chr = opaque;
2683 087f4ae0 ths
    WinCharState *s = chr->opaque;
2684 f331110f bellard
    DWORD size;
2685 f331110f bellard
2686 f331110f bellard
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2687 f331110f bellard
    if (size > 0) {
2688 f331110f bellard
        s->len = size;
2689 087f4ae0 ths
        win_chr_read_poll(chr);
2690 087f4ae0 ths
        win_chr_read(chr);
2691 f331110f bellard
        return 1;
2692 f331110f bellard
    }
2693 f331110f bellard
    return 0;
2694 f331110f bellard
}
2695 f331110f bellard
2696 087f4ae0 ths
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
2697 f331110f bellard
{
2698 087f4ae0 ths
    WinCharState *s = chr->opaque;
2699 f331110f bellard
    OVERLAPPED ov;
2700 f331110f bellard
    int ret;
2701 f331110f bellard
    DWORD size;
2702 f331110f bellard
    char openname[256];
2703 f331110f bellard
    
2704 f331110f bellard
    s->fpipe = TRUE;
2705 f331110f bellard
2706 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2707 f331110f bellard
    if (!s->hsend) {
2708 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2709 f331110f bellard
        goto fail;
2710 f331110f bellard
    }
2711 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2712 f331110f bellard
    if (!s->hrecv) {
2713 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2714 f331110f bellard
        goto fail;
2715 f331110f bellard
    }
2716 f331110f bellard
    
2717 f331110f bellard
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
2718 f331110f bellard
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2719 f331110f bellard
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2720 f331110f bellard
                              PIPE_WAIT,
2721 f331110f bellard
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2722 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2723 f331110f bellard
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
2724 f331110f bellard
        s->hcom = NULL;
2725 f331110f bellard
        goto fail;
2726 f331110f bellard
    }
2727 f331110f bellard
2728 f331110f bellard
    ZeroMemory(&ov, sizeof(ov));
2729 f331110f bellard
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2730 f331110f bellard
    ret = ConnectNamedPipe(s->hcom, &ov);
2731 f331110f bellard
    if (ret) {
2732 f331110f bellard
        fprintf(stderr, "Failed ConnectNamedPipe\n");
2733 f331110f bellard
        goto fail;
2734 f331110f bellard
    }
2735 f331110f bellard
2736 f331110f bellard
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2737 f331110f bellard
    if (!ret) {
2738 f331110f bellard
        fprintf(stderr, "Failed GetOverlappedResult\n");
2739 f331110f bellard
        if (ov.hEvent) {
2740 f331110f bellard
            CloseHandle(ov.hEvent);
2741 f331110f bellard
            ov.hEvent = NULL;
2742 f331110f bellard
        }
2743 f331110f bellard
        goto fail;
2744 f331110f bellard
    }
2745 f331110f bellard
2746 f331110f bellard
    if (ov.hEvent) {
2747 f331110f bellard
        CloseHandle(ov.hEvent);
2748 f331110f bellard
        ov.hEvent = NULL;
2749 f331110f bellard
    }
2750 087f4ae0 ths
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
2751 f331110f bellard
    return 0;
2752 f331110f bellard
2753 f331110f bellard
 fail:
2754 087f4ae0 ths
    win_chr_close(chr);
2755 f331110f bellard
    return -1;
2756 f331110f bellard
}
2757 f331110f bellard
2758 f331110f bellard
2759 52f61fde ths
static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
2760 f331110f bellard
{
2761 f331110f bellard
    CharDriverState *chr;
2762 f331110f bellard
    WinCharState *s;
2763 f331110f bellard
2764 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2765 f331110f bellard
    if (!chr)
2766 f331110f bellard
        return NULL;
2767 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2768 f331110f bellard
    if (!s) {
2769 f331110f bellard
        free(chr);
2770 f331110f bellard
        return NULL;
2771 f331110f bellard
    }
2772 f331110f bellard
    chr->opaque = s;
2773 f331110f bellard
    chr->chr_write = win_chr_write;
2774 f331110f bellard
    chr->chr_close = win_chr_close;
2775 f331110f bellard
    
2776 087f4ae0 ths
    if (win_chr_pipe_init(chr, filename) < 0) {
2777 f331110f bellard
        free(s);
2778 f331110f bellard
        free(chr);
2779 f331110f bellard
        return NULL;
2780 f331110f bellard
    }
2781 86e94dea ths
    qemu_chr_reset(chr);
2782 f331110f bellard
    return chr;
2783 f331110f bellard
}
2784 f331110f bellard
2785 52f61fde ths
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
2786 f331110f bellard
{
2787 f331110f bellard
    CharDriverState *chr;
2788 f331110f bellard
    WinCharState *s;
2789 f331110f bellard
2790 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2791 f331110f bellard
    if (!chr)
2792 f331110f bellard
        return NULL;
2793 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2794 f331110f bellard
    if (!s) {
2795 f331110f bellard
        free(chr);
2796 f331110f bellard
        return NULL;
2797 f331110f bellard
    }
2798 f331110f bellard
    s->hcom = fd_out;
2799 f331110f bellard
    chr->opaque = s;
2800 f331110f bellard
    chr->chr_write = win_chr_write;
2801 86e94dea ths
    qemu_chr_reset(chr);
2802 f331110f bellard
    return chr;
2803 f331110f bellard
}
2804 72d46479 ths
2805 72d46479 ths
static CharDriverState *qemu_chr_open_win_con(const char *filename)
2806 72d46479 ths
{
2807 72d46479 ths
    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
2808 72d46479 ths
}
2809 72d46479 ths
2810 52f61fde ths
static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
2811 f331110f bellard
{
2812 f331110f bellard
    HANDLE fd_out;
2813 f331110f bellard
    
2814 f331110f bellard
    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
2815 f331110f bellard
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2816 f331110f bellard
    if (fd_out == INVALID_HANDLE_VALUE)
2817 f331110f bellard
        return NULL;
2818 f331110f bellard
2819 f331110f bellard
    return qemu_chr_open_win_file(fd_out);
2820 f331110f bellard
}
2821 aec62507 ths
#endif /* !_WIN32 */
2822 f331110f bellard
2823 0bab00f3 bellard
/***********************************************************/
2824 0bab00f3 bellard
/* UDP Net console */
2825 0bab00f3 bellard
2826 0bab00f3 bellard
typedef struct {
2827 0bab00f3 bellard
    int fd;
2828 0bab00f3 bellard
    struct sockaddr_in daddr;
2829 0bab00f3 bellard
    char buf[1024];
2830 0bab00f3 bellard
    int bufcnt;
2831 0bab00f3 bellard
    int bufptr;
2832 0bab00f3 bellard
    int max_size;
2833 0bab00f3 bellard
} NetCharDriver;
2834 0bab00f3 bellard
2835 0bab00f3 bellard
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2836 0bab00f3 bellard
{
2837 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2838 0bab00f3 bellard
2839 0bab00f3 bellard
    return sendto(s->fd, buf, len, 0,
2840 0bab00f3 bellard
                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
2841 0bab00f3 bellard
}
2842 0bab00f3 bellard
2843 0bab00f3 bellard
static int udp_chr_read_poll(void *opaque)
2844 0bab00f3 bellard
{
2845 0bab00f3 bellard
    CharDriverState *chr = opaque;
2846 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2847 0bab00f3 bellard
2848 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2849 0bab00f3 bellard
2850 0bab00f3 bellard
    /* If there were any stray characters in the queue process them
2851 0bab00f3 bellard
     * first
2852 0bab00f3 bellard
     */
2853 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2854 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2855 0bab00f3 bellard
        s->bufptr++;
2856 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2857 0bab00f3 bellard
    }
2858 0bab00f3 bellard
    return s->max_size;
2859 0bab00f3 bellard
}
2860 0bab00f3 bellard
2861 0bab00f3 bellard
static void udp_chr_read(void *opaque)
2862 0bab00f3 bellard
{
2863 0bab00f3 bellard
    CharDriverState *chr = opaque;
2864 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2865 0bab00f3 bellard
2866 0bab00f3 bellard
    if (s->max_size == 0)
2867 0bab00f3 bellard
        return;
2868 0bab00f3 bellard
    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
2869 0bab00f3 bellard
    s->bufptr = s->bufcnt;
2870 0bab00f3 bellard
    if (s->bufcnt <= 0)
2871 0bab00f3 bellard
        return;
2872 0bab00f3 bellard
2873 0bab00f3 bellard
    s->bufptr = 0;
2874 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2875 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2876 0bab00f3 bellard
        s->bufptr++;
2877 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2878 0bab00f3 bellard
    }
2879 0bab00f3 bellard
}
2880 0bab00f3 bellard
2881 e5b0bc44 pbrook
static void udp_chr_update_read_handler(CharDriverState *chr)
2882 0bab00f3 bellard
{
2883 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2884 0bab00f3 bellard
2885 0bab00f3 bellard
    if (s->fd >= 0) {
2886 0bab00f3 bellard
        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
2887 0bab00f3 bellard
                             udp_chr_read, NULL, chr);
2888 0bab00f3 bellard
    }
2889 0bab00f3 bellard
}
2890 0bab00f3 bellard
2891 0bab00f3 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str);
2892 52f61fde ths
#ifndef _WIN32
2893 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
2894 52f61fde ths
#endif
2895 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
2896 951f1351 bellard
                        struct sockaddr_in *saddr,
2897 951f1351 bellard
                        const char *str);
2898 0bab00f3 bellard
2899 52f61fde ths
static CharDriverState *qemu_chr_open_udp(const char *def)
2900 0bab00f3 bellard
{
2901 0bab00f3 bellard
    CharDriverState *chr = NULL;
2902 0bab00f3 bellard
    NetCharDriver *s = NULL;
2903 0bab00f3 bellard
    int fd = -1;
2904 951f1351 bellard
    struct sockaddr_in saddr;
2905 0bab00f3 bellard
2906 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2907 0bab00f3 bellard
    if (!chr)
2908 0bab00f3 bellard
        goto return_err;
2909 0bab00f3 bellard
    s = qemu_mallocz(sizeof(NetCharDriver));
2910 0bab00f3 bellard
    if (!s)
2911 0bab00f3 bellard
        goto return_err;
2912 0bab00f3 bellard
2913 0bab00f3 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
2914 0bab00f3 bellard
    if (fd < 0) {
2915 0bab00f3 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
2916 0bab00f3 bellard
        goto return_err;
2917 0bab00f3 bellard
    }
2918 0bab00f3 bellard
2919 951f1351 bellard
    if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
2920 951f1351 bellard
        printf("Could not parse: %s\n", def);
2921 951f1351 bellard
        goto return_err;
2922 0bab00f3 bellard
    }
2923 0bab00f3 bellard
2924 951f1351 bellard
    if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
2925 0bab00f3 bellard
    {
2926 0bab00f3 bellard
        perror("bind");
2927 0bab00f3 bellard
        goto return_err;
2928 0bab00f3 bellard
    }
2929 0bab00f3 bellard
2930 0bab00f3 bellard
    s->fd = fd;
2931 0bab00f3 bellard
    s->bufcnt = 0;
2932 0bab00f3 bellard
    s->bufptr = 0;
2933 0bab00f3 bellard
    chr->opaque = s;
2934 0bab00f3 bellard
    chr->chr_write = udp_chr_write;
2935 e5b0bc44 pbrook
    chr->chr_update_read_handler = udp_chr_update_read_handler;
2936 0bab00f3 bellard
    return chr;
2937 0bab00f3 bellard
2938 0bab00f3 bellard
return_err:
2939 0bab00f3 bellard
    if (chr)
2940 0bab00f3 bellard
        free(chr);
2941 0bab00f3 bellard
    if (s)
2942 0bab00f3 bellard
        free(s);
2943 0bab00f3 bellard
    if (fd >= 0)
2944 0bab00f3 bellard
        closesocket(fd);
2945 0bab00f3 bellard
    return NULL;
2946 0bab00f3 bellard
}
2947 0bab00f3 bellard
2948 0bab00f3 bellard
/***********************************************************/
2949 0bab00f3 bellard
/* TCP Net console */
2950 0bab00f3 bellard
2951 0bab00f3 bellard
typedef struct {
2952 0bab00f3 bellard
    int fd, listen_fd;
2953 0bab00f3 bellard
    int connected;
2954 0bab00f3 bellard
    int max_size;
2955 951f1351 bellard
    int do_telnetopt;
2956 e5b0bc44 pbrook
    int do_nodelay;
2957 ffd843bc ths
    int is_unix;
2958 0bab00f3 bellard
} TCPCharDriver;
2959 0bab00f3 bellard
2960 0bab00f3 bellard
static void tcp_chr_accept(void *opaque);
2961 0bab00f3 bellard
2962 0bab00f3 bellard
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2963 0bab00f3 bellard
{
2964 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2965 0bab00f3 bellard
    if (s->connected) {
2966 0bab00f3 bellard
        return send_all(s->fd, buf, len);
2967 0bab00f3 bellard
    } else {
2968 0bab00f3 bellard
        /* XXX: indicate an error ? */
2969 0bab00f3 bellard
        return len;
2970 0bab00f3 bellard
    }
2971 0bab00f3 bellard
}
2972 0bab00f3 bellard
2973 0bab00f3 bellard
static int tcp_chr_read_poll(void *opaque)
2974 0bab00f3 bellard
{
2975 0bab00f3 bellard
    CharDriverState *chr = opaque;
2976 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2977 0bab00f3 bellard
    if (!s->connected)
2978 0bab00f3 bellard
        return 0;
2979 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2980 0bab00f3 bellard
    return s->max_size;
2981 0bab00f3 bellard
}
2982 0bab00f3 bellard
2983 951f1351 bellard
#define IAC 255
2984 951f1351 bellard
#define IAC_BREAK 243
2985 951f1351 bellard
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2986 951f1351 bellard
                                      TCPCharDriver *s,
2987 951f1351 bellard
                                      char *buf, int *size)
2988 951f1351 bellard
{
2989 951f1351 bellard
    /* Handle any telnet client's basic IAC options to satisfy char by
2990 951f1351 bellard
     * char mode with no echo.  All IAC options will be removed from
2991 951f1351 bellard
     * the buf and the do_telnetopt variable will be used to track the
2992 951f1351 bellard
     * state of the width of the IAC information.
2993 951f1351 bellard
     *
2994 951f1351 bellard
     * IAC commands come in sets of 3 bytes with the exception of the
2995 951f1351 bellard
     * "IAC BREAK" command and the double IAC.
2996 951f1351 bellard
     */
2997 951f1351 bellard
2998 951f1351 bellard
    int i;
2999 951f1351 bellard
    int j = 0;
3000 951f1351 bellard
3001 951f1351 bellard
    for (i = 0; i < *size; i++) {
3002 951f1351 bellard
        if (s->do_telnetopt > 1) {
3003 951f1351 bellard
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
3004 951f1351 bellard
                /* Double IAC means send an IAC */
3005 951f1351 bellard
                if (j != i)
3006 951f1351 bellard
                    buf[j] = buf[i];
3007 951f1351 bellard
                j++;
3008 951f1351 bellard
                s->do_telnetopt = 1;
3009 951f1351 bellard
            } else {
3010 951f1351 bellard
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
3011 951f1351 bellard
                    /* Handle IAC break commands by sending a serial break */
3012 e5b0bc44 pbrook
                    qemu_chr_event(chr, CHR_EVENT_BREAK);
3013 951f1351 bellard
                    s->do_telnetopt++;
3014 951f1351 bellard
                }
3015 951f1351 bellard
                s->do_telnetopt++;
3016 951f1351 bellard
            }
3017 951f1351 bellard
            if (s->do_telnetopt >= 4) {
3018 951f1351 bellard
                s->do_telnetopt = 1;
3019 951f1351 bellard
            }
3020 951f1351 bellard
        } else {
3021 951f1351 bellard
            if ((unsigned char)buf[i] == IAC) {
3022 951f1351 bellard
                s->do_telnetopt = 2;
3023 951f1351 bellard
            } else {
3024 951f1351 bellard
                if (j != i)
3025 951f1351 bellard
                    buf[j] = buf[i];
3026 951f1351 bellard
                j++;
3027 951f1351 bellard
            }
3028 951f1351 bellard
        }
3029 951f1351 bellard
    }
3030 951f1351 bellard
    *size = j;
3031 951f1351 bellard
}
3032 951f1351 bellard
3033 0bab00f3 bellard
static void tcp_chr_read(void *opaque)
3034 0bab00f3 bellard
{
3035 0bab00f3 bellard
    CharDriverState *chr = opaque;
3036 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3037 0bab00f3 bellard
    uint8_t buf[1024];
3038 0bab00f3 bellard
    int len, size;
3039 0bab00f3 bellard
3040 0bab00f3 bellard
    if (!s->connected || s->max_size <= 0)
3041 0bab00f3 bellard
        return;
3042 0bab00f3 bellard
    len = sizeof(buf);
3043 0bab00f3 bellard
    if (len > s->max_size)
3044 0bab00f3 bellard
        len = s->max_size;
3045 0bab00f3 bellard
    size = recv(s->fd, buf, len, 0);
3046 0bab00f3 bellard
    if (size == 0) {
3047 0bab00f3 bellard
        /* connection closed */
3048 0bab00f3 bellard
        s->connected = 0;
3049 0bab00f3 bellard
        if (s->listen_fd >= 0) {
3050 0bab00f3 bellard
            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3051 0bab00f3 bellard
        }
3052 0bab00f3 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3053 0bab00f3 bellard
        closesocket(s->fd);
3054 0bab00f3 bellard
        s->fd = -1;
3055 0bab00f3 bellard
    } else if (size > 0) {
3056 951f1351 bellard
        if (s->do_telnetopt)
3057 951f1351 bellard
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
3058 951f1351 bellard
        if (size > 0)
3059 e5b0bc44 pbrook
            qemu_chr_read(chr, buf, size);
3060 0bab00f3 bellard
    }
3061 0bab00f3 bellard
}
3062 0bab00f3 bellard
3063 0bab00f3 bellard
static void tcp_chr_connect(void *opaque)
3064 0bab00f3 bellard
{
3065 0bab00f3 bellard
    CharDriverState *chr = opaque;
3066 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3067 0bab00f3 bellard
3068 0bab00f3 bellard
    s->connected = 1;
3069 0bab00f3 bellard
    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
3070 0bab00f3 bellard
                         tcp_chr_read, NULL, chr);
3071 86e94dea ths
    qemu_chr_reset(chr);
3072 0bab00f3 bellard
}
3073 0bab00f3 bellard
3074 951f1351 bellard
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
3075 951f1351 bellard
static void tcp_chr_telnet_init(int fd)
3076 951f1351 bellard
{
3077 951f1351 bellard
    char buf[3];
3078 951f1351 bellard
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
3079 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
3080 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3081 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
3082 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3083 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
3084 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3085 951f1351 bellard
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
3086 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
3087 951f1351 bellard
}
3088 951f1351 bellard
3089 f7499989 pbrook
static void socket_set_nodelay(int fd)
3090 f7499989 pbrook
{
3091 f7499989 pbrook
    int val = 1;
3092 f7499989 pbrook
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
3093 f7499989 pbrook
}
3094 f7499989 pbrook
3095 0bab00f3 bellard
static void tcp_chr_accept(void *opaque)
3096 0bab00f3 bellard
{
3097 0bab00f3 bellard
    CharDriverState *chr = opaque;
3098 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3099 0bab00f3 bellard
    struct sockaddr_in saddr;
3100 ffd843bc ths
#ifndef _WIN32
3101 ffd843bc ths
    struct sockaddr_un uaddr;
3102 ffd843bc ths
#endif
3103 ffd843bc ths
    struct sockaddr *addr;
3104 0bab00f3 bellard
    socklen_t len;
3105 0bab00f3 bellard
    int fd;
3106 0bab00f3 bellard
3107 0bab00f3 bellard
    for(;;) {
3108 ffd843bc ths
#ifndef _WIN32
3109 ffd843bc ths
        if (s->is_unix) {
3110 ffd843bc ths
            len = sizeof(uaddr);
3111 ffd843bc ths
            addr = (struct sockaddr *)&uaddr;
3112 ffd843bc ths
        } else
3113 ffd843bc ths
#endif
3114 ffd843bc ths
        {
3115 ffd843bc ths
            len = sizeof(saddr);
3116 ffd843bc ths
            addr = (struct sockaddr *)&saddr;
3117 ffd843bc ths
        }
3118 ffd843bc ths
        fd = accept(s->listen_fd, addr, &len);
3119 0bab00f3 bellard
        if (fd < 0 && errno != EINTR) {
3120 0bab00f3 bellard
            return;
3121 0bab00f3 bellard
        } else if (fd >= 0) {
3122 951f1351 bellard
            if (s->do_telnetopt)
3123 951f1351 bellard
                tcp_chr_telnet_init(fd);
3124 0bab00f3 bellard
            break;
3125 0bab00f3 bellard
        }
3126 0bab00f3 bellard
    }
3127 0bab00f3 bellard
    socket_set_nonblock(fd);
3128 f7499989 pbrook
    if (s->do_nodelay)
3129 f7499989 pbrook
        socket_set_nodelay(fd);
3130 0bab00f3 bellard
    s->fd = fd;
3131 0bab00f3 bellard
    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
3132 0bab00f3 bellard
    tcp_chr_connect(chr);
3133 0bab00f3 bellard
}
3134 0bab00f3 bellard
3135 0bab00f3 bellard
static void tcp_chr_close(CharDriverState *chr)
3136 0bab00f3 bellard
{
3137 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
3138 0bab00f3 bellard
    if (s->fd >= 0)
3139 0bab00f3 bellard
        closesocket(s->fd);
3140 0bab00f3 bellard
    if (s->listen_fd >= 0)
3141 0bab00f3 bellard
        closesocket(s->listen_fd);
3142 0bab00f3 bellard
    qemu_free(s);
3143 0bab00f3 bellard
}
3144 0bab00f3 bellard
3145 0bab00f3 bellard
static CharDriverState *qemu_chr_open_tcp(const char *host_str, 
3146 ffd843bc ths
                                          int is_telnet,
3147 ffd843bc ths
                                          int is_unix)
3148 0bab00f3 bellard
{
3149 0bab00f3 bellard
    CharDriverState *chr = NULL;
3150 0bab00f3 bellard
    TCPCharDriver *s = NULL;
3151 0bab00f3 bellard
    int fd = -1, ret, err, val;
3152 951f1351 bellard
    int is_listen = 0;
3153 951f1351 bellard
    int is_waitconnect = 1;
3154 f7499989 pbrook
    int do_nodelay = 0;
3155 951f1351 bellard
    const char *ptr;
3156 0bab00f3 bellard
    struct sockaddr_in saddr;
3157 ffd843bc ths
#ifndef _WIN32
3158 ffd843bc ths
    struct sockaddr_un uaddr;
3159 ffd843bc ths
#endif
3160 ffd843bc ths
    struct sockaddr *addr;
3161 ffd843bc ths
    socklen_t addrlen;
3162 0bab00f3 bellard
3163 ffd843bc ths
#ifndef _WIN32
3164 ffd843bc ths
    if (is_unix) {
3165 ffd843bc ths
        addr = (struct sockaddr *)&uaddr;
3166 ffd843bc ths
        addrlen = sizeof(uaddr);
3167 ffd843bc ths
        if (parse_unix_path(&uaddr, host_str) < 0)
3168 ffd843bc ths
            goto fail;
3169 ffd843bc ths
    } else
3170 ffd843bc ths
#endif
3171 ffd843bc ths
    {
3172 ffd843bc ths
        addr = (struct sockaddr *)&saddr;
3173 ffd843bc ths
        addrlen = sizeof(saddr);
3174 ffd843bc ths
        if (parse_host_port(&saddr, host_str) < 0)
3175 ffd843bc ths
            goto fail;
3176 ffd843bc ths
    }
3177 0bab00f3 bellard
3178 951f1351 bellard
    ptr = host_str;
3179 951f1351 bellard
    while((ptr = strchr(ptr,','))) {
3180 951f1351 bellard
        ptr++;
3181 951f1351 bellard
        if (!strncmp(ptr,"server",6)) {
3182 951f1351 bellard
            is_listen = 1;
3183 951f1351 bellard
        } else if (!strncmp(ptr,"nowait",6)) {
3184 951f1351 bellard
            is_waitconnect = 0;
3185 f7499989 pbrook
        } else if (!strncmp(ptr,"nodelay",6)) {
3186 f7499989 pbrook
            do_nodelay = 1;
3187 951f1351 bellard
        } else {
3188 951f1351 bellard
            printf("Unknown option: %s\n", ptr);
3189 951f1351 bellard
            goto fail;
3190 951f1351 bellard
        }
3191 951f1351 bellard
    }
3192 951f1351 bellard
    if (!is_listen)
3193 951f1351 bellard
        is_waitconnect = 0;
3194 951f1351 bellard
3195 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
3196 0bab00f3 bellard
    if (!chr)
3197 0bab00f3 bellard
        goto fail;
3198 0bab00f3 bellard
    s = qemu_mallocz(sizeof(TCPCharDriver));
3199 0bab00f3 bellard
    if (!s)
3200 0bab00f3 bellard
        goto fail;
3201 ffd843bc ths
3202 ffd843bc ths
#ifndef _WIN32
3203 ffd843bc ths
    if (is_unix)
3204 ffd843bc ths
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
3205 ffd843bc ths
    else
3206 ffd843bc ths
#endif
3207 ffd843bc ths
        fd = socket(PF_INET, SOCK_STREAM, 0);
3208 ffd843bc ths
        
3209 0bab00f3 bellard
    if (fd < 0) 
3210 0bab00f3 bellard
        goto fail;
3211 951f1351 bellard
3212 951f1351 bellard
    if (!is_waitconnect)
3213 951f1351 bellard
        socket_set_nonblock(fd);
3214 0bab00f3 bellard
3215 0bab00f3 bellard
    s->connected = 0;
3216 0bab00f3 bellard
    s->fd = -1;
3217 0bab00f3 bellard
    s->listen_fd = -1;
3218 ffd843bc ths
    s->is_unix = is_unix;
3219 f7499989 pbrook
    s->do_nodelay = do_nodelay && !is_unix;
3220 ffd843bc ths
3221 ffd843bc ths
    chr->opaque = s;
3222 ffd843bc ths
    chr->chr_write = tcp_chr_write;
3223 ffd843bc ths
    chr->chr_close = tcp_chr_close;
3224 ffd843bc ths
3225 0bab00f3 bellard
    if (is_listen) {
3226 0bab00f3 bellard
        /* allow fast reuse */
3227 ffd843bc ths
#ifndef _WIN32
3228 ffd843bc ths
        if (is_unix) {
3229 ffd843bc ths
            char path[109];
3230 ffd843bc ths
            strncpy(path, uaddr.sun_path, 108);
3231 ffd843bc ths
            path[108] = 0;
3232 ffd843bc ths
            unlink(path);
3233 ffd843bc ths
        } else
3234 ffd843bc ths
#endif
3235 ffd843bc ths
        {
3236 ffd843bc ths
            val = 1;
3237 ffd843bc ths
            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3238 ffd843bc ths
        }
3239 0bab00f3 bellard
        
3240 ffd843bc ths
        ret = bind(fd, addr, addrlen);
3241 ffd843bc ths
        if (ret < 0)
3242 0bab00f3 bellard
            goto fail;
3243 ffd843bc ths
3244 0bab00f3 bellard
        ret = listen(fd, 0);
3245 0bab00f3 bellard
        if (ret < 0)
3246 0bab00f3 bellard
            goto fail;
3247 ffd843bc ths
3248 0bab00f3 bellard
        s->listen_fd = fd;
3249 0bab00f3 bellard
        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
3250 951f1351 bellard
        if (is_telnet)
3251 951f1351 bellard
            s->do_telnetopt = 1;
3252 0bab00f3 bellard
    } else {
3253 0bab00f3 bellard
        for(;;) {
3254 ffd843bc ths
            ret = connect(fd, addr, addrlen);
3255 0bab00f3 bellard
            if (ret < 0) {
3256 0bab00f3 bellard
                err = socket_error();
3257 0bab00f3 bellard
                if (err == EINTR || err == EWOULDBLOCK) {
3258 0bab00f3 bellard
                } else if (err == EINPROGRESS) {
3259 0bab00f3 bellard
                    break;
3260 f5b12268 ths
#ifdef _WIN32
3261 f5b12268 ths
                } else if (err == WSAEALREADY) {
3262 f5b12268 ths
                    break;
3263 f5b12268 ths
#endif
3264 0bab00f3 bellard
                } else {
3265 0bab00f3 bellard
                    goto fail;
3266 0bab00f3 bellard
                }
3267 0bab00f3 bellard
            } else {
3268 0bab00f3 bellard
                s->connected = 1;
3269 0bab00f3 bellard
                break;
3270 0bab00f3 bellard
            }
3271 0bab00f3 bellard
        }
3272 0bab00f3 bellard
        s->fd = fd;
3273 f7499989 pbrook
        socket_set_nodelay(fd);
3274 0bab00f3 bellard
        if (s->connected)
3275 0bab00f3 bellard
            tcp_chr_connect(chr);
3276 0bab00f3 bellard
        else
3277 0bab00f3 bellard
            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
3278 0bab00f3 bellard
    }
3279 0bab00f3 bellard
    
3280 951f1351 bellard
    if (is_listen && is_waitconnect) {
3281 951f1351 bellard
        printf("QEMU waiting for connection on: %s\n", host_str);
3282 951f1351 bellard
        tcp_chr_accept(chr);
3283 951f1351 bellard
        socket_set_nonblock(s->listen_fd);
3284 951f1351 bellard
    }
3285 951f1351 bellard
3286 0bab00f3 bellard
    return chr;
3287 0bab00f3 bellard
 fail:
3288 0bab00f3 bellard
    if (fd >= 0)
3289 0bab00f3 bellard
        closesocket(fd);
3290 0bab00f3 bellard
    qemu_free(s);
3291 0bab00f3 bellard
    qemu_free(chr);
3292 0bab00f3 bellard
    return NULL;
3293 0bab00f3 bellard
}
3294 0bab00f3 bellard
3295 82c643ff bellard
CharDriverState *qemu_chr_open(const char *filename)
3296 82c643ff bellard
{
3297 f8d179e3 bellard
    const char *p;
3298 fd1dff4b bellard
3299 82c643ff bellard
    if (!strcmp(filename, "vc")) {
3300 af3a9031 ths
        return text_console_init(&display_state, 0);
3301 af3a9031 ths
    } else if (strstart(filename, "vc:", &p)) {
3302 af3a9031 ths
        return text_console_init(&display_state, p);
3303 82c643ff bellard
    } else if (!strcmp(filename, "null")) {
3304 82c643ff bellard
        return qemu_chr_open_null();
3305 7664728b bellard
    } else 
3306 0bab00f3 bellard
    if (strstart(filename, "tcp:", &p)) {
3307 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 0);
3308 0bab00f3 bellard
    } else
3309 951f1351 bellard
    if (strstart(filename, "telnet:", &p)) {
3310 ffd843bc ths
        return qemu_chr_open_tcp(p, 1, 0);
3311 0bab00f3 bellard
    } else
3312 0bab00f3 bellard
    if (strstart(filename, "udp:", &p)) {
3313 0bab00f3 bellard
        return qemu_chr_open_udp(p);
3314 0bab00f3 bellard
    } else
3315 20d8a3ed ths
    if (strstart(filename, "mon:", &p)) {
3316 20d8a3ed ths
        CharDriverState *drv = qemu_chr_open(p);
3317 20d8a3ed ths
        if (drv) {
3318 20d8a3ed ths
            drv = qemu_chr_open_mux(drv);
3319 20d8a3ed ths
            monitor_init(drv, !nographic);
3320 20d8a3ed ths
            return drv;
3321 20d8a3ed ths
        }
3322 20d8a3ed ths
        printf("Unable to open driver: %s\n", p);
3323 20d8a3ed ths
        return 0;
3324 20d8a3ed ths
    } else
3325 7664728b bellard
#ifndef _WIN32
3326 ffd843bc ths
    if (strstart(filename, "unix:", &p)) {
3327 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 1);
3328 ffd843bc ths
    } else if (strstart(filename, "file:", &p)) {
3329 f8d179e3 bellard
        return qemu_chr_open_file_out(p);
3330 f8d179e3 bellard
    } else if (strstart(filename, "pipe:", &p)) {
3331 f8d179e3 bellard
        return qemu_chr_open_pipe(p);
3332 7664728b bellard
    } else if (!strcmp(filename, "pty")) {
3333 82c643ff bellard
        return qemu_chr_open_pty();
3334 82c643ff bellard
    } else if (!strcmp(filename, "stdio")) {
3335 82c643ff bellard
        return qemu_chr_open_stdio();
3336 82c643ff bellard
    } else 
3337 f8d179e3 bellard
#if defined(__linux__)
3338 e57a8c0e bellard
    if (strstart(filename, "/dev/parport", NULL)) {
3339 e57a8c0e bellard
        return qemu_chr_open_pp(filename);
3340 e57a8c0e bellard
    } else 
3341 aec62507 ths
#endif
3342 3fda388a ths
#if defined(__linux__) || defined(__sun__)
3343 f8d179e3 bellard
    if (strstart(filename, "/dev/", NULL)) {
3344 f8d179e3 bellard
        return qemu_chr_open_tty(filename);
3345 3fda388a ths
    } else
3346 3fda388a ths
#endif
3347 aec62507 ths
#else /* !_WIN32 */
3348 f331110f bellard
    if (strstart(filename, "COM", NULL)) {
3349 f331110f bellard
        return qemu_chr_open_win(filename);
3350 f331110f bellard
    } else
3351 f331110f bellard
    if (strstart(filename, "pipe:", &p)) {
3352 f331110f bellard
        return qemu_chr_open_win_pipe(p);
3353 f331110f bellard
    } else
3354 72d46479 ths
    if (strstart(filename, "con:", NULL)) {
3355 72d46479 ths
        return qemu_chr_open_win_con(filename);
3356 72d46479 ths
    } else
3357 f331110f bellard
    if (strstart(filename, "file:", &p)) {
3358 f331110f bellard
        return qemu_chr_open_win_file_out(p);
3359 f331110f bellard
    }
3360 f331110f bellard
#endif
3361 82c643ff bellard
    {
3362 82c643ff bellard
        return NULL;
3363 82c643ff bellard
    }
3364 82c643ff bellard
}
3365 82c643ff bellard
3366 f331110f bellard
void qemu_chr_close(CharDriverState *chr)
3367 f331110f bellard
{
3368 f331110f bellard
    if (chr->chr_close)
3369 f331110f bellard
        chr->chr_close(chr);
3370 f331110f bellard
}
3371 f331110f bellard
3372 80cabfad bellard
/***********************************************************/
3373 7c9d8e07 bellard
/* network device redirectors */
3374 330d0414 bellard
3375 c20709aa bellard
void hex_dump(FILE *f, const uint8_t *buf, int size)
3376 c20709aa bellard
{
3377 c20709aa bellard
    int len, i, j, c;
3378 c20709aa bellard
3379 c20709aa bellard
    for(i=0;i<size;i+=16) {
3380 c20709aa bellard
        len = size - i;
3381 c20709aa bellard
        if (len > 16)
3382 c20709aa bellard
            len = 16;
3383 c20709aa bellard
        fprintf(f, "%08x ", i);
3384 c20709aa bellard
        for(j=0;j<16;j++) {
3385 c20709aa bellard
            if (j < len)
3386 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
3387 c20709aa bellard
            else
3388 c20709aa bellard
                fprintf(f, "   ");
3389 c20709aa bellard
        }
3390 c20709aa bellard
        fprintf(f, " ");
3391 c20709aa bellard
        for(j=0;j<len;j++) {
3392 c20709aa bellard
            c = buf[i+j];
3393 c20709aa bellard
            if (c < ' ' || c > '~')
3394 c20709aa bellard
                c = '.';
3395 c20709aa bellard
            fprintf(f, "%c", c);
3396 c20709aa bellard
        }
3397 c20709aa bellard
        fprintf(f, "\n");
3398 c20709aa bellard
    }
3399 c20709aa bellard
}
3400 c20709aa bellard
3401 7c9d8e07 bellard
static int parse_macaddr(uint8_t *macaddr, const char *p)
3402 c20709aa bellard
{
3403 7c9d8e07 bellard
    int i;
3404 7c9d8e07 bellard
    for(i = 0; i < 6; i++) {
3405 7c9d8e07 bellard
        macaddr[i] = strtol(p, (char **)&p, 16);
3406 7c9d8e07 bellard
        if (i == 5) {
3407 7c9d8e07 bellard
            if (*p != '\0') 
3408 7c9d8e07 bellard
                return -1;
3409 7c9d8e07 bellard
        } else {
3410 7c9d8e07 bellard
            if (*p != ':') 
3411 7c9d8e07 bellard
                return -1;
3412 7c9d8e07 bellard
            p++;
3413 7c9d8e07 bellard
        }
3414 7c9d8e07 bellard
    }
3415 7c9d8e07 bellard
    return 0;
3416 c20709aa bellard
}
3417 67b915a5 bellard
3418 7c9d8e07 bellard
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3419 67b915a5 bellard
{
3420 7c9d8e07 bellard
    const char *p, *p1;
3421 7c9d8e07 bellard
    int len;
3422 7c9d8e07 bellard
    p = *pp;
3423 7c9d8e07 bellard
    p1 = strchr(p, sep);
3424 7c9d8e07 bellard
    if (!p1)
3425 7c9d8e07 bellard
        return -1;
3426 7c9d8e07 bellard
    len = p1 - p;
3427 7c9d8e07 bellard
    p1++;
3428 7c9d8e07 bellard
    if (buf_size > 0) {
3429 7c9d8e07 bellard
        if (len > buf_size - 1)
3430 7c9d8e07 bellard
            len = buf_size - 1;
3431 7c9d8e07 bellard
        memcpy(buf, p, len);
3432 7c9d8e07 bellard
        buf[len] = '\0';
3433 7c9d8e07 bellard
    }
3434 7c9d8e07 bellard
    *pp = p1;
3435 7c9d8e07 bellard
    return 0;
3436 c20709aa bellard
}
3437 c20709aa bellard
3438 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
3439 951f1351 bellard
                        struct sockaddr_in *saddr,
3440 951f1351 bellard
                        const char *input_str)
3441 951f1351 bellard
{
3442 951f1351 bellard
    char *str = strdup(input_str);
3443 951f1351 bellard
    char *host_str = str;
3444 951f1351 bellard
    char *src_str;
3445 951f1351 bellard
    char *ptr;
3446 951f1351 bellard
3447 951f1351 bellard
    /*
3448 951f1351 bellard
     * Chop off any extra arguments at the end of the string which
3449 951f1351 bellard
     * would start with a comma, then fill in the src port information
3450 951f1351 bellard
     * if it was provided else use the "any address" and "any port".
3451 951f1351 bellard
     */
3452 951f1351 bellard
    if ((ptr = strchr(str,',')))
3453 951f1351 bellard
        *ptr = '\0';
3454 951f1351 bellard
3455 951f1351 bellard
    if ((src_str = strchr(input_str,'@'))) {
3456 951f1351 bellard
        *src_str = '\0';
3457 951f1351 bellard
        src_str++;
3458 951f1351 bellard
    }
3459 951f1351 bellard
3460 951f1351 bellard
    if (parse_host_port(haddr, host_str) < 0)
3461 951f1351 bellard
        goto fail;
3462 951f1351 bellard
3463 951f1351 bellard
    if (!src_str || *src_str == '\0')
3464 951f1351 bellard
        src_str = ":0";
3465 951f1351 bellard
3466 951f1351 bellard
    if (parse_host_port(saddr, src_str) < 0)
3467 951f1351 bellard
        goto fail;
3468 951f1351 bellard
3469 951f1351 bellard
    free(str);
3470 951f1351 bellard
    return(0);
3471 951f1351 bellard
3472 951f1351 bellard
fail:
3473 951f1351 bellard
    free(str);
3474 951f1351 bellard
    return -1;
3475 951f1351 bellard
}
3476 951f1351 bellard
3477 7c9d8e07 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str)
3478 7c9d8e07 bellard
{
3479 7c9d8e07 bellard
    char buf[512];
3480 7c9d8e07 bellard
    struct hostent *he;
3481 7c9d8e07 bellard
    const char *p, *r;
3482 7c9d8e07 bellard
    int port;
3483 7c9d8e07 bellard
3484 7c9d8e07 bellard
    p = str;
3485 7c9d8e07 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3486 7c9d8e07 bellard
        return -1;
3487 7c9d8e07 bellard
    saddr->sin_family = AF_INET;
3488 7c9d8e07 bellard
    if (buf[0] == '\0') {
3489 7c9d8e07 bellard
        saddr->sin_addr.s_addr = 0;
3490 7c9d8e07 bellard
    } else {
3491 7c9d8e07 bellard
        if (isdigit(buf[0])) {
3492 7c9d8e07 bellard
            if (!inet_aton(buf, &saddr->sin_addr))
3493 7c9d8e07 bellard
                return -1;
3494 7c9d8e07 bellard
        } else {
3495 7c9d8e07 bellard
            if ((he = gethostbyname(buf)) == NULL)
3496 7c9d8e07 bellard
                return - 1;
3497 7c9d8e07 bellard
            saddr->sin_addr = *(struct in_addr *)he->h_addr;
3498 7c9d8e07 bellard
        }
3499 7c9d8e07 bellard
    }
3500 7c9d8e07 bellard
    port = strtol(p, (char **)&r, 0);
3501 7c9d8e07 bellard
    if (r == p)
3502 7c9d8e07 bellard
        return -1;
3503 7c9d8e07 bellard
    saddr->sin_port = htons(port);
3504 7c9d8e07 bellard
    return 0;
3505 7c9d8e07 bellard
}
3506 c20709aa bellard
3507 52f61fde ths
#ifndef _WIN32
3508 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
3509 ffd843bc ths
{
3510 ffd843bc ths
    const char *p;
3511 ffd843bc ths
    int len;
3512 ffd843bc ths
3513 ffd843bc ths
    len = MIN(108, strlen(str));
3514 ffd843bc ths
    p = strchr(str, ',');
3515 ffd843bc ths
    if (p)
3516 ffd843bc ths
        len = MIN(len, p - str);
3517 ffd843bc ths
3518 ffd843bc ths
    memset(uaddr, 0, sizeof(*uaddr));
3519 ffd843bc ths
3520 ffd843bc ths
    uaddr->sun_family = AF_UNIX;
3521 ffd843bc ths
    memcpy(uaddr->sun_path, str, len);
3522 ffd843bc ths
3523 ffd843bc ths
    return 0;
3524 ffd843bc ths
}
3525 52f61fde ths
#endif
3526 ffd843bc ths
3527 7c9d8e07 bellard
/* find or alloc a new VLAN */
3528 7c9d8e07 bellard
VLANState *qemu_find_vlan(int id)
3529 c20709aa bellard
{
3530 7c9d8e07 bellard
    VLANState **pvlan, *vlan;
3531 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3532 7c9d8e07 bellard
        if (vlan->id == id)
3533 7c9d8e07 bellard
            return vlan;
3534 7c9d8e07 bellard
    }
3535 7c9d8e07 bellard
    vlan = qemu_mallocz(sizeof(VLANState));
3536 7c9d8e07 bellard
    if (!vlan)
3537 7c9d8e07 bellard
        return NULL;
3538 7c9d8e07 bellard
    vlan->id = id;
3539 7c9d8e07 bellard
    vlan->next = NULL;
3540 7c9d8e07 bellard
    pvlan = &first_vlan;
3541 7c9d8e07 bellard
    while (*pvlan != NULL)
3542 7c9d8e07 bellard
        pvlan = &(*pvlan)->next;
3543 7c9d8e07 bellard
    *pvlan = vlan;
3544 7c9d8e07 bellard
    return vlan;
3545 c20709aa bellard
}
3546 c20709aa bellard
3547 7c9d8e07 bellard
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
3548 d861b05e pbrook
                                      IOReadHandler *fd_read,
3549 d861b05e pbrook
                                      IOCanRWHandler *fd_can_read,
3550 d861b05e pbrook
                                      void *opaque)
3551 c20709aa bellard
{
3552 7c9d8e07 bellard
    VLANClientState *vc, **pvc;
3553 7c9d8e07 bellard
    vc = qemu_mallocz(sizeof(VLANClientState));
3554 7c9d8e07 bellard
    if (!vc)
3555 7c9d8e07 bellard
        return NULL;
3556 7c9d8e07 bellard
    vc->fd_read = fd_read;
3557 d861b05e pbrook
    vc->fd_can_read = fd_can_read;
3558 7c9d8e07 bellard
    vc->opaque = opaque;
3559 7c9d8e07 bellard
    vc->vlan = vlan;
3560 7c9d8e07 bellard
3561 7c9d8e07 bellard
    vc->next = NULL;
3562 7c9d8e07 bellard
    pvc = &vlan->first_client;
3563 7c9d8e07 bellard
    while (*pvc != NULL)
3564 7c9d8e07 bellard
        pvc = &(*pvc)->next;
3565 7c9d8e07 bellard
    *pvc = vc;
3566 7c9d8e07 bellard
    return vc;
3567 c20709aa bellard
}
3568 c20709aa bellard
3569 d861b05e pbrook
int qemu_can_send_packet(VLANClientState *vc1)
3570 d861b05e pbrook
{
3571 d861b05e pbrook
    VLANState *vlan = vc1->vlan;
3572 d861b05e pbrook
    VLANClientState *vc;
3573 d861b05e pbrook
3574 d861b05e pbrook
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3575 d861b05e pbrook
        if (vc != vc1) {
3576 fbd1711d balrog
            if (vc->fd_can_read && vc->fd_can_read(vc->opaque))
3577 fbd1711d balrog
                return 1;
3578 d861b05e pbrook
        }
3579 d861b05e pbrook
    }
3580 fbd1711d balrog
    return 0;
3581 d861b05e pbrook
}
3582 d861b05e pbrook
3583 7c9d8e07 bellard
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
3584 c20709aa bellard
{
3585 7c9d8e07 bellard
    VLANState *vlan = vc1->vlan;
3586 7c9d8e07 bellard
    VLANClientState *vc;
3587 7c9d8e07 bellard
3588 7c9d8e07 bellard
#if 0
3589 7c9d8e07 bellard
    printf("vlan %d send:\n", vlan->id);
3590 7c9d8e07 bellard
    hex_dump(stdout, buf, size);
3591 7c9d8e07 bellard
#endif
3592 7c9d8e07 bellard
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3593 7c9d8e07 bellard
        if (vc != vc1) {
3594 7c9d8e07 bellard
            vc->fd_read(vc->opaque, buf, size);
3595 7c9d8e07 bellard
        }
3596 7c9d8e07 bellard
    }
3597 67b915a5 bellard
}
3598 67b915a5 bellard
3599 c20709aa bellard
#if defined(CONFIG_SLIRP)
3600 c20709aa bellard
3601 c20709aa bellard
/* slirp network adapter */
3602 c20709aa bellard
3603 c20709aa bellard
static int slirp_inited;
3604 7c9d8e07 bellard
static VLANClientState *slirp_vc;
3605 c20709aa bellard
3606 c20709aa bellard
int slirp_can_output(void)
3607 c20709aa bellard
{
3608 3b7f5d47 pbrook
    return !slirp_vc || qemu_can_send_packet(slirp_vc);
3609 c20709aa bellard
}
3610 c20709aa bellard
3611 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
3612 67b915a5 bellard
{
3613 c20709aa bellard
#if 0
3614 7c9d8e07 bellard
    printf("slirp output:\n");
3615 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
3616 c20709aa bellard
#endif
3617 3b7f5d47 pbrook
    if (!slirp_vc)
3618 3b7f5d47 pbrook
        return;
3619 7c9d8e07 bellard
    qemu_send_packet(slirp_vc, pkt, pkt_len);
3620 67b915a5 bellard
}
3621 67b915a5 bellard
3622 7c9d8e07 bellard
static void slirp_receive(void *opaque, const uint8_t *buf, int size)
3623 c20709aa bellard
{
3624 c20709aa bellard
#if 0
3625 7c9d8e07 bellard
    printf("slirp input:\n");
3626 c20709aa bellard
    hex_dump(stdout, buf, size);
3627 c20709aa bellard
#endif
3628 c20709aa bellard
    slirp_input(buf, size);
3629 c20709aa bellard
}
3630 c20709aa bellard
3631 7c9d8e07 bellard
static int net_slirp_init(VLANState *vlan)
3632 c20709aa bellard
{
3633 c20709aa bellard
    if (!slirp_inited) {
3634 c20709aa bellard
        slirp_inited = 1;
3635 c20709aa bellard
        slirp_init();
3636 c20709aa bellard
    }
3637 7c9d8e07 bellard
    slirp_vc = qemu_new_vlan_client(vlan, 
3638 d861b05e pbrook
                                    slirp_receive, NULL, NULL);
3639 7c9d8e07 bellard
    snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
3640 9bf05444 bellard
    return 0;
3641 9bf05444 bellard
}
3642 9bf05444 bellard
3643 9bf05444 bellard
static void net_slirp_redir(const char *redir_str)
3644 9bf05444 bellard
{
3645 9bf05444 bellard
    int is_udp;
3646 9bf05444 bellard
    char buf[256], *r;
3647 9bf05444 bellard
    const char *p;
3648 9bf05444 bellard
    struct in_addr guest_addr;
3649 9bf05444 bellard
    int host_port, guest_port;
3650 9bf05444 bellard
    
3651 9bf05444 bellard
    if (!slirp_inited) {
3652 9bf05444 bellard
        slirp_inited = 1;
3653 9bf05444 bellard
        slirp_init();
3654 9bf05444 bellard
    }
3655 9bf05444 bellard
3656 9bf05444 bellard
    p = redir_str;
3657 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3658 9bf05444 bellard
        goto fail;
3659 9bf05444 bellard
    if (!strcmp(buf, "tcp")) {
3660 9bf05444 bellard
        is_udp = 0;
3661 9bf05444 bellard
    } else if (!strcmp(buf, "udp")) {
3662 9bf05444 bellard
        is_udp = 1;
3663 9bf05444 bellard
    } else {
3664 9bf05444 bellard
        goto fail;
3665 9bf05444 bellard
    }
3666 9bf05444 bellard
3667 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3668 9bf05444 bellard
        goto fail;
3669 9bf05444 bellard
    host_port = strtol(buf, &r, 0);
3670 9bf05444 bellard
    if (r == buf)
3671 9bf05444 bellard
        goto fail;
3672 9bf05444 bellard
3673 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3674 9bf05444 bellard
        goto fail;
3675 9bf05444 bellard
    if (buf[0] == '\0') {
3676 9bf05444 bellard
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
3677 9bf05444 bellard
    }
3678 9bf05444 bellard
    if (!inet_aton(buf, &guest_addr))
3679 9bf05444 bellard
        goto fail;
3680 9bf05444 bellard
    
3681 9bf05444 bellard
    guest_port = strtol(p, &r, 0);
3682 9bf05444 bellard
    if (r == p)
3683 9bf05444 bellard
        goto fail;
3684 9bf05444 bellard
    
3685 9bf05444 bellard
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
3686 9bf05444 bellard
        fprintf(stderr, "qemu: could not set up redirection\n");
3687 9bf05444 bellard
        exit(1);
3688 9bf05444 bellard
    }
3689 9bf05444 bellard
    return;
3690 9bf05444 bellard
 fail:
3691 9bf05444 bellard
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
3692 9bf05444 bellard
    exit(1);
3693 9bf05444 bellard
}
3694 9d728e8c bellard
    
3695 c94c8d64 bellard
#ifndef _WIN32
3696 c94c8d64 bellard
3697 9d728e8c bellard
char smb_dir[1024];
3698 9d728e8c bellard
3699 9d728e8c bellard
static void smb_exit(void)
3700 9d728e8c bellard
{
3701 9d728e8c bellard
    DIR *d;
3702 9d728e8c bellard
    struct dirent *de;
3703 9d728e8c bellard
    char filename[1024];
3704 9d728e8c bellard
3705 9d728e8c bellard
    /* erase all the files in the directory */
3706 9d728e8c bellard
    d = opendir(smb_dir);
3707 9d728e8c bellard
    for(;;) {
3708 9d728e8c bellard
        de = readdir(d);
3709 9d728e8c bellard
        if (!de)
3710 9d728e8c bellard
            break;
3711 9d728e8c bellard
        if (strcmp(de->d_name, ".") != 0 &&
3712 9d728e8c bellard
            strcmp(de->d_name, "..") != 0) {
3713 9d728e8c bellard
            snprintf(filename, sizeof(filename), "%s/%s", 
3714 9d728e8c bellard
                     smb_dir, de->d_name);
3715 9d728e8c bellard
            unlink(filename);
3716 9d728e8c bellard
        }
3717 9d728e8c bellard
    }
3718 03ffbb69 bellard
    closedir(d);
3719 9d728e8c bellard
    rmdir(smb_dir);
3720 9d728e8c bellard
}
3721 9d728e8c bellard
3722 9d728e8c bellard
/* automatic user mode samba server configuration */
3723 9d728e8c bellard
void net_slirp_smb(const char *exported_dir)
3724 9d728e8c bellard
{
3725 9d728e8c bellard
    char smb_conf[1024];
3726 9d728e8c bellard
    char smb_cmdline[1024];
3727 9d728e8c bellard
    FILE *f;
3728 9d728e8c bellard
3729 9d728e8c bellard
    if (!slirp_inited) {
3730 9d728e8c bellard
        slirp_inited = 1;
3731 9d728e8c bellard
        slirp_init();
3732 9d728e8c bellard
    }
3733 9d728e8c bellard
3734 9d728e8c bellard
    /* XXX: better tmp dir construction */
3735 9d728e8c bellard
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
3736 9d728e8c bellard
    if (mkdir(smb_dir, 0700) < 0) {
3737 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
3738 9d728e8c bellard
        exit(1);
3739 9d728e8c bellard
    }
3740 9d728e8c bellard
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
3741 9d728e8c bellard
    
3742 9d728e8c bellard
    f = fopen(smb_conf, "w");
3743 9d728e8c bellard
    if (!f) {
3744 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
3745 9d728e8c bellard
        exit(1);
3746 9d728e8c bellard
    }
3747 9d728e8c bellard
    fprintf(f, 
3748 9d728e8c bellard
            "[global]\n"
3749 157777ef bellard
            "private dir=%s\n"
3750 157777ef bellard
            "smb ports=0\n"
3751 157777ef bellard
            "socket address=127.0.0.1\n"
3752 9d728e8c bellard
            "pid directory=%s\n"
3753 9d728e8c bellard
            "lock directory=%s\n"
3754 9d728e8c bellard
            "log file=%s/log.smbd\n"
3755 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
3756 03ffbb69 bellard
            "security = share\n"
3757 9d728e8c bellard
            "[qemu]\n"
3758 9d728e8c bellard
            "path=%s\n"
3759 9d728e8c bellard
            "read only=no\n"
3760 9d728e8c bellard
            "guest ok=yes\n",
3761 9d728e8c bellard
            smb_dir,
3762 157777ef bellard
            smb_dir,
3763 9d728e8c bellard
            smb_dir,
3764 9d728e8c bellard
            smb_dir,
3765 9d728e8c bellard
            smb_dir,
3766 9d728e8c bellard
            exported_dir
3767 9d728e8c bellard
            );
3768 9d728e8c bellard
    fclose(f);
3769 9d728e8c bellard
    atexit(smb_exit);
3770 9d728e8c bellard
3771 a14d6c8c pbrook
    snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
3772 a14d6c8c pbrook
             SMBD_COMMAND, smb_conf);
3773 9d728e8c bellard
    
3774 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
3775 9d728e8c bellard
}
3776 9bf05444 bellard
3777 c94c8d64 bellard
#endif /* !defined(_WIN32) */
3778 c94c8d64 bellard
3779 c20709aa bellard
#endif /* CONFIG_SLIRP */
3780 c20709aa bellard
3781 c20709aa bellard
#if !defined(_WIN32)
3782 7c9d8e07 bellard
3783 7c9d8e07 bellard
typedef struct TAPState {
3784 7c9d8e07 bellard
    VLANClientState *vc;
3785 7c9d8e07 bellard
    int fd;
3786 7c9d8e07 bellard
} TAPState;
3787 7c9d8e07 bellard
3788 7c9d8e07 bellard
static void tap_receive(void *opaque, const uint8_t *buf, int size)
3789 7c9d8e07 bellard
{
3790 7c9d8e07 bellard
    TAPState *s = opaque;
3791 7c9d8e07 bellard
    int ret;
3792 7c9d8e07 bellard
    for(;;) {
3793 7c9d8e07 bellard
        ret = write(s->fd, buf, size);
3794 7c9d8e07 bellard
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
3795 7c9d8e07 bellard
        } else {
3796 7c9d8e07 bellard
            break;
3797 7c9d8e07 bellard
        }
3798 7c9d8e07 bellard
    }
3799 7c9d8e07 bellard
}
3800 7c9d8e07 bellard
3801 7c9d8e07 bellard
static void tap_send(void *opaque)
3802 7c9d8e07 bellard
{
3803 7c9d8e07 bellard
    TAPState *s = opaque;
3804 7c9d8e07 bellard
    uint8_t buf[4096];
3805 7c9d8e07 bellard
    int size;
3806 7c9d8e07 bellard
3807 d5d10bc3 ths
#ifdef __sun__
3808 d5d10bc3 ths
    struct strbuf sbuf;
3809 d5d10bc3 ths
    int f = 0;
3810 d5d10bc3 ths
    sbuf.maxlen = sizeof(buf);
3811 d5d10bc3 ths
    sbuf.buf = buf;
3812 d5d10bc3 ths
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
3813 d5d10bc3 ths
#else
3814 7c9d8e07 bellard
    size = read(s->fd, buf, sizeof(buf));
3815 d5d10bc3 ths
#endif
3816 7c9d8e07 bellard
    if (size > 0) {
3817 7c9d8e07 bellard
        qemu_send_packet(s->vc, buf, size);
3818 7c9d8e07 bellard
    }
3819 7c9d8e07 bellard
}
3820 7c9d8e07 bellard
3821 7c9d8e07 bellard
/* fd support */
3822 7c9d8e07 bellard
3823 7c9d8e07 bellard
static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
3824 7c9d8e07 bellard
{
3825 7c9d8e07 bellard
    TAPState *s;
3826 7c9d8e07 bellard
3827 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(TAPState));
3828 7c9d8e07 bellard
    if (!s)
3829 7c9d8e07 bellard
        return NULL;
3830 7c9d8e07 bellard
    s->fd = fd;
3831 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
3832 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
3833 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
3834 7c9d8e07 bellard
    return s;
3835 7c9d8e07 bellard
}
3836 7c9d8e07 bellard
3837 5c40d2bd ths
#if defined (_BSD) || defined (__FreeBSD_kernel__)
3838 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3839 7d3505c5 bellard
{
3840 7d3505c5 bellard
    int fd;
3841 7d3505c5 bellard
    char *dev;
3842 7d3505c5 bellard
    struct stat s;
3843 67b915a5 bellard
3844 aeb30be6 balrog
    TFR(fd = open("/dev/tap", O_RDWR));
3845 7d3505c5 bellard
    if (fd < 0) {
3846 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
3847 7d3505c5 bellard
        return -1;
3848 7d3505c5 bellard
    }
3849 7d3505c5 bellard
3850 7d3505c5 bellard
    fstat(fd, &s);
3851 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
3852 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
3853 7d3505c5 bellard
3854 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
3855 7d3505c5 bellard
    return fd;
3856 7d3505c5 bellard
}
3857 ec530c81 bellard
#elif defined(__sun__)
3858 d5d10bc3 ths
#define TUNNEWPPA       (('T'<<16) | 0x0001)
3859 d5d10bc3 ths
/* 
3860 d5d10bc3 ths
 * Allocate TAP device, returns opened fd. 
3861 d5d10bc3 ths
 * Stores dev name in the first arg(must be large enough).
3862 d5d10bc3 ths
 */  
3863 d5d10bc3 ths
int tap_alloc(char *dev)
3864 d5d10bc3 ths
{
3865 d5d10bc3 ths
    int tap_fd, if_fd, ppa = -1;
3866 d5d10bc3 ths
    static int ip_fd = 0;
3867 d5d10bc3 ths
    char *ptr;
3868 d5d10bc3 ths
3869 d5d10bc3 ths
    static int arp_fd = 0;
3870 d5d10bc3 ths
    int ip_muxid, arp_muxid;
3871 d5d10bc3 ths
    struct strioctl  strioc_if, strioc_ppa;
3872 d5d10bc3 ths
    int link_type = I_PLINK;;
3873 d5d10bc3 ths
    struct lifreq ifr;
3874 d5d10bc3 ths
    char actual_name[32] = "";
3875 d5d10bc3 ths
3876 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3877 d5d10bc3 ths
3878 d5d10bc3 ths
    if( *dev ){
3879 d5d10bc3 ths
       ptr = dev;        
3880 d5d10bc3 ths
       while( *ptr && !isdigit((int)*ptr) ) ptr++; 
3881 d5d10bc3 ths
       ppa = atoi(ptr);
3882 d5d10bc3 ths
    }
3883 d5d10bc3 ths
3884 d5d10bc3 ths
    /* Check if IP device was opened */
3885 d5d10bc3 ths
    if( ip_fd )
3886 d5d10bc3 ths
       close(ip_fd);
3887 d5d10bc3 ths
3888 aeb30be6 balrog
    TFR(ip_fd = open("/dev/udp", O_RDWR, 0));
3889 aeb30be6 balrog
    if (ip_fd < 0) {
3890 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
3891 d5d10bc3 ths
       return -1;
3892 d5d10bc3 ths
    }
3893 d5d10bc3 ths
3894 aeb30be6 balrog
    TFR(tap_fd = open("/dev/tap", O_RDWR, 0));
3895 aeb30be6 balrog
    if (tap_fd < 0) {
3896 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap");
3897 d5d10bc3 ths
       return -1;
3898 d5d10bc3 ths
    }
3899 d5d10bc3 ths
3900 d5d10bc3 ths
    /* Assign a new PPA and get its unit number. */
3901 d5d10bc3 ths
    strioc_ppa.ic_cmd = TUNNEWPPA;
3902 d5d10bc3 ths
    strioc_ppa.ic_timout = 0;
3903 d5d10bc3 ths
    strioc_ppa.ic_len = sizeof(ppa);
3904 d5d10bc3 ths
    strioc_ppa.ic_dp = (char *)&ppa;
3905 d5d10bc3 ths
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
3906 d5d10bc3 ths
       syslog (LOG_ERR, "Can't assign new interface");
3907 d5d10bc3 ths
3908 aeb30be6 balrog
    TFR(if_fd = open("/dev/tap", O_RDWR, 0));
3909 aeb30be6 balrog
    if (if_fd < 0) {
3910 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
3911 d5d10bc3 ths
       return -1;
3912 d5d10bc3 ths
    }
3913 d5d10bc3 ths
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
3914 d5d10bc3 ths
       syslog(LOG_ERR, "Can't push IP module");
3915 d5d10bc3 ths
       return -1;
3916 d5d10bc3 ths
    }
3917 d5d10bc3 ths
3918 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
3919 d5d10bc3 ths
        syslog(LOG_ERR, "Can't get flags\n");
3920 d5d10bc3 ths
3921 d5d10bc3 ths
    snprintf (actual_name, 32, "tap%d", ppa);
3922 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3923 d5d10bc3 ths
3924 d5d10bc3 ths
    ifr.lifr_ppa = ppa;
3925 d5d10bc3 ths
    /* Assign ppa according to the unit number returned by tun device */
3926 d5d10bc3 ths
3927 d5d10bc3 ths
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
3928 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
3929 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
3930 d5d10bc3 ths
        syslog (LOG_ERR, "Can't get flags\n");
3931 d5d10bc3 ths
    /* Push arp module to if_fd */
3932 d5d10bc3 ths
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
3933 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (2)");
3934 d5d10bc3 ths
3935 d5d10bc3 ths
    /* Push arp module to ip_fd */
3936 d5d10bc3 ths
    if (ioctl (ip_fd, I_POP, NULL) < 0)
3937 d5d10bc3 ths
        syslog (LOG_ERR, "I_POP failed\n");
3938 d5d10bc3 ths
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
3939 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
3940 d5d10bc3 ths
    /* Open arp_fd */
3941 aeb30be6 balrog
    TFR(arp_fd = open ("/dev/tap", O_RDWR, 0));
3942 aeb30be6 balrog
    if (arp_fd < 0)
3943 d5d10bc3 ths
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
3944 d5d10bc3 ths
3945 d5d10bc3 ths
    /* Set ifname to arp */
3946 d5d10bc3 ths
    strioc_if.ic_cmd = SIOCSLIFNAME;
3947 d5d10bc3 ths
    strioc_if.ic_timout = 0;
3948 d5d10bc3 ths
    strioc_if.ic_len = sizeof(ifr);
3949 d5d10bc3 ths
    strioc_if.ic_dp = (char *)&ifr;
3950 d5d10bc3 ths
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
3951 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set ifname to arp\n");
3952 d5d10bc3 ths
    }
3953 d5d10bc3 ths
3954 d5d10bc3 ths
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
3955 d5d10bc3 ths
       syslog(LOG_ERR, "Can't link TAP device to IP");
3956 d5d10bc3 ths
       return -1;
3957 d5d10bc3 ths
    }
3958 d5d10bc3 ths
3959 d5d10bc3 ths
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
3960 d5d10bc3 ths
        syslog (LOG_ERR, "Can't link TAP device to ARP");
3961 d5d10bc3 ths
3962 d5d10bc3 ths
    close (if_fd);
3963 d5d10bc3 ths
3964 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3965 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3966 d5d10bc3 ths
    ifr.lifr_ip_muxid  = ip_muxid;
3967 d5d10bc3 ths
    ifr.lifr_arp_muxid = arp_muxid;
3968 d5d10bc3 ths
3969 d5d10bc3 ths
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
3970 d5d10bc3 ths
    {
3971 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
3972 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
3973 d5d10bc3 ths
      syslog (LOG_ERR, "Can't set multiplexor id");
3974 d5d10bc3 ths
    }
3975 d5d10bc3 ths
3976 d5d10bc3 ths
    sprintf(dev, "tap%d", ppa);
3977 d5d10bc3 ths
    return tap_fd;
3978 d5d10bc3 ths
}
3979 d5d10bc3 ths
3980 ec530c81 bellard
static int tap_open(char *ifname, int ifname_size)
3981 ec530c81 bellard
{
3982 d5d10bc3 ths
    char  dev[10]="";
3983 d5d10bc3 ths
    int fd;
3984 d5d10bc3 ths
    if( (fd = tap_alloc(dev)) < 0 ){
3985 d5d10bc3 ths
       fprintf(stderr, "Cannot allocate TAP device\n");
3986 d5d10bc3 ths
       return -1;
3987 d5d10bc3 ths
    }
3988 d5d10bc3 ths
    pstrcpy(ifname, ifname_size, dev);
3989 d5d10bc3 ths
    fcntl(fd, F_SETFL, O_NONBLOCK);
3990 d5d10bc3 ths
    return fd;
3991 ec530c81 bellard
}
3992 7d3505c5 bellard
#else
3993 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3994 330d0414 bellard
{
3995 80cabfad bellard
    struct ifreq ifr;
3996 c4b1fcc0 bellard
    int fd, ret;
3997 80cabfad bellard
    
3998 aeb30be6 balrog
    TFR(fd = open("/dev/net/tun", O_RDWR));
3999 80cabfad bellard
    if (fd < 0) {
4000 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
4001 80cabfad bellard
        return -1;
4002 330d0414 bellard
    }
4003 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
4004 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
4005 7c9d8e07 bellard
    if (ifname[0] != '\0')
4006 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
4007 7c9d8e07 bellard
    else
4008 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
4009 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
4010 80cabfad bellard
    if (ret != 0) {
4011 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
4012 80cabfad bellard
        close(fd);
4013 80cabfad bellard
        return -1;
4014 80cabfad bellard
    }
4015 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
4016 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
4017 c4b1fcc0 bellard
    return fd;
4018 c4b1fcc0 bellard
}
4019 7d3505c5 bellard
#endif
4020 330d0414 bellard
4021 7c9d8e07 bellard
static int net_tap_init(VLANState *vlan, const char *ifname1,
4022 7c9d8e07 bellard
                        const char *setup_script)
4023 7c9d8e07 bellard
{
4024 7c9d8e07 bellard
    TAPState *s;
4025 7c9d8e07 bellard
    int pid, status, fd;
4026 7c9d8e07 bellard
    char *args[3];
4027 7c9d8e07 bellard
    char **parg;
4028 7c9d8e07 bellard
    char ifname[128];
4029 7c9d8e07 bellard
4030 7c9d8e07 bellard
    if (ifname1 != NULL)
4031 7c9d8e07 bellard
        pstrcpy(ifname, sizeof(ifname), ifname1);
4032 7c9d8e07 bellard
    else
4033 7c9d8e07 bellard
        ifname[0] = '\0';
4034 aeb30be6 balrog
    TFR(fd = tap_open(ifname, sizeof(ifname)));
4035 7c9d8e07 bellard
    if (fd < 0)
4036 7c9d8e07 bellard
        return -1;
4037 7c9d8e07 bellard
4038 6a1cbf68 ths
    if (!setup_script || !strcmp(setup_script, "no"))
4039 7c9d8e07 bellard
        setup_script = "";
4040 7c9d8e07 bellard
    if (setup_script[0] != '\0') {
4041 7c9d8e07 bellard
        /* try to launch network init script */
4042 7c9d8e07 bellard
        pid = fork();
4043 7c9d8e07 bellard
        if (pid >= 0) {
4044 7c9d8e07 bellard
            if (pid == 0) {
4045 50d3eeae ths
                int open_max = sysconf (_SC_OPEN_MAX), i;
4046 50d3eeae ths
                for (i = 0; i < open_max; i++)
4047 50d3eeae ths
                    if (i != STDIN_FILENO &&
4048 50d3eeae ths
                        i != STDOUT_FILENO &&
4049 50d3eeae ths
                        i != STDERR_FILENO &&
4050 50d3eeae ths
                        i != fd)
4051 50d3eeae ths
                        close(i);
4052 50d3eeae ths
4053 7c9d8e07 bellard
                parg = args;
4054 7c9d8e07 bellard
                *parg++ = (char *)setup_script;
4055 7c9d8e07 bellard
                *parg++ = ifname;
4056 7c9d8e07 bellard
                *parg++ = NULL;
4057 7c9d8e07 bellard
                execv(setup_script, args);
4058 4a38940d bellard
                _exit(1);
4059 7c9d8e07 bellard
            }
4060 7c9d8e07 bellard
            while (waitpid(pid, &status, 0) != pid);
4061 7c9d8e07 bellard
            if (!WIFEXITED(status) ||
4062 7c9d8e07 bellard
                WEXITSTATUS(status) != 0) {
4063 7c9d8e07 bellard
                fprintf(stderr, "%s: could not launch network script\n",
4064 7c9d8e07 bellard
                        setup_script);
4065 7c9d8e07 bellard
                return -1;
4066 7c9d8e07 bellard
            }
4067 7c9d8e07 bellard
        }
4068 7c9d8e07 bellard
    }
4069 7c9d8e07 bellard
    s = net_tap_fd_init(vlan, fd);
4070 7c9d8e07 bellard
    if (!s)
4071 7c9d8e07 bellard
        return -1;
4072 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), 
4073 7c9d8e07 bellard
             "tap: ifname=%s setup_script=%s", ifname, setup_script);
4074 7c9d8e07 bellard
    return 0;
4075 7c9d8e07 bellard
}
4076 7c9d8e07 bellard
4077 fd1dff4b bellard
#endif /* !_WIN32 */
4078 fd1dff4b bellard
4079 7c9d8e07 bellard
/* network connection */
4080 7c9d8e07 bellard
typedef struct NetSocketState {
4081 7c9d8e07 bellard
    VLANClientState *vc;
4082 7c9d8e07 bellard
    int fd;
4083 7c9d8e07 bellard
    int state; /* 0 = getting length, 1 = getting data */
4084 7c9d8e07 bellard
    int index;
4085 7c9d8e07 bellard
    int packet_len;
4086 7c9d8e07 bellard
    uint8_t buf[4096];
4087 3d830459 bellard
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
4088 7c9d8e07 bellard
} NetSocketState;
4089 7c9d8e07 bellard
4090 7c9d8e07 bellard
typedef struct NetSocketListenState {
4091 7c9d8e07 bellard
    VLANState *vlan;
4092 7c9d8e07 bellard
    int fd;
4093 7c9d8e07 bellard
} NetSocketListenState;
4094 7c9d8e07 bellard
4095 7c9d8e07 bellard
/* XXX: we consider we can send the whole packet without blocking */
4096 7c9d8e07 bellard
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
4097 c20709aa bellard
{
4098 7c9d8e07 bellard
    NetSocketState *s = opaque;
4099 7c9d8e07 bellard
    uint32_t len;
4100 7c9d8e07 bellard
    len = htonl(size);
4101 7c9d8e07 bellard
4102 fd1dff4b bellard
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
4103 fd1dff4b bellard
    send_all(s->fd, buf, size);
4104 c20709aa bellard
}
4105 c20709aa bellard
4106 3d830459 bellard
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
4107 3d830459 bellard
{
4108 3d830459 bellard
    NetSocketState *s = opaque;
4109 3d830459 bellard
    sendto(s->fd, buf, size, 0, 
4110 3d830459 bellard
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
4111 3d830459 bellard
}
4112 3d830459 bellard
4113 7c9d8e07 bellard
static void net_socket_send(void *opaque)
4114 c4b1fcc0 bellard
{
4115 7c9d8e07 bellard
    NetSocketState *s = opaque;
4116 fd1dff4b bellard
    int l, size, err;
4117 7c9d8e07 bellard
    uint8_t buf1[4096];
4118 7c9d8e07 bellard
    const uint8_t *buf;
4119 7c9d8e07 bellard
4120 fd1dff4b bellard
    size = recv(s->fd, buf1, sizeof(buf1), 0);
4121 fd1dff4b bellard
    if (size < 0) {
4122 fd1dff4b bellard
        err = socket_error();
4123 fd1dff4b bellard
        if (err != EWOULDBLOCK) 
4124 fd1dff4b bellard
            goto eoc;
4125 fd1dff4b bellard
    } else if (size == 0) {
4126 7c9d8e07 bellard
        /* end of connection */
4127 fd1dff4b bellard
    eoc:
4128 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4129 fd1dff4b bellard
        closesocket(s->fd);
4130 7c9d8e07 bellard
        return;
4131 7c9d8e07 bellard
    }
4132 7c9d8e07 bellard
    buf = buf1;
4133 7c9d8e07 bellard
    while (size > 0) {
4134 7c9d8e07 bellard
        /* reassemble a packet from the network */
4135 7c9d8e07 bellard
        switch(s->state) {
4136 7c9d8e07 bellard
        case 0:
4137 7c9d8e07 bellard
            l = 4 - s->index;
4138 7c9d8e07 bellard
            if (l > size)
4139 7c9d8e07 bellard
                l = size;
4140 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4141 7c9d8e07 bellard
            buf += l;
4142 7c9d8e07 bellard
            size -= l;
4143 7c9d8e07 bellard
            s->index += l;
4144 7c9d8e07 bellard
            if (s->index == 4) {
4145 7c9d8e07 bellard
                /* got length */
4146 7c9d8e07 bellard
                s->packet_len = ntohl(*(uint32_t *)s->buf);
4147 7c9d8e07 bellard
                s->index = 0;
4148 7c9d8e07 bellard
                s->state = 1;
4149 7c9d8e07 bellard
            }
4150 7c9d8e07 bellard
            break;
4151 7c9d8e07 bellard
        case 1:
4152 7c9d8e07 bellard
            l = s->packet_len - s->index;
4153 7c9d8e07 bellard
            if (l > size)
4154 7c9d8e07 bellard
                l = size;
4155 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
4156 7c9d8e07 bellard
            s->index += l;
4157 7c9d8e07 bellard
            buf += l;
4158 7c9d8e07 bellard
            size -= l;
4159 7c9d8e07 bellard
            if (s->index >= s->packet_len) {
4160 7c9d8e07 bellard
                qemu_send_packet(s->vc, s->buf, s->packet_len);
4161 7c9d8e07 bellard
                s->index = 0;
4162 7c9d8e07 bellard
                s->state = 0;
4163 7c9d8e07 bellard
            }
4164 7c9d8e07 bellard
            break;
4165 7c9d8e07 bellard
        }
4166 7c9d8e07 bellard
    }
4167 c20709aa bellard
}
4168 c20709aa bellard
4169 3d830459 bellard
static void net_socket_send_dgram(void *opaque)
4170 3d830459 bellard
{
4171 3d830459 bellard
    NetSocketState *s = opaque;
4172 3d830459 bellard
    int size;
4173 3d830459 bellard
4174 3d830459 bellard
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
4175 3d830459 bellard
    if (size < 0) 
4176 3d830459 bellard
        return;
4177 3d830459 bellard
    if (size == 0) {
4178 3d830459 bellard
        /* end of connection */
4179 3d830459 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
4180 3d830459 bellard
        return;
4181 3d830459 bellard
    }
4182 3d830459 bellard
    qemu_send_packet(s->vc, s->buf, size);
4183 3d830459 bellard
}
4184 3d830459 bellard
4185 3d830459 bellard
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
4186 3d830459 bellard
{
4187 3d830459 bellard
    struct ip_mreq imr;
4188 3d830459 bellard
    int fd;
4189 3d830459 bellard
    int val, ret;
4190 3d830459 bellard
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
4191 3d830459 bellard
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
4192 fd1dff4b bellard
                inet_ntoa(mcastaddr->sin_addr), 
4193 fd1dff4b bellard
                (int)ntohl(mcastaddr->sin_addr.s_addr));
4194 3d830459 bellard
        return -1;
4195 3d830459 bellard
4196 3d830459 bellard
    }
4197 3d830459 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
4198 3d830459 bellard
    if (fd < 0) {
4199 3d830459 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
4200 3d830459 bellard
        return -1;
4201 3d830459 bellard
    }
4202 3d830459 bellard
4203 fd1dff4b bellard
    val = 1;
4204 fd1dff4b bellard
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
4205 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4206 fd1dff4b bellard
    if (ret < 0) {
4207 fd1dff4b bellard
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
4208 fd1dff4b bellard
        goto fail;
4209 fd1dff4b bellard
    }
4210 fd1dff4b bellard
4211 fd1dff4b bellard
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
4212 fd1dff4b bellard
    if (ret < 0) {
4213 fd1dff4b bellard
        perror("bind");
4214 fd1dff4b bellard
        goto fail;
4215 fd1dff4b bellard
    }
4216 fd1dff4b bellard
    
4217 3d830459 bellard
    /* Add host to multicast group */
4218 3d830459 bellard
    imr.imr_multiaddr = mcastaddr->sin_addr;
4219 3d830459 bellard
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
4220 3d830459 bellard
4221 fd1dff4b bellard
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
4222 fd1dff4b bellard
                     (const char *)&imr, sizeof(struct ip_mreq));
4223 3d830459 bellard
    if (ret < 0) {
4224 3d830459 bellard
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
4225 3d830459 bellard
        goto fail;
4226 3d830459 bellard
    }
4227 3d830459 bellard
4228 3d830459 bellard
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
4229 3d830459 bellard
    val = 1;
4230 fd1dff4b bellard
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, 
4231 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
4232 3d830459 bellard
    if (ret < 0) {
4233 3d830459 bellard
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
4234 3d830459 bellard
        goto fail;
4235 3d830459 bellard
    }
4236 3d830459 bellard
4237 fd1dff4b bellard
    socket_set_nonblock(fd);
4238 3d830459 bellard
    return fd;
4239 3d830459 bellard
fail:
4240 0bab00f3 bellard
    if (fd >= 0) 
4241 0bab00f3 bellard
        closesocket(fd);
4242 3d830459 bellard
    return -1;
4243 3d830459 bellard
}
4244 3d830459 bellard
4245 3d830459 bellard
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd, 
4246 3d830459 bellard
                                          int is_connected)
4247 3d830459 bellard
{
4248 3d830459 bellard
    struct sockaddr_in saddr;
4249 3d830459 bellard
    int newfd;
4250 3d830459 bellard
    socklen_t saddr_len;
4251 3d830459 bellard
    NetSocketState *s;
4252 3d830459 bellard
4253 3d830459 bellard
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
4254 3d830459 bellard
     * Because this may be "shared" socket from a "master" process, datagrams would be recv() 
4255 3d830459 bellard
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
4256 3d830459 bellard
     */
4257 3d830459 bellard
4258 3d830459 bellard
    if (is_connected) {
4259 3d830459 bellard
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
4260 3d830459 bellard
            /* must be bound */
4261 3d830459 bellard
            if (saddr.sin_addr.s_addr==0) {
4262 3d830459 bellard
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
4263 3d830459 bellard
                        fd);
4264 3d830459 bellard
                return NULL;
4265 3d830459 bellard
            }
4266 3d830459 bellard
            /* clone dgram socket */
4267 3d830459 bellard
            newfd = net_socket_mcast_create(&saddr);
4268 3d830459 bellard
            if (newfd < 0) {
4269 3d830459 bellard
                /* error already reported by net_socket_mcast_create() */
4270 3d830459 bellard
                close(fd);
4271 3d830459 bellard
                return NULL;
4272 3d830459 bellard
            }
4273 3d830459 bellard
            /* clone newfd to fd, close newfd */
4274 3d830459 bellard
            dup2(newfd, fd);
4275 3d830459 bellard
            close(newfd);
4276 3d830459 bellard
        
4277 3d830459 bellard
        } else {
4278 3d830459 bellard
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
4279 3d830459 bellard
                    fd, strerror(errno));
4280 3d830459 bellard
            return NULL;
4281 3d830459 bellard
        }
4282 3d830459 bellard
    }
4283 3d830459 bellard
4284 3d830459 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4285 3d830459 bellard
    if (!s)
4286 3d830459 bellard
        return NULL;
4287 3d830459 bellard
    s->fd = fd;
4288 3d830459 bellard
4289 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
4290 3d830459 bellard
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
4291 3d830459 bellard
4292 3d830459 bellard
    /* mcast: save bound address as dst */
4293 3d830459 bellard
    if (is_connected) s->dgram_dst=saddr;
4294 3d830459 bellard
4295 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4296 3d830459 bellard
            "socket: fd=%d (%s mcast=%s:%d)", 
4297 3d830459 bellard
            fd, is_connected? "cloned" : "",
4298 3d830459 bellard
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4299 3d830459 bellard
    return s;
4300 3d830459 bellard
}
4301 3d830459 bellard
4302 7c9d8e07 bellard
static void net_socket_connect(void *opaque)
4303 c20709aa bellard
{
4304 7c9d8e07 bellard
    NetSocketState *s = opaque;
4305 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
4306 7c9d8e07 bellard
}
4307 c4b1fcc0 bellard
4308 3d830459 bellard
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd, 
4309 7c9d8e07 bellard
                                          int is_connected)
4310 7c9d8e07 bellard
{
4311 7c9d8e07 bellard
    NetSocketState *s;
4312 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
4313 7c9d8e07 bellard
    if (!s)
4314 7c9d8e07 bellard
        return NULL;
4315 7c9d8e07 bellard
    s->fd = fd;
4316 7c9d8e07 bellard
    s->vc = qemu_new_vlan_client(vlan, 
4317 d861b05e pbrook
                                 net_socket_receive, NULL, s);
4318 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4319 7c9d8e07 bellard
             "socket: fd=%d", fd);
4320 7c9d8e07 bellard
    if (is_connected) {
4321 7c9d8e07 bellard
        net_socket_connect(s);
4322 7c9d8e07 bellard
    } else {
4323 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
4324 7c9d8e07 bellard
    }
4325 7c9d8e07 bellard
    return s;
4326 7c9d8e07 bellard
}
4327 c4b1fcc0 bellard
4328 3d830459 bellard
static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd, 
4329 3d830459 bellard
                                          int is_connected)
4330 3d830459 bellard
{
4331 3d830459 bellard
    int so_type=-1, optlen=sizeof(so_type);
4332 3d830459 bellard
4333 fd1dff4b bellard
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) {
4334 931f03ee ths
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
4335 3d830459 bellard
        return NULL;
4336 3d830459 bellard
    }
4337 3d830459 bellard
    switch(so_type) {
4338 3d830459 bellard
    case SOCK_DGRAM:
4339 3d830459 bellard
        return net_socket_fd_init_dgram(vlan, fd, is_connected);
4340 3d830459 bellard
    case SOCK_STREAM:
4341 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4342 3d830459 bellard
    default:
4343 3d830459 bellard
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
4344 3d830459 bellard
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
4345 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
4346 3d830459 bellard
    }
4347 3d830459 bellard
    return NULL;
4348 3d830459 bellard
}
4349 3d830459 bellard
4350 7c9d8e07 bellard
static void net_socket_accept(void *opaque)
4351 7c9d8e07 bellard
{
4352 7c9d8e07 bellard
    NetSocketListenState *s = opaque;    
4353 7c9d8e07 bellard
    NetSocketState *s1;
4354 7c9d8e07 bellard
    struct sockaddr_in saddr;
4355 7c9d8e07 bellard
    socklen_t len;
4356 7c9d8e07 bellard
    int fd;
4357 7c9d8e07 bellard
4358 7c9d8e07 bellard
    for(;;) {
4359 7c9d8e07 bellard
        len = sizeof(saddr);
4360 7c9d8e07 bellard
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
4361 7c9d8e07 bellard
        if (fd < 0 && errno != EINTR) {
4362 7c9d8e07 bellard
            return;
4363 7c9d8e07 bellard
        } else if (fd >= 0) {
4364 7c9d8e07 bellard
            break;
4365 80cabfad bellard
        }
4366 330d0414 bellard
    }
4367 7c9d8e07 bellard
    s1 = net_socket_fd_init(s->vlan, fd, 1); 
4368 7c9d8e07 bellard
    if (!s1) {
4369 0bab00f3 bellard
        closesocket(fd);
4370 7c9d8e07 bellard
    } else {
4371 7c9d8e07 bellard
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
4372 7c9d8e07 bellard
                 "socket: connection from %s:%d", 
4373 7c9d8e07 bellard
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4374 7c9d8e07 bellard
    }
4375 7c9d8e07 bellard
}
4376 7c9d8e07 bellard
4377 7c9d8e07 bellard
static int net_socket_listen_init(VLANState *vlan, const char *host_str)
4378 7c9d8e07 bellard
{
4379 7c9d8e07 bellard
    NetSocketListenState *s;
4380 7c9d8e07 bellard
    int fd, val, ret;
4381 7c9d8e07 bellard
    struct sockaddr_in saddr;
4382 7c9d8e07 bellard
4383 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4384 7c9d8e07 bellard
        return -1;
4385 7c9d8e07 bellard
    
4386 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketListenState));
4387 7c9d8e07 bellard
    if (!s)
4388 7c9d8e07 bellard
        return -1;
4389 7c9d8e07 bellard
4390 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4391 7c9d8e07 bellard
    if (fd < 0) {
4392 7c9d8e07 bellard
        perror("socket");
4393 7c9d8e07 bellard
        return -1;
4394 7c9d8e07 bellard
    }
4395 fd1dff4b bellard
    socket_set_nonblock(fd);
4396 7c9d8e07 bellard
4397 7c9d8e07 bellard
    /* allow fast reuse */
4398 7c9d8e07 bellard
    val = 1;
4399 fd1dff4b bellard
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
4400 7c9d8e07 bellard
    
4401 7c9d8e07 bellard
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4402 7c9d8e07 bellard
    if (ret < 0) {
4403 7c9d8e07 bellard
        perror("bind");
4404 7c9d8e07 bellard
        return -1;
4405 7c9d8e07 bellard
    }
4406 7c9d8e07 bellard
    ret = listen(fd, 0);
4407 7c9d8e07 bellard
    if (ret < 0) {
4408 7c9d8e07 bellard
        perror("listen");
4409 7c9d8e07 bellard
        return -1;
4410 7c9d8e07 bellard
    }
4411 7c9d8e07 bellard
    s->vlan = vlan;
4412 7c9d8e07 bellard
    s->fd = fd;
4413 7c9d8e07 bellard
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
4414 80cabfad bellard
    return 0;
4415 330d0414 bellard
}
4416 330d0414 bellard
4417 7c9d8e07 bellard
static int net_socket_connect_init(VLANState *vlan, const char *host_str)
4418 330d0414 bellard
{
4419 7c9d8e07 bellard
    NetSocketState *s;
4420 fd1dff4b bellard
    int fd, connected, ret, err;
4421 7c9d8e07 bellard
    struct sockaddr_in saddr;
4422 7c9d8e07 bellard
4423 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4424 7c9d8e07 bellard
        return -1;
4425 7c9d8e07 bellard
4426 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4427 7c9d8e07 bellard
    if (fd < 0) {
4428 7c9d8e07 bellard
        perror("socket");
4429 7c9d8e07 bellard
        return -1;
4430 7c9d8e07 bellard
    }
4431 fd1dff4b bellard
    socket_set_nonblock(fd);
4432 7c9d8e07 bellard
4433 7c9d8e07 bellard
    connected = 0;
4434 7c9d8e07 bellard
    for(;;) {
4435 7c9d8e07 bellard
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4436 7c9d8e07 bellard
        if (ret < 0) {
4437 fd1dff4b bellard
            err = socket_error();
4438 fd1dff4b bellard
            if (err == EINTR || err == EWOULDBLOCK) {
4439 fd1dff4b bellard
            } else if (err == EINPROGRESS) {
4440 7c9d8e07 bellard
                break;
4441 f5b12268 ths
#ifdef _WIN32
4442 f5b12268 ths
            } else if (err == WSAEALREADY) {
4443 f5b12268 ths
                break;
4444 f5b12268 ths
#endif
4445 7c9d8e07 bellard
            } else {
4446 7c9d8e07 bellard
                perror("connect");
4447 fd1dff4b bellard
                closesocket(fd);
4448 7c9d8e07 bellard
                return -1;
4449 7c9d8e07 bellard
            }
4450 7c9d8e07 bellard
        } else {
4451 7c9d8e07 bellard
            connected = 1;
4452 7c9d8e07 bellard
            break;
4453 7c9d8e07 bellard
        }
4454 7c9d8e07 bellard
    }
4455 7c9d8e07 bellard
    s = net_socket_fd_init(vlan, fd, connected);
4456 7c9d8e07 bellard
    if (!s)
4457 7c9d8e07 bellard
        return -1;
4458 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4459 7c9d8e07 bellard
             "socket: connect to %s:%d", 
4460 7c9d8e07 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4461 c20709aa bellard
    return 0;
4462 80cabfad bellard
}
4463 330d0414 bellard
4464 3d830459 bellard
static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
4465 3d830459 bellard
{
4466 3d830459 bellard
    NetSocketState *s;
4467 3d830459 bellard
    int fd;
4468 3d830459 bellard
    struct sockaddr_in saddr;
4469 3d830459 bellard
4470 3d830459 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4471 3d830459 bellard
        return -1;
4472 3d830459 bellard
4473 3d830459 bellard
4474 3d830459 bellard
    fd = net_socket_mcast_create(&saddr);
4475 3d830459 bellard
    if (fd < 0)
4476 3d830459 bellard
        return -1;
4477 3d830459 bellard
4478 3d830459 bellard
    s = net_socket_fd_init(vlan, fd, 0);
4479 3d830459 bellard
    if (!s)
4480 3d830459 bellard
        return -1;
4481 3d830459 bellard
4482 3d830459 bellard
    s->dgram_dst = saddr;
4483 3d830459 bellard
    
4484 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4485 3d830459 bellard
             "socket: mcast=%s:%d", 
4486 3d830459 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4487 3d830459 bellard
    return 0;
4488 3d830459 bellard
4489 3d830459 bellard
}
4490 3d830459 bellard
4491 7c9d8e07 bellard
static int get_param_value(char *buf, int buf_size,
4492 7c9d8e07 bellard
                           const char *tag, const char *str)
4493 7c9d8e07 bellard
{
4494 7c9d8e07 bellard
    const char *p;
4495 7c9d8e07 bellard
    char *q;
4496 7c9d8e07 bellard
    char option[128];
4497 7c9d8e07 bellard
4498 7c9d8e07 bellard
    p = str;
4499 7c9d8e07 bellard
    for(;;) {
4500 7c9d8e07 bellard
        q = option;
4501 7c9d8e07 bellard
        while (*p != '\0' && *p != '=') {
4502 7c9d8e07 bellard
            if ((q - option) < sizeof(option) - 1)
4503 7c9d8e07 bellard
                *q++ = *p;
4504 7c9d8e07 bellard
            p++;
4505 7c9d8e07 bellard
        }
4506 7c9d8e07 bellard
        *q = '\0';
4507 7c9d8e07 bellard
        if (*p != '=')
4508 7c9d8e07 bellard
            break;
4509 7c9d8e07 bellard
        p++;
4510 7c9d8e07 bellard
        if (!strcmp(tag, option)) {
4511 7c9d8e07 bellard
            q = buf;
4512 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4513 7c9d8e07 bellard
                if ((q - buf) < buf_size - 1)
4514 7c9d8e07 bellard
                    *q++ = *p;
4515 7c9d8e07 bellard
                p++;
4516 7c9d8e07 bellard
            }
4517 7c9d8e07 bellard
            *q = '\0';
4518 7c9d8e07 bellard
            return q - buf;
4519 7c9d8e07 bellard
        } else {
4520 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4521 7c9d8e07 bellard
                p++;
4522 7c9d8e07 bellard
            }
4523 7c9d8e07 bellard
        }
4524 7c9d8e07 bellard
        if (*p != ',')
4525 7c9d8e07 bellard
            break;
4526 7c9d8e07 bellard
        p++;
4527 7c9d8e07 bellard
    }
4528 7c9d8e07 bellard
    return 0;
4529 7c9d8e07 bellard
}
4530 7c9d8e07 bellard
4531 52f61fde ths
static int net_client_init(const char *str)
4532 7c9d8e07 bellard
{
4533 7c9d8e07 bellard
    const char *p;
4534 7c9d8e07 bellard
    char *q;
4535 7c9d8e07 bellard
    char device[64];
4536 7c9d8e07 bellard
    char buf[1024];
4537 7c9d8e07 bellard
    int vlan_id, ret;
4538 7c9d8e07 bellard
    VLANState *vlan;
4539 7c9d8e07 bellard
4540 7c9d8e07 bellard
    p = str;
4541 7c9d8e07 bellard
    q = device;
4542 7c9d8e07 bellard
    while (*p != '\0' && *p != ',') {
4543 7c9d8e07 bellard
        if ((q - device) < sizeof(device) - 1)
4544 7c9d8e07 bellard
            *q++ = *p;
4545 7c9d8e07 bellard
        p++;
4546 7c9d8e07 bellard
    }
4547 7c9d8e07 bellard
    *q = '\0';
4548 7c9d8e07 bellard
    if (*p == ',')
4549 7c9d8e07 bellard
        p++;
4550 7c9d8e07 bellard
    vlan_id = 0;
4551 7c9d8e07 bellard
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
4552 7c9d8e07 bellard
        vlan_id = strtol(buf, NULL, 0);
4553 7c9d8e07 bellard
    }
4554 7c9d8e07 bellard
    vlan = qemu_find_vlan(vlan_id);
4555 7c9d8e07 bellard
    if (!vlan) {
4556 7c9d8e07 bellard
        fprintf(stderr, "Could not create vlan %d\n", vlan_id);
4557 7c9d8e07 bellard
        return -1;
4558 7c9d8e07 bellard
    }
4559 7c9d8e07 bellard
    if (!strcmp(device, "nic")) {
4560 7c9d8e07 bellard
        NICInfo *nd;
4561 7c9d8e07 bellard
        uint8_t *macaddr;
4562 7c9d8e07 bellard
4563 7c9d8e07 bellard
        if (nb_nics >= MAX_NICS) {
4564 7c9d8e07 bellard
            fprintf(stderr, "Too Many NICs\n");
4565 7c9d8e07 bellard
            return -1;
4566 7c9d8e07 bellard
        }
4567 7c9d8e07 bellard
        nd = &nd_table[nb_nics];
4568 7c9d8e07 bellard
        macaddr = nd->macaddr;
4569 7c9d8e07 bellard
        macaddr[0] = 0x52;
4570 7c9d8e07 bellard
        macaddr[1] = 0x54;
4571 7c9d8e07 bellard
        macaddr[2] = 0x00;
4572 7c9d8e07 bellard
        macaddr[3] = 0x12;
4573 7c9d8e07 bellard
        macaddr[4] = 0x34;
4574 7c9d8e07 bellard
        macaddr[5] = 0x56 + nb_nics;
4575 7c9d8e07 bellard
4576 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
4577 7c9d8e07 bellard
            if (parse_macaddr(macaddr, buf) < 0) {
4578 7c9d8e07 bellard
                fprintf(stderr, "invalid syntax for ethernet address\n");
4579 7c9d8e07 bellard
                return -1;
4580 7c9d8e07 bellard
            }
4581 7c9d8e07 bellard
        }
4582 a41b2ff2 pbrook
        if (get_param_value(buf, sizeof(buf), "model", p)) {
4583 a41b2ff2 pbrook
            nd->model = strdup(buf);
4584 a41b2ff2 pbrook
        }
4585 7c9d8e07 bellard
        nd->vlan = vlan;
4586 7c9d8e07 bellard
        nb_nics++;
4587 833c7174 blueswir1
        vlan->nb_guest_devs++;
4588 7c9d8e07 bellard
        ret = 0;
4589 7c9d8e07 bellard
    } else
4590 7c9d8e07 bellard
    if (!strcmp(device, "none")) {
4591 7c9d8e07 bellard
        /* does nothing. It is needed to signal that no network cards
4592 7c9d8e07 bellard
           are wanted */
4593 7c9d8e07 bellard
        ret = 0;
4594 7c9d8e07 bellard
    } else
4595 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
4596 7c9d8e07 bellard
    if (!strcmp(device, "user")) {
4597 115defd1 pbrook
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
4598 3f423c9c bellard
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
4599 115defd1 pbrook
        }
4600 833c7174 blueswir1
        vlan->nb_host_devs++;
4601 7c9d8e07 bellard
        ret = net_slirp_init(vlan);
4602 7c9d8e07 bellard
    } else
4603 7c9d8e07 bellard
#endif
4604 7fb843f8 bellard
#ifdef _WIN32
4605 7fb843f8 bellard
    if (!strcmp(device, "tap")) {
4606 7fb843f8 bellard
        char ifname[64];
4607 7fb843f8 bellard
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4608 7fb843f8 bellard
            fprintf(stderr, "tap: no interface name\n");
4609 7fb843f8 bellard
            return -1;
4610 7fb843f8 bellard
        }
4611 833c7174 blueswir1
        vlan->nb_host_devs++;
4612 7fb843f8 bellard
        ret = tap_win32_init(vlan, ifname);
4613 7fb843f8 bellard
    } else
4614 7fb843f8 bellard
#else
4615 7c9d8e07 bellard
    if (!strcmp(device, "tap")) {
4616 7c9d8e07 bellard
        char ifname[64];
4617 7c9d8e07 bellard
        char setup_script[1024];
4618 7c9d8e07 bellard
        int fd;
4619 4f01035f pbrook
        vlan->nb_host_devs++;
4620 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4621 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4622 7c9d8e07 bellard
            ret = -1;
4623 7c9d8e07 bellard
            if (net_tap_fd_init(vlan, fd))
4624 7c9d8e07 bellard
                ret = 0;
4625 7c9d8e07 bellard
        } else {
4626 bf8c5342 bellard
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4627 bf8c5342 bellard
                ifname[0] = '\0';
4628 bf8c5342 bellard
            }
4629 7c9d8e07 bellard
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
4630 7c9d8e07 bellard
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
4631 7c9d8e07 bellard
            }
4632 7c9d8e07 bellard
            ret = net_tap_init(vlan, ifname, setup_script);
4633 7c9d8e07 bellard
        }
4634 7c9d8e07 bellard
    } else
4635 fd1dff4b bellard
#endif
4636 7c9d8e07 bellard
    if (!strcmp(device, "socket")) {
4637 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4638 7c9d8e07 bellard
            int fd;
4639 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4640 7c9d8e07 bellard
            ret = -1;
4641 7c9d8e07 bellard
            if (net_socket_fd_init(vlan, fd, 1))
4642 7c9d8e07 bellard
                ret = 0;
4643 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
4644 7c9d8e07 bellard
            ret = net_socket_listen_init(vlan, buf);
4645 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
4646 7c9d8e07 bellard
            ret = net_socket_connect_init(vlan, buf);
4647 3d830459 bellard
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
4648 3d830459 bellard
            ret = net_socket_mcast_init(vlan, buf);
4649 7c9d8e07 bellard
        } else {
4650 7c9d8e07 bellard
            fprintf(stderr, "Unknown socket options: %s\n", p);
4651 7c9d8e07 bellard
            return -1;
4652 7c9d8e07 bellard
        }
4653 833c7174 blueswir1
        vlan->nb_host_devs++;
4654 7c9d8e07 bellard
    } else
4655 7c9d8e07 bellard
    {
4656 7c9d8e07 bellard
        fprintf(stderr, "Unknown network device: %s\n", device);
4657 7c9d8e07 bellard
        return -1;
4658 7c9d8e07 bellard
    }
4659 7c9d8e07 bellard
    if (ret < 0) {
4660 7c9d8e07 bellard
        fprintf(stderr, "Could not initialize device '%s'\n", device);
4661 7c9d8e07 bellard
    }
4662 7c9d8e07 bellard
    
4663 7c9d8e07 bellard
    return ret;
4664 7c9d8e07 bellard
}
4665 7c9d8e07 bellard
4666 7c9d8e07 bellard
void do_info_network(void)
4667 7c9d8e07 bellard
{
4668 7c9d8e07 bellard
    VLANState *vlan;
4669 7c9d8e07 bellard
    VLANClientState *vc;
4670 7c9d8e07 bellard
4671 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4672 7c9d8e07 bellard
        term_printf("VLAN %d devices:\n", vlan->id);
4673 7c9d8e07 bellard
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
4674 7c9d8e07 bellard
            term_printf("  %s\n", vc->info_str);
4675 7c9d8e07 bellard
    }
4676 7c9d8e07 bellard
}
4677 42550fde ths
4678 330d0414 bellard
/***********************************************************/
4679 a594cfbf bellard
/* USB devices */
4680 a594cfbf bellard
4681 0d92ed30 pbrook
static USBPort *used_usb_ports;
4682 0d92ed30 pbrook
static USBPort *free_usb_ports;
4683 0d92ed30 pbrook
4684 0d92ed30 pbrook
/* ??? Maybe change this to register a hub to keep track of the topology.  */
4685 0d92ed30 pbrook
void qemu_register_usb_port(USBPort *port, void *opaque, int index,
4686 0d92ed30 pbrook
                            usb_attachfn attach)
4687 0d92ed30 pbrook
{
4688 0d92ed30 pbrook
    port->opaque = opaque;
4689 0d92ed30 pbrook
    port->index = index;
4690 0d92ed30 pbrook
    port->attach = attach;
4691 0d92ed30 pbrook
    port->next = free_usb_ports;
4692 0d92ed30 pbrook
    free_usb_ports = port;
4693 0d92ed30 pbrook
}
4694 0d92ed30 pbrook
4695 a594cfbf bellard
static int usb_device_add(const char *devname)
4696 a594cfbf bellard
{
4697 a594cfbf bellard
    const char *p;
4698 a594cfbf bellard
    USBDevice *dev;
4699 0d92ed30 pbrook
    USBPort *port;
4700 a594cfbf bellard
4701 0d92ed30 pbrook
    if (!free_usb_ports)
4702 a594cfbf bellard
        return -1;
4703 a594cfbf bellard
4704 a594cfbf bellard
    if (strstart(devname, "host:", &p)) {
4705 a594cfbf bellard
        dev = usb_host_device_open(p);
4706 a594cfbf bellard
    } else if (!strcmp(devname, "mouse")) {
4707 a594cfbf bellard
        dev = usb_mouse_init();
4708 09b26c5e bellard
    } else if (!strcmp(devname, "tablet")) {
4709 47b2d338 balrog
        dev = usb_tablet_init();
4710 47b2d338 balrog
    } else if (!strcmp(devname, "keyboard")) {
4711 47b2d338 balrog
        dev = usb_keyboard_init();
4712 2e5d83bb pbrook
    } else if (strstart(devname, "disk:", &p)) {
4713 2e5d83bb pbrook
        dev = usb_msd_init(p);
4714 f6d2a316 balrog
    } else if (!strcmp(devname, "wacom-tablet")) {
4715 f6d2a316 balrog
        dev = usb_wacom_init();
4716 a594cfbf bellard
    } else {
4717 a594cfbf bellard
        return -1;
4718 a594cfbf bellard
    }
4719 0d92ed30 pbrook
    if (!dev)
4720 0d92ed30 pbrook
        return -1;
4721 0d92ed30 pbrook
4722 0d92ed30 pbrook
    /* Find a USB port to add the device to.  */
4723 0d92ed30 pbrook
    port = free_usb_ports;
4724 0d92ed30 pbrook
    if (!port->next) {
4725 0d92ed30 pbrook
        USBDevice *hub;
4726 0d92ed30 pbrook
4727 0d92ed30 pbrook
        /* Create a new hub and chain it on.  */
4728 0d92ed30 pbrook
        free_usb_ports = NULL;
4729 0d92ed30 pbrook
        port->next = used_usb_ports;
4730 0d92ed30 pbrook
        used_usb_ports = port;
4731 0d92ed30 pbrook
4732 0d92ed30 pbrook
        hub = usb_hub_init(VM_USB_HUB_SIZE);
4733 0d92ed30 pbrook
        usb_attach(port, hub);
4734 0d92ed30 pbrook
        port = free_usb_ports;
4735 0d92ed30 pbrook
    }
4736 0d92ed30 pbrook
4737 0d92ed30 pbrook
    free_usb_ports = port->next;
4738 0d92ed30 pbrook
    port->next = used_usb_ports;
4739 0d92ed30 pbrook
    used_usb_ports = port;
4740 0d92ed30 pbrook
    usb_attach(port, dev);
4741 a594cfbf bellard
    return 0;
4742 a594cfbf bellard
}
4743 a594cfbf bellard
4744 a594cfbf bellard
static int usb_device_del(const char *devname)
4745 a594cfbf bellard
{
4746 0d92ed30 pbrook
    USBPort *port;
4747 0d92ed30 pbrook
    USBPort **lastp;
4748 059809e4 bellard
    USBDevice *dev;
4749 0d92ed30 pbrook
    int bus_num, addr;
4750 a594cfbf bellard
    const char *p;
4751 a594cfbf bellard
4752 0d92ed30 pbrook
    if (!used_usb_ports)
4753 a594cfbf bellard
        return -1;
4754 a594cfbf bellard
4755 a594cfbf bellard
    p = strchr(devname, '.');
4756 a594cfbf bellard
    if (!p) 
4757 a594cfbf bellard
        return -1;
4758 a594cfbf bellard
    bus_num = strtoul(devname, NULL, 0);
4759 a594cfbf bellard
    addr = strtoul(p + 1, NULL, 0);
4760 a594cfbf bellard
    if (bus_num != 0)
4761 a594cfbf bellard
        return -1;
4762 0d92ed30 pbrook
4763 0d92ed30 pbrook
    lastp = &used_usb_ports;
4764 0d92ed30 pbrook
    port = used_usb_ports;
4765 0d92ed30 pbrook
    while (port && port->dev->addr != addr) {
4766 0d92ed30 pbrook
        lastp = &port->next;
4767 0d92ed30 pbrook
        port = port->next;
4768 a594cfbf bellard
    }
4769 0d92ed30 pbrook
4770 0d92ed30 pbrook
    if (!port)
4771 a594cfbf bellard
        return -1;
4772 0d92ed30 pbrook
4773 059809e4 bellard
    dev = port->dev;
4774 0d92ed30 pbrook
    *lastp = port->next;
4775 0d92ed30 pbrook
    usb_attach(port, NULL);
4776 059809e4 bellard
    dev->handle_destroy(dev);
4777 0d92ed30 pbrook
    port->next = free_usb_ports;
4778 0d92ed30 pbrook
    free_usb_ports = port;
4779 a594cfbf bellard
    return 0;
4780 a594cfbf bellard
}
4781 a594cfbf bellard
4782 a594cfbf bellard
void do_usb_add(const char *devname)
4783 a594cfbf bellard
{
4784 a594cfbf bellard
    int ret;
4785 a594cfbf bellard
    ret = usb_device_add(devname);
4786 a594cfbf bellard
    if (ret < 0) 
4787 a594cfbf bellard
        term_printf("Could not add USB device '%s'\n", devname);
4788 a594cfbf bellard
}
4789 a594cfbf bellard
4790 a594cfbf bellard
void do_usb_del(const char *devname)
4791 a594cfbf bellard
{
4792 a594cfbf bellard
    int ret;
4793 a594cfbf bellard
    ret = usb_device_del(devname);
4794 a594cfbf bellard
    if (ret < 0) 
4795 a594cfbf bellard
        term_printf("Could not remove USB device '%s'\n", devname);
4796 a594cfbf bellard
}
4797 a594cfbf bellard
4798 a594cfbf bellard
void usb_info(void)
4799 a594cfbf bellard
{
4800 a594cfbf bellard
    USBDevice *dev;
4801 0d92ed30 pbrook
    USBPort *port;
4802 a594cfbf bellard
    const char *speed_str;
4803 a594cfbf bellard
4804 0d92ed30 pbrook
    if (!usb_enabled) {
4805 a594cfbf bellard
        term_printf("USB support not enabled\n");
4806 a594cfbf bellard
        return;
4807 a594cfbf bellard
    }
4808 a594cfbf bellard
4809 0d92ed30 pbrook
    for (port = used_usb_ports; port; port = port->next) {
4810 0d92ed30 pbrook
        dev = port->dev;
4811 0d92ed30 pbrook
        if (!dev)
4812 0d92ed30 pbrook
            continue;
4813 0d92ed30 pbrook
        switch(dev->speed) {
4814 0d92ed30 pbrook
        case USB_SPEED_LOW: 
4815 0d92ed30 pbrook
            speed_str = "1.5"; 
4816 0d92ed30 pbrook
            break;
4817 0d92ed30 pbrook
        case USB_SPEED_FULL: 
4818 0d92ed30 pbrook
            speed_str = "12"; 
4819 0d92ed30 pbrook
            break;
4820 0d92ed30 pbrook
        case USB_SPEED_HIGH: 
4821 0d92ed30 pbrook
            speed_str = "480"; 
4822 0d92ed30 pbrook
            break;
4823 0d92ed30 pbrook
        default:
4824 0d92ed30 pbrook
            speed_str = "?"; 
4825 0d92ed30 pbrook
            break;
4826 a594cfbf bellard
        }
4827 1f6e24e7 bellard
        term_printf("  Device %d.%d, Speed %s Mb/s, Product %s\n", 
4828 1f6e24e7 bellard
                    0, dev->addr, speed_str, dev->devname);
4829 a594cfbf bellard
    }
4830 a594cfbf bellard
}
4831 a594cfbf bellard
4832 f7cce898 bellard
/***********************************************************/
4833 201a51fc balrog
/* PCMCIA/Cardbus */
4834 201a51fc balrog
4835 201a51fc balrog
static struct pcmcia_socket_entry_s {
4836 201a51fc balrog
    struct pcmcia_socket_s *socket;
4837 201a51fc balrog
    struct pcmcia_socket_entry_s *next;
4838 201a51fc balrog
} *pcmcia_sockets = 0;
4839 201a51fc balrog
4840 201a51fc balrog
void pcmcia_socket_register(struct pcmcia_socket_s *socket)
4841 201a51fc balrog
{
4842 201a51fc balrog
    struct pcmcia_socket_entry_s *entry;
4843 201a51fc balrog
4844 201a51fc balrog
    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
4845 201a51fc balrog
    entry->socket = socket;
4846 201a51fc balrog
    entry->next = pcmcia_sockets;
4847 201a51fc balrog
    pcmcia_sockets = entry;
4848 201a51fc balrog
}
4849 201a51fc balrog
4850 201a51fc balrog
void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
4851 201a51fc balrog
{
4852 201a51fc balrog
    struct pcmcia_socket_entry_s *entry, **ptr;
4853 201a51fc balrog
4854 201a51fc balrog
    ptr = &pcmcia_sockets;
4855 201a51fc balrog
    for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
4856 201a51fc balrog
        if (entry->socket == socket) {
4857 201a51fc balrog
            *ptr = entry->next;
4858 201a51fc balrog
            qemu_free(entry);
4859 201a51fc balrog
        }
4860 201a51fc balrog
}
4861 201a51fc balrog
4862 201a51fc balrog
void pcmcia_info(void)
4863 201a51fc balrog
{
4864 201a51fc balrog
    struct pcmcia_socket_entry_s *iter;
4865 201a51fc balrog
    if (!pcmcia_sockets)
4866 201a51fc balrog
        term_printf("No PCMCIA sockets\n");
4867 201a51fc balrog
4868 201a51fc balrog
    for (iter = pcmcia_sockets; iter; iter = iter->next)
4869 201a51fc balrog
        term_printf("%s: %s\n", iter->socket->slot_string,
4870 201a51fc balrog
                    iter->socket->attached ? iter->socket->card_string :
4871 201a51fc balrog
                    "Empty");
4872 201a51fc balrog
}
4873 201a51fc balrog
4874 201a51fc balrog
/***********************************************************/
4875 2ff89790 ths
/* dumb display */
4876 2ff89790 ths
4877 2ff89790 ths
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
4878 2ff89790 ths
{
4879 2ff89790 ths
}
4880 2ff89790 ths
4881 2ff89790 ths
static void dumb_resize(DisplayState *ds, int w, int h)
4882 2ff89790 ths
{
4883 2ff89790 ths
}
4884 2ff89790 ths
4885 2ff89790 ths
static void dumb_refresh(DisplayState *ds)
4886 2ff89790 ths
{
4887 2ff89790 ths
#if defined(CONFIG_SDL)
4888 2ff89790 ths
    vga_hw_update();
4889 2ff89790 ths
#endif
4890 2ff89790 ths
}
4891 2ff89790 ths
4892 2ff89790 ths
static void dumb_display_init(DisplayState *ds)
4893 2ff89790 ths
{
4894 2ff89790 ths
    ds->data = NULL;
4895 2ff89790 ths
    ds->linesize = 0;
4896 2ff89790 ths
    ds->depth = 0;
4897 2ff89790 ths
    ds->dpy_update = dumb_update;
4898 2ff89790 ths
    ds->dpy_resize = dumb_resize;
4899 2ff89790 ths
    ds->dpy_refresh = dumb_refresh;
4900 2ff89790 ths
}
4901 2ff89790 ths
4902 2ff89790 ths
/***********************************************************/
4903 8a7ddc38 bellard
/* I/O handling */
4904 0824d6fc bellard
4905 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
4906 c4b1fcc0 bellard
4907 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
4908 c4b1fcc0 bellard
    int fd;
4909 7c9d8e07 bellard
    IOCanRWHandler *fd_read_poll;
4910 7c9d8e07 bellard
    IOHandler *fd_read;
4911 7c9d8e07 bellard
    IOHandler *fd_write;
4912 cafffd40 ths
    int deleted;
4913 c4b1fcc0 bellard
    void *opaque;
4914 c4b1fcc0 bellard
    /* temporary data */
4915 c4b1fcc0 bellard
    struct pollfd *ufd;
4916 8a7ddc38 bellard
    struct IOHandlerRecord *next;
4917 c4b1fcc0 bellard
} IOHandlerRecord;
4918 c4b1fcc0 bellard
4919 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
4920 c4b1fcc0 bellard
4921 7c9d8e07 bellard
/* XXX: fd_read_poll should be suppressed, but an API change is
4922 7c9d8e07 bellard
   necessary in the character devices to suppress fd_can_read(). */
4923 7c9d8e07 bellard
int qemu_set_fd_handler2(int fd, 
4924 7c9d8e07 bellard
                         IOCanRWHandler *fd_read_poll, 
4925 7c9d8e07 bellard
                         IOHandler *fd_read, 
4926 7c9d8e07 bellard
                         IOHandler *fd_write, 
4927 7c9d8e07 bellard
                         void *opaque)
4928 c4b1fcc0 bellard
{
4929 7c9d8e07 bellard
    IOHandlerRecord **pioh, *ioh;
4930 c4b1fcc0 bellard
4931 7c9d8e07 bellard
    if (!fd_read && !fd_write) {
4932 7c9d8e07 bellard
        pioh = &first_io_handler;
4933 7c9d8e07 bellard
        for(;;) {
4934 7c9d8e07 bellard
            ioh = *pioh;
4935 7c9d8e07 bellard
            if (ioh == NULL)
4936 7c9d8e07 bellard
                break;
4937 7c9d8e07 bellard
            if (ioh->fd == fd) {
4938 cafffd40 ths
                ioh->deleted = 1;
4939 7c9d8e07 bellard
                break;
4940 7c9d8e07 bellard
            }
4941 7c9d8e07 bellard
            pioh = &ioh->next;
4942 7c9d8e07 bellard
        }
4943 7c9d8e07 bellard
    } else {
4944 7c9d8e07 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
4945 7c9d8e07 bellard
            if (ioh->fd == fd)
4946 7c9d8e07 bellard
                goto found;
4947 7c9d8e07 bellard
        }
4948 7c9d8e07 bellard
        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
4949 7c9d8e07 bellard
        if (!ioh)
4950 7c9d8e07 bellard
            return -1;
4951 7c9d8e07 bellard
        ioh->next = first_io_handler;
4952 7c9d8e07 bellard
        first_io_handler = ioh;
4953 7c9d8e07 bellard
    found:
4954 7c9d8e07 bellard
        ioh->fd = fd;
4955 7c9d8e07 bellard
        ioh->fd_read_poll = fd_read_poll;
4956 7c9d8e07 bellard
        ioh->fd_read = fd_read;
4957 7c9d8e07 bellard
        ioh->fd_write = fd_write;
4958 7c9d8e07 bellard
        ioh->opaque = opaque;
4959 cafffd40 ths
        ioh->deleted = 0;
4960 7c9d8e07 bellard
    }
4961 c4b1fcc0 bellard
    return 0;
4962 c4b1fcc0 bellard
}
4963 c4b1fcc0 bellard
4964 7c9d8e07 bellard
int qemu_set_fd_handler(int fd, 
4965 7c9d8e07 bellard
                        IOHandler *fd_read, 
4966 7c9d8e07 bellard
                        IOHandler *fd_write, 
4967 7c9d8e07 bellard
                        void *opaque)
4968 8a7ddc38 bellard
{
4969 7c9d8e07 bellard
    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
4970 8a7ddc38 bellard
}
4971 8a7ddc38 bellard
4972 8a7ddc38 bellard
/***********************************************************/
4973 f331110f bellard
/* Polling handling */
4974 f331110f bellard
4975 f331110f bellard
typedef struct PollingEntry {
4976 f331110f bellard
    PollingFunc *func;
4977 f331110f bellard
    void *opaque;
4978 f331110f bellard
    struct PollingEntry *next;
4979 f331110f bellard
} PollingEntry;
4980 f331110f bellard
4981 f331110f bellard
static PollingEntry *first_polling_entry;
4982 f331110f bellard
4983 f331110f bellard
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
4984 f331110f bellard
{
4985 f331110f bellard
    PollingEntry **ppe, *pe;
4986 f331110f bellard
    pe = qemu_mallocz(sizeof(PollingEntry));
4987 f331110f bellard
    if (!pe)
4988 f331110f bellard
        return -1;
4989 f331110f bellard
    pe->func = func;
4990 f331110f bellard
    pe->opaque = opaque;
4991 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
4992 f331110f bellard
    *ppe = pe;
4993 f331110f bellard
    return 0;
4994 f331110f bellard
}
4995 f331110f bellard
4996 f331110f bellard
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
4997 f331110f bellard
{
4998 f331110f bellard
    PollingEntry **ppe, *pe;
4999 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
5000 f331110f bellard
        pe = *ppe;
5001 f331110f bellard
        if (pe->func == func && pe->opaque == opaque) {
5002 f331110f bellard
            *ppe = pe->next;
5003 f331110f bellard
            qemu_free(pe);
5004 f331110f bellard
            break;
5005 f331110f bellard
        }
5006 f331110f bellard
    }
5007 f331110f bellard
}
5008 f331110f bellard
5009 a18e524a bellard
#ifdef _WIN32
5010 a18e524a bellard
/***********************************************************/
5011 a18e524a bellard
/* Wait objects support */
5012 a18e524a bellard
typedef struct WaitObjects {
5013 a18e524a bellard
    int num;
5014 a18e524a bellard
    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
5015 a18e524a bellard
    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
5016 a18e524a bellard
    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
5017 a18e524a bellard
} WaitObjects;
5018 a18e524a bellard
5019 a18e524a bellard
static WaitObjects wait_objects = {0};
5020 a18e524a bellard
    
5021 a18e524a bellard
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5022 a18e524a bellard
{
5023 a18e524a bellard
    WaitObjects *w = &wait_objects;
5024 a18e524a bellard
5025 a18e524a bellard
    if (w->num >= MAXIMUM_WAIT_OBJECTS)
5026 a18e524a bellard
        return -1;
5027 a18e524a bellard
    w->events[w->num] = handle;
5028 a18e524a bellard
    w->func[w->num] = func;
5029 a18e524a bellard
    w->opaque[w->num] = opaque;
5030 a18e524a bellard
    w->num++;
5031 a18e524a bellard
    return 0;
5032 a18e524a bellard
}
5033 a18e524a bellard
5034 a18e524a bellard
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
5035 a18e524a bellard
{
5036 a18e524a bellard
    int i, found;
5037 a18e524a bellard
    WaitObjects *w = &wait_objects;
5038 a18e524a bellard
5039 a18e524a bellard
    found = 0;
5040 a18e524a bellard
    for (i = 0; i < w->num; i++) {
5041 a18e524a bellard
        if (w->events[i] == handle)
5042 a18e524a bellard
            found = 1;
5043 a18e524a bellard
        if (found) {
5044 a18e524a bellard
            w->events[i] = w->events[i + 1];
5045 a18e524a bellard
            w->func[i] = w->func[i + 1];
5046 a18e524a bellard
            w->opaque[i] = w->opaque[i + 1];
5047 a18e524a bellard
        }            
5048 a18e524a bellard
    }
5049 a18e524a bellard
    if (found)
5050 a18e524a bellard
        w->num--;
5051 a18e524a bellard
}
5052 a18e524a bellard
#endif
5053 a18e524a bellard
5054 f331110f bellard
/***********************************************************/
5055 8a7ddc38 bellard
/* savevm/loadvm support */
5056 8a7ddc38 bellard
5057 faea38e7 bellard
#define IO_BUF_SIZE 32768
5058 faea38e7 bellard
5059 faea38e7 bellard
struct QEMUFile {
5060 faea38e7 bellard
    FILE *outfile;
5061 faea38e7 bellard
    BlockDriverState *bs;
5062 faea38e7 bellard
    int is_file;
5063 faea38e7 bellard
    int is_writable;
5064 faea38e7 bellard
    int64_t base_offset;
5065 faea38e7 bellard
    int64_t buf_offset; /* start of buffer when writing, end of buffer
5066 faea38e7 bellard
                           when reading */
5067 faea38e7 bellard
    int buf_index;
5068 faea38e7 bellard
    int buf_size; /* 0 when writing */
5069 faea38e7 bellard
    uint8_t buf[IO_BUF_SIZE];
5070 faea38e7 bellard
};
5071 faea38e7 bellard
5072 faea38e7 bellard
QEMUFile *qemu_fopen(const char *filename, const char *mode)
5073 faea38e7 bellard
{
5074 faea38e7 bellard
    QEMUFile *f;
5075 faea38e7 bellard
5076 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5077 faea38e7 bellard
    if (!f)
5078 faea38e7 bellard
        return NULL;
5079 faea38e7 bellard
    if (!strcmp(mode, "wb")) {
5080 faea38e7 bellard
        f->is_writable = 1;
5081 faea38e7 bellard
    } else if (!strcmp(mode, "rb")) {
5082 faea38e7 bellard
        f->is_writable = 0;
5083 faea38e7 bellard
    } else {
5084 faea38e7 bellard
        goto fail;
5085 faea38e7 bellard
    }
5086 faea38e7 bellard
    f->outfile = fopen(filename, mode);
5087 faea38e7 bellard
    if (!f->outfile)
5088 faea38e7 bellard
        goto fail;
5089 faea38e7 bellard
    f->is_file = 1;
5090 faea38e7 bellard
    return f;
5091 faea38e7 bellard
 fail:
5092 faea38e7 bellard
    if (f->outfile)
5093 faea38e7 bellard
        fclose(f->outfile);
5094 faea38e7 bellard
    qemu_free(f);
5095 faea38e7 bellard
    return NULL;
5096 faea38e7 bellard
}
5097 faea38e7 bellard
5098 faea38e7 bellard
QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
5099 faea38e7 bellard
{
5100 faea38e7 bellard
    QEMUFile *f;
5101 faea38e7 bellard
5102 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
5103 faea38e7 bellard
    if (!f)
5104 faea38e7 bellard
        return NULL;
5105 faea38e7 bellard
    f->is_file = 0;
5106 faea38e7 bellard
    f->bs = bs;
5107 faea38e7 bellard
    f->is_writable = is_writable;
5108 faea38e7 bellard
    f->base_offset = offset;
5109 faea38e7 bellard
    return f;
5110 faea38e7 bellard
}
5111 faea38e7 bellard
5112 faea38e7 bellard
void qemu_fflush(QEMUFile *f)
5113 faea38e7 bellard
{
5114 faea38e7 bellard
    if (!f->is_writable)
5115 faea38e7 bellard
        return;
5116 faea38e7 bellard
    if (f->buf_index > 0) {
5117 faea38e7 bellard
        if (f->is_file) {
5118 faea38e7 bellard
            fseek(f->outfile, f->buf_offset, SEEK_SET);
5119 faea38e7 bellard
            fwrite(f->buf, 1, f->buf_index, f->outfile);
5120 faea38e7 bellard
        } else {
5121 faea38e7 bellard
            bdrv_pwrite(f->bs, f->base_offset + f->buf_offset, 
5122 faea38e7 bellard
                        f->buf, f->buf_index);
5123 faea38e7 bellard
        }
5124 faea38e7 bellard
        f->buf_offset += f->buf_index;
5125 faea38e7 bellard
        f->buf_index = 0;
5126 faea38e7 bellard
    }
5127 faea38e7 bellard
}
5128 faea38e7 bellard
5129 faea38e7 bellard
static void qemu_fill_buffer(QEMUFile *f)
5130 faea38e7 bellard
{
5131 faea38e7 bellard
    int len;
5132 faea38e7 bellard
5133 faea38e7 bellard
    if (f->is_writable)
5134 faea38e7 bellard
        return;
5135 faea38e7 bellard
    if (f->is_file) {
5136 faea38e7 bellard
        fseek(f->outfile, f->buf_offset, SEEK_SET);
5137 faea38e7 bellard
        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
5138 faea38e7 bellard
        if (len < 0)
5139 faea38e7 bellard
            len = 0;
5140 faea38e7 bellard
    } else {
5141 faea38e7 bellard
        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset, 
5142 faea38e7 bellard
                         f->buf, IO_BUF_SIZE);
5143 faea38e7 bellard
        if (len < 0)
5144 faea38e7 bellard
            len = 0;
5145 faea38e7 bellard
    }
5146 faea38e7 bellard
    f->buf_index = 0;
5147 faea38e7 bellard
    f->buf_size = len;
5148 faea38e7 bellard
    f->buf_offset += len;
5149 faea38e7 bellard
}
5150 faea38e7 bellard
5151 faea38e7 bellard
void qemu_fclose(QEMUFile *f)
5152 faea38e7 bellard
{
5153 faea38e7 bellard
    if (f->is_writable)
5154 faea38e7 bellard
        qemu_fflush(f);
5155 faea38e7 bellard
    if (f->is_file) {
5156 faea38e7 bellard
        fclose(f->outfile);
5157 faea38e7 bellard
    }
5158 faea38e7 bellard
    qemu_free(f);
5159 faea38e7 bellard
}
5160 faea38e7 bellard
5161 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
5162 b4608c04 bellard
{
5163 faea38e7 bellard
    int l;
5164 faea38e7 bellard
    while (size > 0) {
5165 faea38e7 bellard
        l = IO_BUF_SIZE - f->buf_index;
5166 faea38e7 bellard
        if (l > size)
5167 faea38e7 bellard
            l = size;
5168 faea38e7 bellard
        memcpy(f->buf + f->buf_index, buf, l);
5169 faea38e7 bellard
        f->buf_index += l;
5170 faea38e7 bellard
        buf += l;
5171 faea38e7 bellard
        size -= l;
5172 faea38e7 bellard
        if (f->buf_index >= IO_BUF_SIZE)
5173 faea38e7 bellard
            qemu_fflush(f);
5174 faea38e7 bellard
    }
5175 b4608c04 bellard
}
5176 b4608c04 bellard
5177 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
5178 b4608c04 bellard
{
5179 faea38e7 bellard
    f->buf[f->buf_index++] = v;
5180 faea38e7 bellard
    if (f->buf_index >= IO_BUF_SIZE)
5181 faea38e7 bellard
        qemu_fflush(f);
5182 faea38e7 bellard
}
5183 faea38e7 bellard
5184 faea38e7 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
5185 faea38e7 bellard
{
5186 faea38e7 bellard
    int size, l;
5187 faea38e7 bellard
5188 faea38e7 bellard
    size = size1;
5189 faea38e7 bellard
    while (size > 0) {
5190 faea38e7 bellard
        l = f->buf_size - f->buf_index;
5191 faea38e7 bellard
        if (l == 0) {
5192 faea38e7 bellard
            qemu_fill_buffer(f);
5193 faea38e7 bellard
            l = f->buf_size - f->buf_index;
5194 faea38e7 bellard
            if (l == 0)
5195 faea38e7 bellard
                break;
5196 faea38e7 bellard
        }
5197 faea38e7 bellard
        if (l > size)
5198 faea38e7 bellard
            l = size;
5199 faea38e7 bellard
        memcpy(buf, f->buf + f->buf_index, l);
5200 faea38e7 bellard
        f->buf_index += l;
5201 faea38e7 bellard
        buf += l;
5202 faea38e7 bellard
        size -= l;
5203 faea38e7 bellard
    }
5204 faea38e7 bellard
    return size1 - size;
5205 faea38e7 bellard
}
5206 faea38e7 bellard
5207 faea38e7 bellard
int qemu_get_byte(QEMUFile *f)
5208 faea38e7 bellard
{
5209 faea38e7 bellard
    if (f->buf_index >= f->buf_size) {
5210 faea38e7 bellard
        qemu_fill_buffer(f);
5211 faea38e7 bellard
        if (f->buf_index >= f->buf_size)
5212 faea38e7 bellard
            return 0;
5213 faea38e7 bellard
    }
5214 faea38e7 bellard
    return f->buf[f->buf_index++];
5215 faea38e7 bellard
}
5216 faea38e7 bellard
5217 faea38e7 bellard
int64_t qemu_ftell(QEMUFile *f)
5218 faea38e7 bellard
{
5219 faea38e7 bellard
    return f->buf_offset - f->buf_size + f->buf_index;
5220 faea38e7 bellard
}
5221 faea38e7 bellard
5222 faea38e7 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
5223 faea38e7 bellard
{
5224 faea38e7 bellard
    if (whence == SEEK_SET) {
5225 faea38e7 bellard
        /* nothing to do */
5226 faea38e7 bellard
    } else if (whence == SEEK_CUR) {
5227 faea38e7 bellard
        pos += qemu_ftell(f);
5228 faea38e7 bellard
    } else {
5229 faea38e7 bellard
        /* SEEK_END not supported */
5230 faea38e7 bellard
        return -1;
5231 faea38e7 bellard
    }
5232 faea38e7 bellard
    if (f->is_writable) {
5233 faea38e7 bellard
        qemu_fflush(f);
5234 faea38e7 bellard
        f->buf_offset = pos;
5235 faea38e7 bellard
    } else {
5236 faea38e7 bellard
        f->buf_offset = pos;
5237 faea38e7 bellard
        f->buf_index = 0;
5238 faea38e7 bellard
        f->buf_size = 0;
5239 faea38e7 bellard
    }
5240 faea38e7 bellard
    return pos;
5241 8a7ddc38 bellard
}
5242 8a7ddc38 bellard
5243 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
5244 8a7ddc38 bellard
{
5245 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5246 8a7ddc38 bellard
    qemu_put_byte(f, v);
5247 8a7ddc38 bellard
}
5248 8a7ddc38 bellard
5249 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
5250 8a7ddc38 bellard
{
5251 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
5252 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
5253 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
5254 8a7ddc38 bellard
    qemu_put_byte(f, v);
5255 8a7ddc38 bellard
}
5256 8a7ddc38 bellard
5257 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
5258 8a7ddc38 bellard
{
5259 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
5260 8a7ddc38 bellard
    qemu_put_be32(f, v);
5261 8a7ddc38 bellard
}
5262 8a7ddc38 bellard
5263 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
5264 8a7ddc38 bellard
{
5265 8a7ddc38 bellard
    unsigned int v;
5266 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
5267 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5268 8a7ddc38 bellard
    return v;
5269 8a7ddc38 bellard
}
5270 8a7ddc38 bellard
5271 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
5272 8a7ddc38 bellard
{
5273 8a7ddc38 bellard
    unsigned int v;
5274 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
5275 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
5276 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
5277 8a7ddc38 bellard
    v |= qemu_get_byte(f);
5278 8a7ddc38 bellard
    return v;
5279 8a7ddc38 bellard
}
5280 8a7ddc38 bellard
5281 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
5282 8a7ddc38 bellard
{
5283 8a7ddc38 bellard
    uint64_t v;
5284 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
5285 8a7ddc38 bellard
    v |= qemu_get_be32(f);
5286 8a7ddc38 bellard
    return v;
5287 8a7ddc38 bellard
}
5288 8a7ddc38 bellard
5289 8a7ddc38 bellard
typedef struct SaveStateEntry {
5290 8a7ddc38 bellard
    char idstr[256];
5291 8a7ddc38 bellard
    int instance_id;
5292 8a7ddc38 bellard
    int version_id;
5293 8a7ddc38 bellard
    SaveStateHandler *save_state;
5294 8a7ddc38 bellard
    LoadStateHandler *load_state;
5295 8a7ddc38 bellard
    void *opaque;
5296 8a7ddc38 bellard
    struct SaveStateEntry *next;
5297 8a7ddc38 bellard
} SaveStateEntry;
5298 b4608c04 bellard
5299 8a7ddc38 bellard
static SaveStateEntry *first_se;
5300 8a7ddc38 bellard
5301 8a7ddc38 bellard
int register_savevm(const char *idstr, 
5302 8a7ddc38 bellard
                    int instance_id, 
5303 8a7ddc38 bellard
                    int version_id,
5304 8a7ddc38 bellard
                    SaveStateHandler *save_state,
5305 8a7ddc38 bellard
                    LoadStateHandler *load_state,
5306 8a7ddc38 bellard
                    void *opaque)
5307 8a7ddc38 bellard
{
5308 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
5309 8a7ddc38 bellard
5310 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
5311 8a7ddc38 bellard
    if (!se)
5312 8a7ddc38 bellard
        return -1;
5313 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
5314 8a7ddc38 bellard
    se->instance_id = instance_id;
5315 8a7ddc38 bellard
    se->version_id = version_id;
5316 8a7ddc38 bellard
    se->save_state = save_state;
5317 8a7ddc38 bellard
    se->load_state = load_state;
5318 8a7ddc38 bellard
    se->opaque = opaque;
5319 8a7ddc38 bellard
    se->next = NULL;
5320 8a7ddc38 bellard
5321 8a7ddc38 bellard
    /* add at the end of list */
5322 8a7ddc38 bellard
    pse = &first_se;
5323 8a7ddc38 bellard
    while (*pse != NULL)
5324 8a7ddc38 bellard
        pse = &(*pse)->next;
5325 8a7ddc38 bellard
    *pse = se;
5326 8a7ddc38 bellard
    return 0;
5327 8a7ddc38 bellard
}
5328 8a7ddc38 bellard
5329 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
5330 faea38e7 bellard
#define QEMU_VM_FILE_VERSION 0x00000002
5331 8a7ddc38 bellard
5332 faea38e7 bellard
int qemu_savevm_state(QEMUFile *f)
5333 8a7ddc38 bellard
{
5334 8a7ddc38 bellard
    SaveStateEntry *se;
5335 faea38e7 bellard
    int len, ret;
5336 faea38e7 bellard
    int64_t cur_pos, len_pos, total_len_pos;
5337 313aa567 bellard
5338 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
5339 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
5340 faea38e7 bellard
    total_len_pos = qemu_ftell(f);
5341 faea38e7 bellard
    qemu_put_be64(f, 0); /* total size */
5342 8a7ddc38 bellard
5343 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5344 8a7ddc38 bellard
        /* ID string */
5345 8a7ddc38 bellard
        len = strlen(se->idstr);
5346 8a7ddc38 bellard
        qemu_put_byte(f, len);
5347 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
5348 8a7ddc38 bellard
5349 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
5350 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
5351 8a7ddc38 bellard
5352 8a7ddc38 bellard
        /* record size: filled later */
5353 faea38e7 bellard
        len_pos = qemu_ftell(f);
5354 8a7ddc38 bellard
        qemu_put_be32(f, 0);
5355 8a7ddc38 bellard
        
5356 8a7ddc38 bellard
        se->save_state(f, se->opaque);
5357 8a7ddc38 bellard
5358 8a7ddc38 bellard
        /* fill record size */
5359 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5360 faea38e7 bellard
        len = cur_pos - len_pos - 4;
5361 faea38e7 bellard
        qemu_fseek(f, len_pos, SEEK_SET);
5362 8a7ddc38 bellard
        qemu_put_be32(f, len);
5363 faea38e7 bellard
        qemu_fseek(f, cur_pos, SEEK_SET);
5364 8a7ddc38 bellard
    }
5365 faea38e7 bellard
    cur_pos = qemu_ftell(f);
5366 faea38e7 bellard
    qemu_fseek(f, total_len_pos, SEEK_SET);
5367 faea38e7 bellard
    qemu_put_be64(f, cur_pos - total_len_pos - 8);
5368 faea38e7 bellard
    qemu_fseek(f, cur_pos, SEEK_SET);
5369 8a7ddc38 bellard
5370 8a7ddc38 bellard
    ret = 0;
5371 8a7ddc38 bellard
    return ret;
5372 8a7ddc38 bellard
}
5373 8a7ddc38 bellard
5374 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
5375 8a7ddc38 bellard
{
5376 8a7ddc38 bellard
    SaveStateEntry *se;
5377 8a7ddc38 bellard
5378 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
5379 8a7ddc38 bellard
        if (!strcmp(se->idstr, idstr) && 
5380 8a7ddc38 bellard
            instance_id == se->instance_id)
5381 8a7ddc38 bellard
            return se;
5382 8a7ddc38 bellard
    }
5383 8a7ddc38 bellard
    return NULL;
5384 8a7ddc38 bellard
}
5385 8a7ddc38 bellard
5386 faea38e7 bellard
int qemu_loadvm_state(QEMUFile *f)
5387 8a7ddc38 bellard
{
5388 8a7ddc38 bellard
    SaveStateEntry *se;
5389 faea38e7 bellard
    int len, ret, instance_id, record_len, version_id;
5390 faea38e7 bellard
    int64_t total_len, end_pos, cur_pos;
5391 8a7ddc38 bellard
    unsigned int v;
5392 8a7ddc38 bellard
    char idstr[256];
5393 8a7ddc38 bellard
    
5394 8a7ddc38 bellard
    v = qemu_get_be32(f);
5395 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
5396 8a7ddc38 bellard
        goto fail;
5397 8a7ddc38 bellard
    v = qemu_get_be32(f);
5398 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
5399 8a7ddc38 bellard
    fail:
5400 8a7ddc38 bellard
        ret = -1;
5401 8a7ddc38 bellard
        goto the_end;
5402 8a7ddc38 bellard
    }
5403 faea38e7 bellard
    total_len = qemu_get_be64(f);
5404 faea38e7 bellard
    end_pos = total_len + qemu_ftell(f);
5405 b4608c04 bellard
    for(;;) {
5406 faea38e7 bellard
        if (qemu_ftell(f) >= end_pos)
5407 cd4c3e88 bellard
            break;
5408 faea38e7 bellard
        len = qemu_get_byte(f);
5409 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
5410 8a7ddc38 bellard
        idstr[len] = '\0';
5411 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
5412 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
5413 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
5414 8a7ddc38 bellard
#if 0
5415 8a7ddc38 bellard
        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
5416 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
5417 8a7ddc38 bellard
#endif
5418 faea38e7 bellard
        cur_pos = qemu_ftell(f);
5419 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
5420 8a7ddc38 bellard
        if (!se) {
5421 8a7ddc38 bellard
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
5422 8a7ddc38 bellard
                    instance_id, idstr);
5423 8a7ddc38 bellard
        } else {
5424 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
5425 8a7ddc38 bellard
            if (ret < 0) {
5426 8a7ddc38 bellard
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
5427 8a7ddc38 bellard
                        instance_id, idstr);
5428 8a7ddc38 bellard
            }
5429 34865134 bellard
        }
5430 8a7ddc38 bellard
        /* always seek to exact end of record */
5431 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
5432 8a7ddc38 bellard
    }
5433 8a7ddc38 bellard
    ret = 0;
5434 8a7ddc38 bellard
 the_end:
5435 faea38e7 bellard
    return ret;
5436 faea38e7 bellard
}
5437 faea38e7 bellard
5438 faea38e7 bellard
/* device can contain snapshots */
5439 faea38e7 bellard
static int bdrv_can_snapshot(BlockDriverState *bs)
5440 faea38e7 bellard
{
5441 faea38e7 bellard
    return (bs &&
5442 faea38e7 bellard
            !bdrv_is_removable(bs) &&
5443 faea38e7 bellard
            !bdrv_is_read_only(bs));
5444 faea38e7 bellard
}
5445 faea38e7 bellard
5446 faea38e7 bellard
/* device must be snapshots in order to have a reliable snapshot */
5447 faea38e7 bellard
static int bdrv_has_snapshot(BlockDriverState *bs)
5448 faea38e7 bellard
{
5449 faea38e7 bellard
    return (bs &&
5450 faea38e7 bellard
            !bdrv_is_removable(bs) &&
5451 faea38e7 bellard
            !bdrv_is_read_only(bs));
5452 faea38e7 bellard
}
5453 faea38e7 bellard
5454 faea38e7 bellard
static BlockDriverState *get_bs_snapshots(void)
5455 faea38e7 bellard
{
5456 faea38e7 bellard
    BlockDriverState *bs;
5457 faea38e7 bellard
    int i;
5458 faea38e7 bellard
5459 faea38e7 bellard
    if (bs_snapshots)
5460 faea38e7 bellard
        return bs_snapshots;
5461 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5462 faea38e7 bellard
        bs = bs_table[i];
5463 faea38e7 bellard
        if (bdrv_can_snapshot(bs))
5464 faea38e7 bellard
            goto ok;
5465 faea38e7 bellard
    }
5466 faea38e7 bellard
    return NULL;
5467 faea38e7 bellard
 ok:
5468 faea38e7 bellard
    bs_snapshots = bs;
5469 faea38e7 bellard
    return bs;
5470 faea38e7 bellard
}
5471 faea38e7 bellard
5472 faea38e7 bellard
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
5473 faea38e7 bellard
                              const char *name)
5474 faea38e7 bellard
{
5475 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5476 faea38e7 bellard
    int nb_sns, i, ret;
5477 faea38e7 bellard
    
5478 faea38e7 bellard
    ret = -ENOENT;
5479 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5480 faea38e7 bellard
    if (nb_sns < 0)
5481 faea38e7 bellard
        return ret;
5482 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5483 faea38e7 bellard
        sn = &sn_tab[i];
5484 faea38e7 bellard
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
5485 faea38e7 bellard
            *sn_info = *sn;
5486 faea38e7 bellard
            ret = 0;
5487 faea38e7 bellard
            break;
5488 faea38e7 bellard
        }
5489 faea38e7 bellard
    }
5490 faea38e7 bellard
    qemu_free(sn_tab);
5491 faea38e7 bellard
    return ret;
5492 faea38e7 bellard
}
5493 faea38e7 bellard
5494 faea38e7 bellard
void do_savevm(const char *name)
5495 faea38e7 bellard
{
5496 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5497 faea38e7 bellard
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
5498 faea38e7 bellard
    int must_delete, ret, i;
5499 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5500 faea38e7 bellard
    QEMUFile *f;
5501 faea38e7 bellard
    int saved_vm_running;
5502 4c279bdf bellard
#ifdef _WIN32
5503 4c279bdf bellard
    struct _timeb tb;
5504 4c279bdf bellard
#else
5505 faea38e7 bellard
    struct timeval tv;
5506 4c279bdf bellard
#endif
5507 faea38e7 bellard
5508 faea38e7 bellard
    bs = get_bs_snapshots();
5509 faea38e7 bellard
    if (!bs) {
5510 faea38e7 bellard
        term_printf("No block device can accept snapshots\n");
5511 faea38e7 bellard
        return;
5512 faea38e7 bellard
    }
5513 faea38e7 bellard
5514 6192bc37 pbrook
    /* ??? Should this occur after vm_stop?  */
5515 6192bc37 pbrook
    qemu_aio_flush();
5516 6192bc37 pbrook
5517 faea38e7 bellard
    saved_vm_running = vm_running;
5518 faea38e7 bellard
    vm_stop(0);
5519 faea38e7 bellard
    
5520 faea38e7 bellard
    must_delete = 0;
5521 faea38e7 bellard
    if (name) {
5522 faea38e7 bellard
        ret = bdrv_snapshot_find(bs, old_sn, name);
5523 faea38e7 bellard
        if (ret >= 0) {
5524 faea38e7 bellard
            must_delete = 1;
5525 faea38e7 bellard
        }
5526 faea38e7 bellard
    }
5527 faea38e7 bellard
    memset(sn, 0, sizeof(*sn));
5528 faea38e7 bellard
    if (must_delete) {
5529 faea38e7 bellard
        pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
5530 faea38e7 bellard
        pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
5531 faea38e7 bellard
    } else {
5532 faea38e7 bellard
        if (name)
5533 faea38e7 bellard
            pstrcpy(sn->name, sizeof(sn->name), name);
5534 faea38e7 bellard
    }
5535 faea38e7 bellard
5536 faea38e7 bellard
    /* fill auxiliary fields */
5537 4c279bdf bellard
#ifdef _WIN32
5538 4c279bdf bellard
    _ftime(&tb);
5539 4c279bdf bellard
    sn->date_sec = tb.time;
5540 4c279bdf bellard
    sn->date_nsec = tb.millitm * 1000000;
5541 4c279bdf bellard
#else
5542 faea38e7 bellard
    gettimeofday(&tv, NULL);
5543 faea38e7 bellard
    sn->date_sec = tv.tv_sec;
5544 faea38e7 bellard
    sn->date_nsec = tv.tv_usec * 1000;
5545 4c279bdf bellard
#endif
5546 faea38e7 bellard
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
5547 faea38e7 bellard
    
5548 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5549 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5550 faea38e7 bellard
                    bdrv_get_device_name(bs));
5551 faea38e7 bellard
        goto the_end;
5552 faea38e7 bellard
    }
5553 faea38e7 bellard
    
5554 faea38e7 bellard
    /* save the VM state */
5555 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
5556 faea38e7 bellard
    if (!f) {
5557 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5558 faea38e7 bellard
        goto the_end;
5559 faea38e7 bellard
    }
5560 faea38e7 bellard
    ret = qemu_savevm_state(f);
5561 faea38e7 bellard
    sn->vm_state_size = qemu_ftell(f);
5562 faea38e7 bellard
    qemu_fclose(f);
5563 faea38e7 bellard
    if (ret < 0) {
5564 faea38e7 bellard
        term_printf("Error %d while writing VM\n", ret);
5565 faea38e7 bellard
        goto the_end;
5566 faea38e7 bellard
    }
5567 faea38e7 bellard
    
5568 faea38e7 bellard
    /* create the snapshots */
5569 faea38e7 bellard
5570 faea38e7 bellard
    for(i = 0; i < MAX_DISKS; i++) {
5571 faea38e7 bellard
        bs1 = bs_table[i];
5572 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5573 faea38e7 bellard
            if (must_delete) {
5574 faea38e7 bellard
                ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
5575 faea38e7 bellard
                if (ret < 0) {
5576 faea38e7 bellard
                    term_printf("Error while deleting snapshot on '%s'\n",
5577 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5578 faea38e7 bellard
                }
5579 faea38e7 bellard
            }
5580 faea38e7 bellard
            ret = bdrv_snapshot_create(bs1, sn);
5581 faea38e7 bellard
            if (ret < 0) {
5582 faea38e7 bellard
                term_printf("Error while creating snapshot on '%s'\n",
5583 faea38e7 bellard
                            bdrv_get_device_name(bs1));
5584 faea38e7 bellard
            }
5585 faea38e7 bellard
        }
5586 faea38e7 bellard
    }
5587 faea38e7 bellard
5588 faea38e7 bellard
 the_end:
5589 8a7ddc38 bellard
    if (saved_vm_running)
5590 8a7ddc38 bellard
        vm_start();
5591 faea38e7 bellard
}
5592 faea38e7 bellard
5593 faea38e7 bellard
void do_loadvm(const char *name)
5594 faea38e7 bellard
{
5595 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5596 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5597 faea38e7 bellard
    QEMUFile *f;
5598 faea38e7 bellard
    int i, ret;
5599 faea38e7 bellard
    int saved_vm_running;
5600 faea38e7 bellard
5601 faea38e7 bellard
    bs = get_bs_snapshots();
5602 faea38e7 bellard
    if (!bs) {
5603 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5604 faea38e7 bellard
        return;
5605 faea38e7 bellard
    }
5606 faea38e7 bellard
    
5607 6192bc37 pbrook
    /* Flush all IO requests so they don't interfere with the new state.  */
5608 6192bc37 pbrook
    qemu_aio_flush();
5609 6192bc37 pbrook
5610 faea38e7 bellard
    saved_vm_running = vm_running;
5611 faea38e7 bellard
    vm_stop(0);
5612 faea38e7 bellard
5613 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5614 faea38e7 bellard
        bs1 = bs_table[i];
5615 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5616 faea38e7 bellard
            ret = bdrv_snapshot_goto(bs1, name);
5617 faea38e7 bellard
            if (ret < 0) {
5618 faea38e7 bellard
                if (bs != bs1)
5619 faea38e7 bellard
                    term_printf("Warning: ");
5620 faea38e7 bellard
                switch(ret) {
5621 faea38e7 bellard
                case -ENOTSUP:
5622 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5623 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5624 faea38e7 bellard
                    break;
5625 faea38e7 bellard
                case -ENOENT:
5626 faea38e7 bellard
                    term_printf("Could not find snapshot '%s' on device '%s'\n",
5627 faea38e7 bellard
                                name, bdrv_get_device_name(bs1));
5628 faea38e7 bellard
                    break;
5629 faea38e7 bellard
                default:
5630 faea38e7 bellard
                    term_printf("Error %d while activating snapshot on '%s'\n",
5631 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5632 faea38e7 bellard
                    break;
5633 faea38e7 bellard
                }
5634 faea38e7 bellard
                /* fatal on snapshot block device */
5635 faea38e7 bellard
                if (bs == bs1)
5636 faea38e7 bellard
                    goto the_end;
5637 faea38e7 bellard
            }
5638 faea38e7 bellard
        }
5639 faea38e7 bellard
    }
5640 faea38e7 bellard
5641 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5642 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5643 faea38e7 bellard
                    bdrv_get_device_name(bs));
5644 faea38e7 bellard
        return;
5645 faea38e7 bellard
    }
5646 faea38e7 bellard
    
5647 faea38e7 bellard
    /* restore the VM state */
5648 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
5649 faea38e7 bellard
    if (!f) {
5650 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5651 faea38e7 bellard
        goto the_end;
5652 faea38e7 bellard
    }
5653 faea38e7 bellard
    ret = qemu_loadvm_state(f);
5654 faea38e7 bellard
    qemu_fclose(f);
5655 faea38e7 bellard
    if (ret < 0) {
5656 faea38e7 bellard
        term_printf("Error %d while loading VM state\n", ret);
5657 faea38e7 bellard
    }
5658 faea38e7 bellard
 the_end:
5659 faea38e7 bellard
    if (saved_vm_running)
5660 faea38e7 bellard
        vm_start();
5661 faea38e7 bellard
}
5662 faea38e7 bellard
5663 faea38e7 bellard
void do_delvm(const char *name)
5664 faea38e7 bellard
{
5665 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5666 faea38e7 bellard
    int i, ret;
5667 faea38e7 bellard
5668 faea38e7 bellard
    bs = get_bs_snapshots();
5669 faea38e7 bellard
    if (!bs) {
5670 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5671 faea38e7 bellard
        return;
5672 faea38e7 bellard
    }
5673 faea38e7 bellard
    
5674 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5675 faea38e7 bellard
        bs1 = bs_table[i];
5676 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5677 faea38e7 bellard
            ret = bdrv_snapshot_delete(bs1, name);
5678 faea38e7 bellard
            if (ret < 0) {
5679 faea38e7 bellard
                if (ret == -ENOTSUP)
5680 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5681 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5682 faea38e7 bellard
                else
5683 faea38e7 bellard
                    term_printf("Error %d while deleting snapshot on '%s'\n",
5684 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5685 faea38e7 bellard
            }
5686 faea38e7 bellard
        }
5687 faea38e7 bellard
    }
5688 faea38e7 bellard
}
5689 faea38e7 bellard
5690 faea38e7 bellard
void do_info_snapshots(void)
5691 faea38e7 bellard
{
5692 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5693 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5694 faea38e7 bellard
    int nb_sns, i;
5695 faea38e7 bellard
    char buf[256];
5696 faea38e7 bellard
5697 faea38e7 bellard
    bs = get_bs_snapshots();
5698 faea38e7 bellard
    if (!bs) {
5699 faea38e7 bellard
        term_printf("No available block device supports snapshots\n");
5700 faea38e7 bellard
        return;
5701 faea38e7 bellard
    }
5702 faea38e7 bellard
    term_printf("Snapshot devices:");
5703 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5704 faea38e7 bellard
        bs1 = bs_table[i];
5705 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5706 faea38e7 bellard
            if (bs == bs1)
5707 faea38e7 bellard
                term_printf(" %s", bdrv_get_device_name(bs1));
5708 faea38e7 bellard
        }
5709 faea38e7 bellard
    }
5710 faea38e7 bellard
    term_printf("\n");
5711 faea38e7 bellard
5712 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5713 faea38e7 bellard
    if (nb_sns < 0) {
5714 faea38e7 bellard
        term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
5715 faea38e7 bellard
        return;
5716 faea38e7 bellard
    }
5717 faea38e7 bellard
    term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
5718 faea38e7 bellard
    term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
5719 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5720 faea38e7 bellard
        sn = &sn_tab[i];
5721 faea38e7 bellard
        term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
5722 faea38e7 bellard
    }
5723 faea38e7 bellard
    qemu_free(sn_tab);
5724 8a7ddc38 bellard
}
5725 8a7ddc38 bellard
5726 8a7ddc38 bellard
/***********************************************************/
5727 8a7ddc38 bellard
/* cpu save/restore */
5728 8a7ddc38 bellard
5729 8a7ddc38 bellard
#if defined(TARGET_I386)
5730 8a7ddc38 bellard
5731 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
5732 8a7ddc38 bellard
{
5733 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
5734 20f32282 bellard
    qemu_put_betl(f, dt->base);
5735 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
5736 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
5737 8a7ddc38 bellard
}
5738 8a7ddc38 bellard
5739 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
5740 8a7ddc38 bellard
{
5741 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
5742 20f32282 bellard
    dt->base = qemu_get_betl(f);
5743 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
5744 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
5745 8a7ddc38 bellard
}
5746 8a7ddc38 bellard
5747 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
5748 8a7ddc38 bellard
{
5749 8a7ddc38 bellard
    CPUState *env = opaque;
5750 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
5751 8a7ddc38 bellard
    uint32_t hflags;
5752 8a7ddc38 bellard
    int i;
5753 664e0f19 bellard
    
5754 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5755 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
5756 20f32282 bellard
    qemu_put_betls(f, &env->eip);
5757 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
5758 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
5759 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
5760 8a7ddc38 bellard
    
5761 8a7ddc38 bellard
    /* FPU */
5762 8a7ddc38 bellard
    fpuc = env->fpuc;
5763 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
5764 8a7ddc38 bellard
    fptag = 0;
5765 664e0f19 bellard
    for(i = 0; i < 8; i++) {
5766 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
5767 8a7ddc38 bellard
    }
5768 8a7ddc38 bellard
    
5769 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
5770 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
5771 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
5772 8a7ddc38 bellard
5773 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5774 664e0f19 bellard
    fpregs_format = 0;
5775 664e0f19 bellard
#else
5776 664e0f19 bellard
    fpregs_format = 1;
5777 664e0f19 bellard
#endif
5778 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
5779 664e0f19 bellard
    
5780 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5781 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5782 8636b5d8 bellard
        {
5783 8636b5d8 bellard
            uint64_t mant;
5784 8636b5d8 bellard
            uint16_t exp;
5785 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
5786 8636b5d8 bellard
               contains the MMX register */
5787 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
5788 8636b5d8 bellard
            qemu_put_be64(f, mant);
5789 8636b5d8 bellard
            qemu_put_be16(f, exp);
5790 8636b5d8 bellard
        }
5791 664e0f19 bellard
#else
5792 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
5793 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
5794 664e0f19 bellard
           problems if the image is restored on a CPU where long
5795 664e0f19 bellard
           doubles are used instead. */
5796 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
5797 664e0f19 bellard
#endif
5798 8a7ddc38 bellard
    }
5799 8a7ddc38 bellard
5800 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5801 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
5802 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
5803 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
5804 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
5805 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
5806 8a7ddc38 bellard
    
5807 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
5808 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
5809 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
5810 8a7ddc38 bellard
    
5811 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
5812 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
5813 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
5814 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
5815 8a7ddc38 bellard
    
5816 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5817 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
5818 8a7ddc38 bellard
5819 8a7ddc38 bellard
    /* MMU */
5820 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
5821 02536f8b bellard
5822 664e0f19 bellard
    /* XMM */
5823 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
5824 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5825 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5826 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5827 02536f8b bellard
    }
5828 02536f8b bellard
5829 664e0f19 bellard
#ifdef TARGET_X86_64
5830 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
5831 02536f8b bellard
    qemu_put_be64s(f, &env->star);
5832 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
5833 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
5834 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
5835 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
5836 02536f8b bellard
#endif
5837 3b21e03e bellard
    qemu_put_be32s(f, &env->smbase);
5838 8a7ddc38 bellard
}
5839 8a7ddc38 bellard
5840 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
5841 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
5842 664e0f19 bellard
union x86_longdouble {
5843 664e0f19 bellard
    uint64_t mant;
5844 664e0f19 bellard
    uint16_t exp;
5845 664e0f19 bellard
};
5846 664e0f19 bellard
5847 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
5848 664e0f19 bellard
#define EXPBIAS1 1023
5849 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
5850 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
5851 664e0f19 bellard
5852 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
5853 664e0f19 bellard
{
5854 664e0f19 bellard
    int e;
5855 664e0f19 bellard
    /* mantissa */
5856 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
5857 664e0f19 bellard
    /* exponent + sign */
5858 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
5859 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
5860 664e0f19 bellard
    p->exp = e;
5861 664e0f19 bellard
}
5862 8636b5d8 bellard
#endif
5863 664e0f19 bellard
5864 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5865 8a7ddc38 bellard
{
5866 8a7ddc38 bellard
    CPUState *env = opaque;
5867 664e0f19 bellard
    int i, guess_mmx;
5868 8a7ddc38 bellard
    uint32_t hflags;
5869 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
5870 8a7ddc38 bellard
5871 3b21e03e bellard
    if (version_id != 3 && version_id != 4)
5872 8a7ddc38 bellard
        return -EINVAL;
5873 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5874 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
5875 20f32282 bellard
    qemu_get_betls(f, &env->eip);
5876 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
5877 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
5878 8a7ddc38 bellard
5879 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
5880 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
5881 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
5882 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
5883 664e0f19 bellard
    
5884 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
5885 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
5886 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
5887 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
5888 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5889 8a7ddc38 bellard
        uint64_t mant;
5890 8a7ddc38 bellard
        uint16_t exp;
5891 664e0f19 bellard
        
5892 664e0f19 bellard
        switch(fpregs_format) {
5893 664e0f19 bellard
        case 0:
5894 664e0f19 bellard
            mant = qemu_get_be64(f);
5895 664e0f19 bellard
            exp = qemu_get_be16(f);
5896 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5897 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
5898 664e0f19 bellard
#else
5899 664e0f19 bellard
            /* difficult case */
5900 664e0f19 bellard
            if (guess_mmx)
5901 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
5902 664e0f19 bellard
            else
5903 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
5904 664e0f19 bellard
#endif
5905 664e0f19 bellard
            break;
5906 664e0f19 bellard
        case 1:
5907 664e0f19 bellard
            mant = qemu_get_be64(f);
5908 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5909 8636b5d8 bellard
            {
5910 8636b5d8 bellard
                union x86_longdouble *p;
5911 8636b5d8 bellard
                /* difficult case */
5912 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
5913 8636b5d8 bellard
                if (guess_mmx) {
5914 8636b5d8 bellard
                    p->mant = mant;
5915 8636b5d8 bellard
                    p->exp = 0xffff;
5916 8636b5d8 bellard
                } else {
5917 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
5918 8636b5d8 bellard
                }
5919 664e0f19 bellard
            }
5920 664e0f19 bellard
#else
5921 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
5922 664e0f19 bellard
#endif            
5923 664e0f19 bellard
            break;
5924 664e0f19 bellard
        default:
5925 664e0f19 bellard
            return -EINVAL;
5926 664e0f19 bellard
        }
5927 8a7ddc38 bellard
    }
5928 8a7ddc38 bellard
5929 8a7ddc38 bellard
    env->fpuc = fpuc;
5930 7a0e1f41 bellard
    /* XXX: restore FPU round state */
5931 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
5932 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
5933 664e0f19 bellard
    fptag ^= 0xff;
5934 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5935 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
5936 8a7ddc38 bellard
    }
5937 8a7ddc38 bellard
    
5938 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5939 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
5940 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
5941 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
5942 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
5943 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
5944 8a7ddc38 bellard
    
5945 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
5946 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
5947 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
5948 8a7ddc38 bellard
    
5949 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
5950 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
5951 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
5952 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
5953 8a7ddc38 bellard
    
5954 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5955 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
5956 8a7ddc38 bellard
5957 8a7ddc38 bellard
    /* MMU */
5958 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
5959 8a7ddc38 bellard
5960 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
5961 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5962 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5963 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5964 02536f8b bellard
    }
5965 02536f8b bellard
5966 664e0f19 bellard
#ifdef TARGET_X86_64
5967 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
5968 02536f8b bellard
    qemu_get_be64s(f, &env->star);
5969 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
5970 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
5971 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
5972 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
5973 02536f8b bellard
#endif
5974 3b21e03e bellard
    if (version_id >= 4) 
5975 3b21e03e bellard
        qemu_get_be32s(f, &env->smbase);
5976 02536f8b bellard
5977 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
5978 8a7ddc38 bellard
    env->hflags = hflags;
5979 8a7ddc38 bellard
    tlb_flush(env, 1);
5980 8a7ddc38 bellard
    return 0;
5981 8a7ddc38 bellard
}
5982 8a7ddc38 bellard
5983 a541f297 bellard
#elif defined(TARGET_PPC)
5984 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
5985 a541f297 bellard
{
5986 a541f297 bellard
}
5987 a541f297 bellard
5988 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5989 a541f297 bellard
{
5990 a541f297 bellard
    return 0;
5991 a541f297 bellard
}
5992 6af0bf9c bellard
5993 6af0bf9c bellard
#elif defined(TARGET_MIPS)
5994 6af0bf9c bellard
void cpu_save(QEMUFile *f, void *opaque)
5995 6af0bf9c bellard
{
5996 6af0bf9c bellard
}
5997 6af0bf9c bellard
5998 6af0bf9c bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5999 6af0bf9c bellard
{
6000 6af0bf9c bellard
    return 0;
6001 6af0bf9c bellard
}
6002 6af0bf9c bellard
6003 e95c8d51 bellard
#elif defined(TARGET_SPARC)
6004 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
6005 e95c8d51 bellard
{
6006 e80cfcfc bellard
    CPUState *env = opaque;
6007 e80cfcfc bellard
    int i;
6008 e80cfcfc bellard
    uint32_t tmp;
6009 e80cfcfc bellard
6010 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6011 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
6012 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6013 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
6014 e80cfcfc bellard
6015 e80cfcfc bellard
    /* FPU */
6016 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6017 4fa5d772 bellard
        union {
6018 1bdb68ea bellard
            float32 f;
6019 1bdb68ea bellard
            uint32_t i;
6020 4fa5d772 bellard
        } u;
6021 4fa5d772 bellard
        u.f = env->fpr[i];
6022 1bdb68ea bellard
        qemu_put_be32(f, u.i);
6023 4fa5d772 bellard
    }
6024 4fa5d772 bellard
6025 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
6026 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
6027 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
6028 e80cfcfc bellard
    tmp = GET_PSR(env);
6029 4fa5d772 bellard
    qemu_put_be32(f, tmp);
6030 3475187d bellard
    qemu_put_betls(f, &env->fsr);
6031 3475187d bellard
    qemu_put_betls(f, &env->tbr);
6032 3475187d bellard
#ifndef TARGET_SPARC64
6033 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
6034 e80cfcfc bellard
    /* MMU */
6035 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6036 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
6037 3475187d bellard
#endif
6038 e95c8d51 bellard
}
6039 e95c8d51 bellard
6040 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6041 e95c8d51 bellard
{
6042 e80cfcfc bellard
    CPUState *env = opaque;
6043 e80cfcfc bellard
    int i;
6044 e80cfcfc bellard
    uint32_t tmp;
6045 e80cfcfc bellard
6046 4fa5d772 bellard
    for(i = 0; i < 8; i++)
6047 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
6048 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
6049 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
6050 e80cfcfc bellard
6051 e80cfcfc bellard
    /* FPU */
6052 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
6053 4fa5d772 bellard
        union {
6054 1bdb68ea bellard
            float32 f;
6055 1bdb68ea bellard
            uint32_t i;
6056 4fa5d772 bellard
        } u;
6057 1bdb68ea bellard
        u.i = qemu_get_be32(f);
6058 4fa5d772 bellard
        env->fpr[i] = u.f;
6059 4fa5d772 bellard
    }
6060 4fa5d772 bellard
6061 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
6062 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
6063 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
6064 4fa5d772 bellard
    tmp = qemu_get_be32(f);
6065 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
6066 4fa5d772 bellard
                     correctly updated */
6067 e80cfcfc bellard
    PUT_PSR(env, tmp);
6068 3475187d bellard
    qemu_get_betls(f, &env->fsr);
6069 3475187d bellard
    qemu_get_betls(f, &env->tbr);
6070 3475187d bellard
#ifndef TARGET_SPARC64
6071 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
6072 e80cfcfc bellard
    /* MMU */
6073 e80cfcfc bellard
    for(i = 0; i < 16; i++)
6074 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
6075 3475187d bellard
#endif
6076 e80cfcfc bellard
    tlb_flush(env, 1);
6077 e95c8d51 bellard
    return 0;
6078 e95c8d51 bellard
}
6079 b5ff1b31 bellard
6080 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6081 b5ff1b31 bellard
6082 b5ff1b31 bellard
void cpu_save(QEMUFile *f, void *opaque)
6083 b5ff1b31 bellard
{
6084 aa941b94 balrog
    int i;
6085 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6086 aa941b94 balrog
6087 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6088 aa941b94 balrog
        qemu_put_be32(f, env->regs[i]);
6089 aa941b94 balrog
    }
6090 aa941b94 balrog
    qemu_put_be32(f, cpsr_read(env));
6091 aa941b94 balrog
    qemu_put_be32(f, env->spsr);
6092 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6093 aa941b94 balrog
        qemu_put_be32(f, env->banked_spsr[i]);
6094 aa941b94 balrog
        qemu_put_be32(f, env->banked_r13[i]);
6095 aa941b94 balrog
        qemu_put_be32(f, env->banked_r14[i]);
6096 aa941b94 balrog
    }
6097 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6098 aa941b94 balrog
        qemu_put_be32(f, env->usr_regs[i]);
6099 aa941b94 balrog
        qemu_put_be32(f, env->fiq_regs[i]);
6100 aa941b94 balrog
    }
6101 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cpuid);
6102 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c0_cachetype);
6103 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_sys);
6104 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c1_coproc);
6105 610c3c8a balrog
    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
6106 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_base);
6107 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_data);
6108 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c2_insn);
6109 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c3);
6110 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_insn);
6111 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c5_data);
6112 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6113 aa941b94 balrog
        qemu_put_be32(f, env->cp15.c6_region[i]);
6114 aa941b94 balrog
    }
6115 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_insn);
6116 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c6_data);
6117 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_insn);
6118 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c9_data);
6119 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_fcse);
6120 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c13_context);
6121 aa941b94 balrog
    qemu_put_be32(f, env->cp15.c15_cpar);
6122 aa941b94 balrog
6123 aa941b94 balrog
    qemu_put_be32(f, env->features);
6124 aa941b94 balrog
6125 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6126 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6127 aa941b94 balrog
            CPU_DoubleU u;
6128 aa941b94 balrog
            u.d = env->vfp.regs[i];
6129 aa941b94 balrog
            qemu_put_be32(f, u.l.upper);
6130 aa941b94 balrog
            qemu_put_be32(f, u.l.lower);
6131 aa941b94 balrog
        }
6132 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6133 aa941b94 balrog
            qemu_put_be32(f, env->vfp.xregs[i]);
6134 aa941b94 balrog
        }
6135 aa941b94 balrog
6136 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6137 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_len);
6138 aa941b94 balrog
        qemu_put_be32(f, env->vfp.vec_stride);
6139 aa941b94 balrog
    }
6140 aa941b94 balrog
6141 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6142 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6143 aa941b94 balrog
            qemu_put_be64(f, env->iwmmxt.regs[i]);
6144 aa941b94 balrog
        }
6145 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6146 aa941b94 balrog
            qemu_put_be32(f, env->iwmmxt.cregs[i]);
6147 aa941b94 balrog
        }
6148 aa941b94 balrog
    }
6149 b5ff1b31 bellard
}
6150 b5ff1b31 bellard
6151 b5ff1b31 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
6152 b5ff1b31 bellard
{
6153 aa941b94 balrog
    CPUARMState *env = (CPUARMState *)opaque;
6154 aa941b94 balrog
    int i;
6155 aa941b94 balrog
6156 aa941b94 balrog
    if (version_id != 0)
6157 aa941b94 balrog
        return -EINVAL;
6158 aa941b94 balrog
6159 aa941b94 balrog
    for (i = 0; i < 16; i++) {
6160 aa941b94 balrog
        env->regs[i] = qemu_get_be32(f);
6161 aa941b94 balrog
    }
6162 aa941b94 balrog
    cpsr_write(env, qemu_get_be32(f), 0xffffffff);
6163 aa941b94 balrog
    env->spsr = qemu_get_be32(f);
6164 aa941b94 balrog
    for (i = 0; i < 6; i++) {
6165 aa941b94 balrog
        env->banked_spsr[i] = qemu_get_be32(f);
6166 aa941b94 balrog
        env->banked_r13[i] = qemu_get_be32(f);
6167 aa941b94 balrog
        env->banked_r14[i] = qemu_get_be32(f);
6168 aa941b94 balrog
    }
6169 aa941b94 balrog
    for (i = 0; i < 5; i++) {
6170 aa941b94 balrog
        env->usr_regs[i] = qemu_get_be32(f);
6171 aa941b94 balrog
        env->fiq_regs[i] = qemu_get_be32(f);
6172 aa941b94 balrog
    }
6173 aa941b94 balrog
    env->cp15.c0_cpuid = qemu_get_be32(f);
6174 aa941b94 balrog
    env->cp15.c0_cachetype = qemu_get_be32(f);
6175 aa941b94 balrog
    env->cp15.c1_sys = qemu_get_be32(f);
6176 aa941b94 balrog
    env->cp15.c1_coproc = qemu_get_be32(f);
6177 610c3c8a balrog
    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
6178 aa941b94 balrog
    env->cp15.c2_base = qemu_get_be32(f);
6179 aa941b94 balrog
    env->cp15.c2_data = qemu_get_be32(f);
6180 aa941b94 balrog
    env->cp15.c2_insn = qemu_get_be32(f);
6181 aa941b94 balrog
    env->cp15.c3 = qemu_get_be32(f);
6182 aa941b94 balrog
    env->cp15.c5_insn = qemu_get_be32(f);
6183 aa941b94 balrog
    env->cp15.c5_data = qemu_get_be32(f);
6184 aa941b94 balrog
    for (i = 0; i < 8; i++) {
6185 aa941b94 balrog
        env->cp15.c6_region[i] = qemu_get_be32(f);
6186 aa941b94 balrog
    }
6187 aa941b94 balrog
    env->cp15.c6_insn = qemu_get_be32(f);
6188 aa941b94 balrog
    env->cp15.c6_data = qemu_get_be32(f);
6189 aa941b94 balrog
    env->cp15.c9_insn = qemu_get_be32(f);
6190 aa941b94 balrog
    env->cp15.c9_data = qemu_get_be32(f);
6191 aa941b94 balrog
    env->cp15.c13_fcse = qemu_get_be32(f);
6192 aa941b94 balrog
    env->cp15.c13_context = qemu_get_be32(f);
6193 aa941b94 balrog
    env->cp15.c15_cpar = qemu_get_be32(f);
6194 aa941b94 balrog
6195 aa941b94 balrog
    env->features = qemu_get_be32(f);
6196 aa941b94 balrog
6197 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_VFP)) {
6198 aa941b94 balrog
        for (i = 0;  i < 16; i++) {
6199 aa941b94 balrog
            CPU_DoubleU u;
6200 aa941b94 balrog
            u.l.upper = qemu_get_be32(f);
6201 aa941b94 balrog
            u.l.lower = qemu_get_be32(f);
6202 aa941b94 balrog
            env->vfp.regs[i] = u.d;
6203 aa941b94 balrog
        }
6204 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6205 aa941b94 balrog
            env->vfp.xregs[i] = qemu_get_be32(f);
6206 aa941b94 balrog
        }
6207 aa941b94 balrog
6208 aa941b94 balrog
        /* TODO: Should use proper FPSCR access functions.  */
6209 aa941b94 balrog
        env->vfp.vec_len = qemu_get_be32(f);
6210 aa941b94 balrog
        env->vfp.vec_stride = qemu_get_be32(f);
6211 aa941b94 balrog
    }
6212 aa941b94 balrog
6213 aa941b94 balrog
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6214 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6215 aa941b94 balrog
            env->iwmmxt.regs[i] = qemu_get_be64(f);
6216 aa941b94 balrog
        }
6217 aa941b94 balrog
        for (i = 0; i < 16; i++) {
6218 aa941b94 balrog
            env->iwmmxt.cregs[i] = qemu_get_be32(f);
6219 aa941b94 balrog
        }
6220 aa941b94 balrog
    }
6221 aa941b94 balrog
6222 b5ff1b31 bellard
    return 0;
6223 b5ff1b31 bellard
}
6224 b5ff1b31 bellard
6225 8a7ddc38 bellard
#else
6226 8a7ddc38 bellard
6227 8a7ddc38 bellard
#warning No CPU save/restore functions
6228 8a7ddc38 bellard
6229 8a7ddc38 bellard
#endif
6230 8a7ddc38 bellard
6231 8a7ddc38 bellard
/***********************************************************/
6232 8a7ddc38 bellard
/* ram save/restore */
6233 8a7ddc38 bellard
6234 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
6235 8a7ddc38 bellard
{
6236 8a7ddc38 bellard
    int v;
6237 8a7ddc38 bellard
6238 8a7ddc38 bellard
    v = qemu_get_byte(f);
6239 8a7ddc38 bellard
    switch(v) {
6240 8a7ddc38 bellard
    case 0:
6241 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
6242 8a7ddc38 bellard
            return -EIO;
6243 8a7ddc38 bellard
        break;
6244 8a7ddc38 bellard
    case 1:
6245 8a7ddc38 bellard
        v = qemu_get_byte(f);
6246 8a7ddc38 bellard
        memset(buf, v, len);
6247 8a7ddc38 bellard
        break;
6248 8a7ddc38 bellard
    default:
6249 8a7ddc38 bellard
        return -EINVAL;
6250 8a7ddc38 bellard
    }
6251 8a7ddc38 bellard
    return 0;
6252 8a7ddc38 bellard
}
6253 8a7ddc38 bellard
6254 c88676f8 bellard
static int ram_load_v1(QEMUFile *f, void *opaque)
6255 c88676f8 bellard
{
6256 c88676f8 bellard
    int i, ret;
6257 c88676f8 bellard
6258 c88676f8 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6259 c88676f8 bellard
        return -EINVAL;
6260 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
6261 c88676f8 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
6262 c88676f8 bellard
        if (ret)
6263 c88676f8 bellard
            return ret;
6264 c88676f8 bellard
    }
6265 c88676f8 bellard
    return 0;
6266 c88676f8 bellard
}
6267 c88676f8 bellard
6268 c88676f8 bellard
#define BDRV_HASH_BLOCK_SIZE 1024
6269 c88676f8 bellard
#define IOBUF_SIZE 4096
6270 c88676f8 bellard
#define RAM_CBLOCK_MAGIC 0xfabe
6271 c88676f8 bellard
6272 c88676f8 bellard
typedef struct RamCompressState {
6273 c88676f8 bellard
    z_stream zstream;
6274 c88676f8 bellard
    QEMUFile *f;
6275 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6276 c88676f8 bellard
} RamCompressState;
6277 c88676f8 bellard
6278 c88676f8 bellard
static int ram_compress_open(RamCompressState *s, QEMUFile *f)
6279 c88676f8 bellard
{
6280 c88676f8 bellard
    int ret;
6281 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6282 c88676f8 bellard
    s->f = f;
6283 c88676f8 bellard
    ret = deflateInit2(&s->zstream, 1,
6284 c88676f8 bellard
                       Z_DEFLATED, 15, 
6285 c88676f8 bellard
                       9, Z_DEFAULT_STRATEGY);
6286 c88676f8 bellard
    if (ret != Z_OK)
6287 c88676f8 bellard
        return -1;
6288 c88676f8 bellard
    s->zstream.avail_out = IOBUF_SIZE;
6289 c88676f8 bellard
    s->zstream.next_out = s->buf;
6290 c88676f8 bellard
    return 0;
6291 c88676f8 bellard
}
6292 c88676f8 bellard
6293 c88676f8 bellard
static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
6294 c88676f8 bellard
{
6295 c88676f8 bellard
    qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
6296 c88676f8 bellard
    qemu_put_be16(s->f, len);
6297 c88676f8 bellard
    qemu_put_buffer(s->f, buf, len);
6298 c88676f8 bellard
}
6299 c88676f8 bellard
6300 c88676f8 bellard
static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
6301 c88676f8 bellard
{
6302 c88676f8 bellard
    int ret;
6303 c88676f8 bellard
6304 c88676f8 bellard
    s->zstream.avail_in = len;
6305 c88676f8 bellard
    s->zstream.next_in = (uint8_t *)buf;
6306 c88676f8 bellard
    while (s->zstream.avail_in > 0) {
6307 c88676f8 bellard
        ret = deflate(&s->zstream, Z_NO_FLUSH);
6308 c88676f8 bellard
        if (ret != Z_OK)
6309 c88676f8 bellard
            return -1;
6310 c88676f8 bellard
        if (s->zstream.avail_out == 0) {
6311 c88676f8 bellard
            ram_put_cblock(s, s->buf, IOBUF_SIZE);
6312 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6313 c88676f8 bellard
            s->zstream.next_out = s->buf;
6314 c88676f8 bellard
        }
6315 c88676f8 bellard
    }
6316 c88676f8 bellard
    return 0;
6317 c88676f8 bellard
}
6318 c88676f8 bellard
6319 c88676f8 bellard
static void ram_compress_close(RamCompressState *s)
6320 c88676f8 bellard
{
6321 c88676f8 bellard
    int len, ret;
6322 c88676f8 bellard
6323 c88676f8 bellard
    /* compress last bytes */
6324 c88676f8 bellard
    for(;;) {
6325 c88676f8 bellard
        ret = deflate(&s->zstream, Z_FINISH);
6326 c88676f8 bellard
        if (ret == Z_OK || ret == Z_STREAM_END) {
6327 c88676f8 bellard
            len = IOBUF_SIZE - s->zstream.avail_out;
6328 c88676f8 bellard
            if (len > 0) {
6329 c88676f8 bellard
                ram_put_cblock(s, s->buf, len);
6330 c88676f8 bellard
            }
6331 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
6332 c88676f8 bellard
            s->zstream.next_out = s->buf;
6333 c88676f8 bellard
            if (ret == Z_STREAM_END)
6334 c88676f8 bellard
                break;
6335 c88676f8 bellard
        } else {
6336 c88676f8 bellard
            goto fail;
6337 c88676f8 bellard
        }
6338 c88676f8 bellard
    }
6339 c88676f8 bellard
fail:
6340 c88676f8 bellard
    deflateEnd(&s->zstream);
6341 c88676f8 bellard
}
6342 c88676f8 bellard
6343 c88676f8 bellard
typedef struct RamDecompressState {
6344 c88676f8 bellard
    z_stream zstream;
6345 c88676f8 bellard
    QEMUFile *f;
6346 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
6347 c88676f8 bellard
} RamDecompressState;
6348 c88676f8 bellard
6349 c88676f8 bellard
static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
6350 c88676f8 bellard
{
6351 c88676f8 bellard
    int ret;
6352 c88676f8 bellard
    memset(s, 0, sizeof(*s));
6353 c88676f8 bellard
    s->f = f;
6354 c88676f8 bellard
    ret = inflateInit(&s->zstream);
6355 c88676f8 bellard
    if (ret != Z_OK)
6356 c88676f8 bellard
        return -1;
6357 c88676f8 bellard
    return 0;
6358 c88676f8 bellard
}
6359 c88676f8 bellard
6360 c88676f8 bellard
static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
6361 c88676f8 bellard
{
6362 c88676f8 bellard
    int ret, clen;
6363 c88676f8 bellard
6364 c88676f8 bellard
    s->zstream.avail_out = len;
6365 c88676f8 bellard
    s->zstream.next_out = buf;
6366 c88676f8 bellard
    while (s->zstream.avail_out > 0) {
6367 c88676f8 bellard
        if (s->zstream.avail_in == 0) {
6368 c88676f8 bellard
            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
6369 c88676f8 bellard
                return -1;
6370 c88676f8 bellard
            clen = qemu_get_be16(s->f);
6371 c88676f8 bellard
            if (clen > IOBUF_SIZE)
6372 c88676f8 bellard
                return -1;
6373 c88676f8 bellard
            qemu_get_buffer(s->f, s->buf, clen);
6374 c88676f8 bellard
            s->zstream.avail_in = clen;
6375 c88676f8 bellard
            s->zstream.next_in = s->buf;
6376 c88676f8 bellard
        }
6377 c88676f8 bellard
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
6378 c88676f8 bellard
        if (ret != Z_OK && ret != Z_STREAM_END) {
6379 c88676f8 bellard
            return -1;
6380 c88676f8 bellard
        }
6381 c88676f8 bellard
    }
6382 c88676f8 bellard
    return 0;
6383 c88676f8 bellard
}
6384 c88676f8 bellard
6385 c88676f8 bellard
static void ram_decompress_close(RamDecompressState *s)
6386 c88676f8 bellard
{
6387 c88676f8 bellard
    inflateEnd(&s->zstream);
6388 c88676f8 bellard
}
6389 c88676f8 bellard
6390 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
6391 8a7ddc38 bellard
{
6392 8a7ddc38 bellard
    int i;
6393 c88676f8 bellard
    RamCompressState s1, *s = &s1;
6394 c88676f8 bellard
    uint8_t buf[10];
6395 c88676f8 bellard
    
6396 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
6397 c88676f8 bellard
    if (ram_compress_open(s, f) < 0)
6398 c88676f8 bellard
        return;
6399 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6400 c88676f8 bellard
#if 0
6401 c88676f8 bellard
        if (tight_savevm_enabled) {
6402 c88676f8 bellard
            int64_t sector_num;
6403 c88676f8 bellard
            int j;
6404 c88676f8 bellard

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

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