Statistics
| Branch: | Revision:

root / vl.c @ 50d3eeae

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

5814 c88676f8 bellard
            /* find if the memory block is available on a virtual
5815 c88676f8 bellard
               block device */
5816 c88676f8 bellard
            sector_num = -1;
5817 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5818 c88676f8 bellard
                if (bs_table[j]) {
5819 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5820 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5821 c88676f8 bellard
                    if (sector_num >= 0)
5822 c88676f8 bellard
                        break;
5823 c88676f8 bellard
                }
5824 c88676f8 bellard
            }
5825 c88676f8 bellard
            if (j == MAX_DISKS)
5826 c88676f8 bellard
                goto normal_compress;
5827 c88676f8 bellard
            buf[0] = 1;
5828 c88676f8 bellard
            buf[1] = j;
5829 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5830 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5831 c88676f8 bellard
        } else 
5832 c88676f8 bellard
#endif
5833 c88676f8 bellard
        {
5834 c88676f8 bellard
            //        normal_compress:
5835 c88676f8 bellard
            buf[0] = 0;
5836 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5837 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5838 c88676f8 bellard
        }
5839 8a7ddc38 bellard
    }
5840 c88676f8 bellard
    ram_compress_close(s);
5841 8a7ddc38 bellard
}
5842 8a7ddc38 bellard
5843 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5844 8a7ddc38 bellard
{
5845 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5846 c88676f8 bellard
    uint8_t buf[10];
5847 c88676f8 bellard
    int i;
5848 8a7ddc38 bellard
5849 c88676f8 bellard
    if (version_id == 1)
5850 c88676f8 bellard
        return ram_load_v1(f, opaque);
5851 c88676f8 bellard
    if (version_id != 2)
5852 8a7ddc38 bellard
        return -EINVAL;
5853 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5854 8a7ddc38 bellard
        return -EINVAL;
5855 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5856 c88676f8 bellard
        return -EINVAL;
5857 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5858 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5859 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5860 c88676f8 bellard
            goto error;
5861 c88676f8 bellard
        }
5862 c88676f8 bellard
        if (buf[0] == 0) {
5863 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5864 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5865 c88676f8 bellard
                goto error;
5866 c88676f8 bellard
            }
5867 c88676f8 bellard
        } else 
5868 c88676f8 bellard
#if 0
5869 c88676f8 bellard
        if (buf[0] == 1) {
5870 c88676f8 bellard
            int bs_index;
5871 c88676f8 bellard
            int64_t sector_num;
5872 c88676f8 bellard

5873 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
5874 c88676f8 bellard
            bs_index = buf[1];
5875 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
5876 c88676f8 bellard
            if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
5877 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
5878 c88676f8 bellard
                goto error;
5879 c88676f8 bellard
            }
5880 c88676f8 bellard
            if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i, 
5881 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
5882 c88676f8 bellard
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n", 
5883 c88676f8 bellard
                        bs_index, sector_num);
5884 c88676f8 bellard
                goto error;
5885 c88676f8 bellard
            }
5886 c88676f8 bellard
        } else 
5887 c88676f8 bellard
#endif
5888 c88676f8 bellard
        {
5889 c88676f8 bellard
        error:
5890 c88676f8 bellard
            printf("Error block header\n");
5891 c88676f8 bellard
            return -EINVAL;
5892 c88676f8 bellard
        }
5893 8a7ddc38 bellard
    }
5894 c88676f8 bellard
    ram_decompress_close(s);
5895 8a7ddc38 bellard
    return 0;
5896 8a7ddc38 bellard
}
5897 8a7ddc38 bellard
5898 8a7ddc38 bellard
/***********************************************************/
5899 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
5900 83f64091 bellard
5901 83f64091 bellard
struct QEMUBH {
5902 83f64091 bellard
    QEMUBHFunc *cb;
5903 83f64091 bellard
    void *opaque;
5904 83f64091 bellard
    int scheduled;
5905 83f64091 bellard
    QEMUBH *next;
5906 83f64091 bellard
};
5907 83f64091 bellard
5908 83f64091 bellard
static QEMUBH *first_bh = NULL;
5909 83f64091 bellard
5910 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
5911 83f64091 bellard
{
5912 83f64091 bellard
    QEMUBH *bh;
5913 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
5914 83f64091 bellard
    if (!bh)
5915 83f64091 bellard
        return NULL;
5916 83f64091 bellard
    bh->cb = cb;
5917 83f64091 bellard
    bh->opaque = opaque;
5918 83f64091 bellard
    return bh;
5919 83f64091 bellard
}
5920 83f64091 bellard
5921 6eb5733a bellard
int qemu_bh_poll(void)
5922 83f64091 bellard
{
5923 83f64091 bellard
    QEMUBH *bh, **pbh;
5924 6eb5733a bellard
    int ret;
5925 83f64091 bellard
5926 6eb5733a bellard
    ret = 0;
5927 83f64091 bellard
    for(;;) {
5928 83f64091 bellard
        pbh = &first_bh;
5929 83f64091 bellard
        bh = *pbh;
5930 83f64091 bellard
        if (!bh)
5931 83f64091 bellard
            break;
5932 6eb5733a bellard
        ret = 1;
5933 83f64091 bellard
        *pbh = bh->next;
5934 83f64091 bellard
        bh->scheduled = 0;
5935 83f64091 bellard
        bh->cb(bh->opaque);
5936 83f64091 bellard
    }
5937 6eb5733a bellard
    return ret;
5938 83f64091 bellard
}
5939 83f64091 bellard
5940 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
5941 83f64091 bellard
{
5942 83f64091 bellard
    CPUState *env = cpu_single_env;
5943 83f64091 bellard
    if (bh->scheduled)
5944 83f64091 bellard
        return;
5945 83f64091 bellard
    bh->scheduled = 1;
5946 83f64091 bellard
    bh->next = first_bh;
5947 83f64091 bellard
    first_bh = bh;
5948 83f64091 bellard
5949 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
5950 83f64091 bellard
    if (env) {
5951 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
5952 83f64091 bellard
    }
5953 83f64091 bellard
}
5954 83f64091 bellard
5955 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
5956 83f64091 bellard
{
5957 83f64091 bellard
    QEMUBH **pbh;
5958 83f64091 bellard
    if (bh->scheduled) {
5959 83f64091 bellard
        pbh = &first_bh;
5960 83f64091 bellard
        while (*pbh != bh)
5961 83f64091 bellard
            pbh = &(*pbh)->next;
5962 83f64091 bellard
        *pbh = bh->next;
5963 83f64091 bellard
        bh->scheduled = 0;
5964 83f64091 bellard
    }
5965 83f64091 bellard
}
5966 83f64091 bellard
5967 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
5968 83f64091 bellard
{
5969 83f64091 bellard
    qemu_bh_cancel(bh);
5970 83f64091 bellard
    qemu_free(bh);
5971 83f64091 bellard
}
5972 83f64091 bellard
5973 83f64091 bellard
/***********************************************************/
5974 cc1daa40 bellard
/* machine registration */
5975 cc1daa40 bellard
5976 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
5977 cc1daa40 bellard
5978 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
5979 cc1daa40 bellard
{
5980 cc1daa40 bellard
    QEMUMachine **pm;
5981 cc1daa40 bellard
    pm = &first_machine;
5982 cc1daa40 bellard
    while (*pm != NULL)
5983 cc1daa40 bellard
        pm = &(*pm)->next;
5984 cc1daa40 bellard
    m->next = NULL;
5985 cc1daa40 bellard
    *pm = m;
5986 cc1daa40 bellard
    return 0;
5987 cc1daa40 bellard
}
5988 cc1daa40 bellard
5989 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
5990 cc1daa40 bellard
{
5991 cc1daa40 bellard
    QEMUMachine *m;
5992 cc1daa40 bellard
5993 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
5994 cc1daa40 bellard
        if (!strcmp(m->name, name))
5995 cc1daa40 bellard
            return m;
5996 cc1daa40 bellard
    }
5997 cc1daa40 bellard
    return NULL;
5998 cc1daa40 bellard
}
5999 cc1daa40 bellard
6000 cc1daa40 bellard
/***********************************************************/
6001 8a7ddc38 bellard
/* main execution loop */
6002 8a7ddc38 bellard
6003 8a7ddc38 bellard
void gui_update(void *opaque)
6004 8a7ddc38 bellard
{
6005 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
6006 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
6007 8a7ddc38 bellard
}
6008 8a7ddc38 bellard
6009 0bd48850 bellard
struct vm_change_state_entry {
6010 0bd48850 bellard
    VMChangeStateHandler *cb;
6011 0bd48850 bellard
    void *opaque;
6012 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
6013 0bd48850 bellard
};
6014 0bd48850 bellard
6015 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
6016 0bd48850 bellard
6017 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
6018 0bd48850 bellard
                                                     void *opaque)
6019 0bd48850 bellard
{
6020 0bd48850 bellard
    VMChangeStateEntry *e;
6021 0bd48850 bellard
6022 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
6023 0bd48850 bellard
    if (!e)
6024 0bd48850 bellard
        return NULL;
6025 0bd48850 bellard
6026 0bd48850 bellard
    e->cb = cb;
6027 0bd48850 bellard
    e->opaque = opaque;
6028 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
6029 0bd48850 bellard
    return e;
6030 0bd48850 bellard
}
6031 0bd48850 bellard
6032 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
6033 0bd48850 bellard
{
6034 0bd48850 bellard
    LIST_REMOVE (e, entries);
6035 0bd48850 bellard
    qemu_free (e);
6036 0bd48850 bellard
}
6037 0bd48850 bellard
6038 0bd48850 bellard
static void vm_state_notify(int running)
6039 0bd48850 bellard
{
6040 0bd48850 bellard
    VMChangeStateEntry *e;
6041 0bd48850 bellard
6042 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
6043 0bd48850 bellard
        e->cb(e->opaque, running);
6044 0bd48850 bellard
    }
6045 0bd48850 bellard
}
6046 0bd48850 bellard
6047 8a7ddc38 bellard
/* XXX: support several handlers */
6048 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
6049 0bd48850 bellard
static void *vm_stop_opaque;
6050 8a7ddc38 bellard
6051 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
6052 8a7ddc38 bellard
{
6053 8a7ddc38 bellard
    vm_stop_cb = cb;
6054 8a7ddc38 bellard
    vm_stop_opaque = opaque;
6055 8a7ddc38 bellard
    return 0;
6056 8a7ddc38 bellard
}
6057 8a7ddc38 bellard
6058 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
6059 8a7ddc38 bellard
{
6060 8a7ddc38 bellard
    vm_stop_cb = NULL;
6061 8a7ddc38 bellard
}
6062 8a7ddc38 bellard
6063 8a7ddc38 bellard
void vm_start(void)
6064 8a7ddc38 bellard
{
6065 8a7ddc38 bellard
    if (!vm_running) {
6066 8a7ddc38 bellard
        cpu_enable_ticks();
6067 8a7ddc38 bellard
        vm_running = 1;
6068 0bd48850 bellard
        vm_state_notify(1);
6069 8a7ddc38 bellard
    }
6070 8a7ddc38 bellard
}
6071 8a7ddc38 bellard
6072 8a7ddc38 bellard
void vm_stop(int reason) 
6073 8a7ddc38 bellard
{
6074 8a7ddc38 bellard
    if (vm_running) {
6075 8a7ddc38 bellard
        cpu_disable_ticks();
6076 8a7ddc38 bellard
        vm_running = 0;
6077 8a7ddc38 bellard
        if (reason != 0) {
6078 8a7ddc38 bellard
            if (vm_stop_cb) {
6079 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
6080 8a7ddc38 bellard
            }
6081 34865134 bellard
        }
6082 0bd48850 bellard
        vm_state_notify(0);
6083 8a7ddc38 bellard
    }
6084 8a7ddc38 bellard
}
6085 8a7ddc38 bellard
6086 bb0c6722 bellard
/* reset/shutdown handler */
6087 bb0c6722 bellard
6088 bb0c6722 bellard
typedef struct QEMUResetEntry {
6089 bb0c6722 bellard
    QEMUResetHandler *func;
6090 bb0c6722 bellard
    void *opaque;
6091 bb0c6722 bellard
    struct QEMUResetEntry *next;
6092 bb0c6722 bellard
} QEMUResetEntry;
6093 bb0c6722 bellard
6094 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
6095 bb0c6722 bellard
static int reset_requested;
6096 bb0c6722 bellard
static int shutdown_requested;
6097 3475187d bellard
static int powerdown_requested;
6098 bb0c6722 bellard
6099 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
6100 bb0c6722 bellard
{
6101 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
6102 bb0c6722 bellard
6103 bb0c6722 bellard
    pre = &first_reset_entry;
6104 bb0c6722 bellard
    while (*pre != NULL)
6105 bb0c6722 bellard
        pre = &(*pre)->next;
6106 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
6107 bb0c6722 bellard
    re->func = func;
6108 bb0c6722 bellard
    re->opaque = opaque;
6109 bb0c6722 bellard
    re->next = NULL;
6110 bb0c6722 bellard
    *pre = re;
6111 bb0c6722 bellard
}
6112 bb0c6722 bellard
6113 52f61fde ths
static void qemu_system_reset(void)
6114 bb0c6722 bellard
{
6115 bb0c6722 bellard
    QEMUResetEntry *re;
6116 bb0c6722 bellard
6117 bb0c6722 bellard
    /* reset all devices */
6118 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
6119 bb0c6722 bellard
        re->func(re->opaque);
6120 bb0c6722 bellard
    }
6121 bb0c6722 bellard
}
6122 bb0c6722 bellard
6123 bb0c6722 bellard
void qemu_system_reset_request(void)
6124 bb0c6722 bellard
{
6125 d1beab82 bellard
    if (no_reboot) {
6126 d1beab82 bellard
        shutdown_requested = 1;
6127 d1beab82 bellard
    } else {
6128 d1beab82 bellard
        reset_requested = 1;
6129 d1beab82 bellard
    }
6130 6a00d601 bellard
    if (cpu_single_env)
6131 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6132 bb0c6722 bellard
}
6133 bb0c6722 bellard
6134 bb0c6722 bellard
void qemu_system_shutdown_request(void)
6135 bb0c6722 bellard
{
6136 bb0c6722 bellard
    shutdown_requested = 1;
6137 6a00d601 bellard
    if (cpu_single_env)
6138 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6139 bb0c6722 bellard
}
6140 bb0c6722 bellard
6141 3475187d bellard
void qemu_system_powerdown_request(void)
6142 3475187d bellard
{
6143 3475187d bellard
    powerdown_requested = 1;
6144 6a00d601 bellard
    if (cpu_single_env)
6145 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6146 bb0c6722 bellard
}
6147 bb0c6722 bellard
6148 5905b2e5 bellard
void main_loop_wait(int timeout)
6149 8a7ddc38 bellard
{
6150 cafffd40 ths
    IOHandlerRecord *ioh;
6151 e035649e bellard
    fd_set rfds, wfds, xfds;
6152 fd1dff4b bellard
    int ret, nfds;
6153 fd1dff4b bellard
    struct timeval tv;
6154 f331110f bellard
    PollingEntry *pe;
6155 f331110f bellard
6156 c4b1fcc0 bellard
6157 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
6158 f331110f bellard
    ret = 0;
6159 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
6160 f331110f bellard
        ret |= pe->func(pe->opaque);
6161 f331110f bellard
    }
6162 38e205a2 bellard
#ifdef _WIN32
6163 f331110f bellard
    if (ret == 0 && timeout > 0) {
6164 a18e524a bellard
        int err;
6165 a18e524a bellard
        WaitObjects *w = &wait_objects;
6166 a18e524a bellard
        
6167 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
6168 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
6169 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
6170 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
6171 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
6172 a18e524a bellard
        } else {
6173 a18e524a bellard
            err = GetLastError();
6174 a18e524a bellard
            fprintf(stderr, "Wait error %d %d\n", ret, err);
6175 a18e524a bellard
        }
6176 f331110f bellard
    }
6177 fd1dff4b bellard
#endif
6178 fd1dff4b bellard
    /* poll any events */
6179 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
6180 fd1dff4b bellard
    nfds = -1;
6181 fd1dff4b bellard
    FD_ZERO(&rfds);
6182 fd1dff4b bellard
    FD_ZERO(&wfds);
6183 e035649e bellard
    FD_ZERO(&xfds);
6184 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6185 cafffd40 ths
        if (ioh->deleted)
6186 cafffd40 ths
            continue;
6187 fd1dff4b bellard
        if (ioh->fd_read &&
6188 fd1dff4b bellard
            (!ioh->fd_read_poll ||
6189 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
6190 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
6191 fd1dff4b bellard
            if (ioh->fd > nfds)
6192 fd1dff4b bellard
                nfds = ioh->fd;
6193 fd1dff4b bellard
        }
6194 fd1dff4b bellard
        if (ioh->fd_write) {
6195 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
6196 fd1dff4b bellard
            if (ioh->fd > nfds)
6197 fd1dff4b bellard
                nfds = ioh->fd;
6198 fd1dff4b bellard
        }
6199 fd1dff4b bellard
    }
6200 fd1dff4b bellard
    
6201 fd1dff4b bellard
    tv.tv_sec = 0;
6202 fd1dff4b bellard
#ifdef _WIN32
6203 fd1dff4b bellard
    tv.tv_usec = 0;
6204 38e205a2 bellard
#else
6205 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
6206 fd1dff4b bellard
#endif
6207 e035649e bellard
#if defined(CONFIG_SLIRP)
6208 e035649e bellard
    if (slirp_inited) {
6209 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
6210 e035649e bellard
    }
6211 e035649e bellard
#endif
6212 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
6213 fd1dff4b bellard
    if (ret > 0) {
6214 cafffd40 ths
        IOHandlerRecord **pioh;
6215 cafffd40 ths
6216 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6217 cafffd40 ths
            if (ioh->deleted)
6218 cafffd40 ths
                continue;
6219 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &rfds)) {
6220 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
6221 7c9d8e07 bellard
            }
6222 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &wfds)) {
6223 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
6224 c4b1fcc0 bellard
            }
6225 b4608c04 bellard
        }
6226 cafffd40 ths
6227 cafffd40 ths
        /* remove deleted IO handlers */
6228 cafffd40 ths
        pioh = &first_io_handler;
6229 cafffd40 ths
        while (*pioh) {
6230 cafffd40 ths
            ioh = *pioh;
6231 cafffd40 ths
            if (ioh->deleted) {
6232 cafffd40 ths
                *pioh = ioh->next;
6233 cafffd40 ths
                qemu_free(ioh);
6234 cafffd40 ths
            } else 
6235 cafffd40 ths
                pioh = &ioh->next;
6236 cafffd40 ths
        }
6237 fd1dff4b bellard
    }
6238 c20709aa bellard
#if defined(CONFIG_SLIRP)
6239 fd1dff4b bellard
    if (slirp_inited) {
6240 e035649e bellard
        if (ret < 0) {
6241 e035649e bellard
            FD_ZERO(&rfds);
6242 e035649e bellard
            FD_ZERO(&wfds);
6243 e035649e bellard
            FD_ZERO(&xfds);
6244 c20709aa bellard
        }
6245 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
6246 fd1dff4b bellard
    }
6247 c20709aa bellard
#endif
6248 83f64091 bellard
    qemu_aio_poll();
6249 83f64091 bellard
    qemu_bh_poll();
6250 c20709aa bellard
6251 fd1dff4b bellard
    if (vm_running) {
6252 fd1dff4b bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
6253 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
6254 fd1dff4b bellard
        /* run dma transfers, if any */
6255 fd1dff4b bellard
        DMA_run();
6256 fd1dff4b bellard
    }
6257 fd1dff4b bellard
    
6258 fd1dff4b bellard
    /* real time timers */
6259 fd1dff4b bellard
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
6260 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
6261 5905b2e5 bellard
}
6262 5905b2e5 bellard
6263 6a00d601 bellard
static CPUState *cur_cpu;
6264 6a00d601 bellard
6265 5905b2e5 bellard
int main_loop(void)
6266 5905b2e5 bellard
{
6267 5905b2e5 bellard
    int ret, timeout;
6268 89bfc105 bellard
#ifdef CONFIG_PROFILER
6269 89bfc105 bellard
    int64_t ti;
6270 89bfc105 bellard
#endif
6271 6a00d601 bellard
    CPUState *env;
6272 5905b2e5 bellard
6273 6a00d601 bellard
    cur_cpu = first_cpu;
6274 5905b2e5 bellard
    for(;;) {
6275 5905b2e5 bellard
        if (vm_running) {
6276 15a76449 bellard
6277 15a76449 bellard
            env = cur_cpu;
6278 15a76449 bellard
            for(;;) {
6279 15a76449 bellard
                /* get next cpu */
6280 15a76449 bellard
                env = env->next_cpu;
6281 15a76449 bellard
                if (!env)
6282 15a76449 bellard
                    env = first_cpu;
6283 89bfc105 bellard
#ifdef CONFIG_PROFILER
6284 89bfc105 bellard
                ti = profile_getclock();
6285 89bfc105 bellard
#endif
6286 6a00d601 bellard
                ret = cpu_exec(env);
6287 89bfc105 bellard
#ifdef CONFIG_PROFILER
6288 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
6289 89bfc105 bellard
#endif
6290 bd967e05 pbrook
                if (ret == EXCP_HLT) {
6291 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
6292 bd967e05 pbrook
                    cur_cpu = env;
6293 bd967e05 pbrook
                    continue;
6294 bd967e05 pbrook
                }
6295 15a76449 bellard
                if (ret != EXCP_HALTED)
6296 15a76449 bellard
                    break;
6297 15a76449 bellard
                /* all CPUs are halted ? */
6298 bd967e05 pbrook
                if (env == cur_cpu)
6299 15a76449 bellard
                    break;
6300 15a76449 bellard
            }
6301 15a76449 bellard
            cur_cpu = env;
6302 15a76449 bellard
6303 5905b2e5 bellard
            if (shutdown_requested) {
6304 3475187d bellard
                ret = EXCP_INTERRUPT;
6305 5905b2e5 bellard
                break;
6306 5905b2e5 bellard
            }
6307 5905b2e5 bellard
            if (reset_requested) {
6308 5905b2e5 bellard
                reset_requested = 0;
6309 5905b2e5 bellard
                qemu_system_reset();
6310 3475187d bellard
                ret = EXCP_INTERRUPT;
6311 3475187d bellard
            }
6312 3475187d bellard
            if (powerdown_requested) {
6313 3475187d bellard
                powerdown_requested = 0;
6314 3475187d bellard
                qemu_system_powerdown();
6315 3475187d bellard
                ret = EXCP_INTERRUPT;
6316 5905b2e5 bellard
            }
6317 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
6318 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
6319 5905b2e5 bellard
            }
6320 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
6321 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
6322 bd967e05 pbrook
            if (ret == EXCP_HALTED)
6323 5905b2e5 bellard
                timeout = 10;
6324 5905b2e5 bellard
            else
6325 5905b2e5 bellard
                timeout = 0;
6326 5905b2e5 bellard
        } else {
6327 5905b2e5 bellard
            timeout = 10;
6328 5905b2e5 bellard
        }
6329 89bfc105 bellard
#ifdef CONFIG_PROFILER
6330 89bfc105 bellard
        ti = profile_getclock();
6331 89bfc105 bellard
#endif
6332 5905b2e5 bellard
        main_loop_wait(timeout);
6333 89bfc105 bellard
#ifdef CONFIG_PROFILER
6334 89bfc105 bellard
        dev_time += profile_getclock() - ti;
6335 89bfc105 bellard
#endif
6336 b4608c04 bellard
    }
6337 34865134 bellard
    cpu_disable_ticks();
6338 34865134 bellard
    return ret;
6339 b4608c04 bellard
}
6340 b4608c04 bellard
6341 0824d6fc bellard
void help(void)
6342 0824d6fc bellard
{
6343 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
6344 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
6345 0824d6fc bellard
           "\n"
6346 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
6347 fc01f7e7 bellard
           "\n"
6348 a20dd508 bellard
           "Standard options:\n"
6349 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
6350 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
6351 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
6352 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
6353 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
6354 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
6355 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
6356 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
6357 667accab ths
#ifdef CONFIG_SDL
6358 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
6359 667accab ths
           "-no-quit        disable SDL window close capability\n"
6360 667accab ths
#endif
6361 52ca8d6a bellard
#ifdef TARGET_I386
6362 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
6363 52ca8d6a bellard
#endif
6364 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
6365 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
6366 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
6367 4ca0074c bellard
#ifndef _WIN32
6368 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
6369 4ca0074c bellard
#endif
6370 1d14ffa9 bellard
#ifdef HAS_AUDIO
6371 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
6372 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
6373 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
6374 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
6375 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
6376 1d14ffa9 bellard
#endif
6377 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
6378 d63d307f bellard
           "-full-screen    start in full screen\n"
6379 a09db21f bellard
#ifdef TARGET_I386
6380 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
6381 a09db21f bellard
#endif
6382 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
6383 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
6384 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6385 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
6386 bb0c6722 bellard
#endif
6387 c35734b2 ths
           "-name string    set the name of the guest\n"
6388 c4b1fcc0 bellard
           "\n"
6389 c4b1fcc0 bellard
           "Network options:\n"
6390 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
6391 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
6392 c20709aa bellard
#ifdef CONFIG_SLIRP
6393 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
6394 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
6395 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
6396 7c9d8e07 bellard
#endif
6397 7fb843f8 bellard
#ifdef _WIN32
6398 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
6399 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
6400 7fb843f8 bellard
#else
6401 7c9d8e07 bellard
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
6402 7c9d8e07 bellard
           "                connect the host TAP network interface to VLAN 'n' and use\n"
6403 7c9d8e07 bellard
           "                the network script 'file' (default=%s);\n"
6404 6a1cbf68 ths
           "                use 'script=no' to disable script execution;\n"
6405 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
6406 7fb843f8 bellard
#endif
6407 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
6408 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
6409 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
6410 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
6411 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
6412 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
6413 7c9d8e07 bellard
           "\n"
6414 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
6415 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
6416 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
6417 7c9d8e07 bellard
#ifndef _WIN32
6418 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
6419 c94c8d64 bellard
#endif
6420 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
6421 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
6422 c20709aa bellard
#endif
6423 a20dd508 bellard
           "\n"
6424 c4b1fcc0 bellard
           "Linux boot specific:\n"
6425 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
6426 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
6427 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
6428 fc01f7e7 bellard
           "\n"
6429 330d0414 bellard
           "Debug/Expert options:\n"
6430 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
6431 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
6432 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
6433 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
6434 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
6435 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
6436 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
6437 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
6438 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
6439 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
6440 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
6441 d993e026 bellard
#ifdef USE_KQEMU
6442 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
6443 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
6444 d993e026 bellard
#endif
6445 77fef8c1 bellard
#ifdef USE_CODE_COPY
6446 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
6447 77fef8c1 bellard
#endif
6448 bb0c6722 bellard
#ifdef TARGET_I386
6449 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
6450 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
6451 6515b203 bellard
           "-no-acpi        disable ACPI\n"
6452 bb0c6722 bellard
#endif
6453 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
6454 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
6455 24236869 bellard
           "-vnc display    start a VNC server on display\n"
6456 71e3ceb8 ths
#ifndef _WIN32
6457 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
6458 71e3ceb8 ths
#endif
6459 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
6460 0824d6fc bellard
           "\n"
6461 82c643ff bellard
           "During emulation, the following keys are useful:\n"
6462 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
6463 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
6464 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
6465 82c643ff bellard
           "\n"
6466 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
6467 82c643ff bellard
           ,
6468 0db63474 bellard
           "qemu",
6469 a00bad7e bellard
           DEFAULT_RAM_SIZE,
6470 7c9d8e07 bellard
#ifndef _WIN32
6471 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
6472 7c9d8e07 bellard
#endif
6473 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
6474 6e44ba7f bellard
           "/tmp/qemu.log");
6475 0824d6fc bellard
    exit(1);
6476 0824d6fc bellard
}
6477 0824d6fc bellard
6478 cd6f1169 bellard
#define HAS_ARG 0x0001
6479 cd6f1169 bellard
6480 cd6f1169 bellard
enum {
6481 cd6f1169 bellard
    QEMU_OPTION_h,
6482 cd6f1169 bellard
6483 cc1daa40 bellard
    QEMU_OPTION_M,
6484 94fc95cd j_mayer
    QEMU_OPTION_cpu,
6485 cd6f1169 bellard
    QEMU_OPTION_fda,
6486 cd6f1169 bellard
    QEMU_OPTION_fdb,
6487 cd6f1169 bellard
    QEMU_OPTION_hda,
6488 cd6f1169 bellard
    QEMU_OPTION_hdb,
6489 cd6f1169 bellard
    QEMU_OPTION_hdc,
6490 cd6f1169 bellard
    QEMU_OPTION_hdd,
6491 cd6f1169 bellard
    QEMU_OPTION_cdrom,
6492 cd6f1169 bellard
    QEMU_OPTION_boot,
6493 cd6f1169 bellard
    QEMU_OPTION_snapshot,
6494 52ca8d6a bellard
#ifdef TARGET_I386
6495 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
6496 52ca8d6a bellard
#endif
6497 cd6f1169 bellard
    QEMU_OPTION_m,
6498 cd6f1169 bellard
    QEMU_OPTION_nographic,
6499 1d14ffa9 bellard
#ifdef HAS_AUDIO
6500 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
6501 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
6502 1d14ffa9 bellard
#endif
6503 cd6f1169 bellard
6504 7c9d8e07 bellard
    QEMU_OPTION_net,
6505 c7f74643 bellard
    QEMU_OPTION_tftp,
6506 47d5d01a ths
    QEMU_OPTION_bootp,
6507 9d728e8c bellard
    QEMU_OPTION_smb,
6508 9bf05444 bellard
    QEMU_OPTION_redir,
6509 cd6f1169 bellard
6510 cd6f1169 bellard
    QEMU_OPTION_kernel,
6511 cd6f1169 bellard
    QEMU_OPTION_append,
6512 cd6f1169 bellard
    QEMU_OPTION_initrd,
6513 cd6f1169 bellard
6514 cd6f1169 bellard
    QEMU_OPTION_S,
6515 cd6f1169 bellard
    QEMU_OPTION_s,
6516 cd6f1169 bellard
    QEMU_OPTION_p,
6517 cd6f1169 bellard
    QEMU_OPTION_d,
6518 cd6f1169 bellard
    QEMU_OPTION_hdachs,
6519 cd6f1169 bellard
    QEMU_OPTION_L,
6520 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
6521 3d11d0eb bellard
    QEMU_OPTION_k,
6522 ee22c2f7 bellard
    QEMU_OPTION_localtime,
6523 1f04275e bellard
    QEMU_OPTION_cirrusvga,
6524 e9b137c2 bellard
    QEMU_OPTION_g,
6525 1bfe856e bellard
    QEMU_OPTION_std_vga,
6526 20d8a3ed ths
    QEMU_OPTION_echr,
6527 82c643ff bellard
    QEMU_OPTION_monitor,
6528 82c643ff bellard
    QEMU_OPTION_serial,
6529 6508fe59 bellard
    QEMU_OPTION_parallel,
6530 d63d307f bellard
    QEMU_OPTION_loadvm,
6531 d63d307f bellard
    QEMU_OPTION_full_screen,
6532 43523e93 ths
    QEMU_OPTION_no_frame,
6533 667accab ths
    QEMU_OPTION_no_quit,
6534 f7cce898 bellard
    QEMU_OPTION_pidfile,
6535 d993e026 bellard
    QEMU_OPTION_no_kqemu,
6536 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
6537 a09db21f bellard
    QEMU_OPTION_win2k_hack,
6538 bb36d470 bellard
    QEMU_OPTION_usb,
6539 a594cfbf bellard
    QEMU_OPTION_usbdevice,
6540 6a00d601 bellard
    QEMU_OPTION_smp,
6541 24236869 bellard
    QEMU_OPTION_vnc,
6542 6515b203 bellard
    QEMU_OPTION_no_acpi,
6543 d1beab82 bellard
    QEMU_OPTION_no_reboot,
6544 71e3ceb8 ths
    QEMU_OPTION_daemonize,
6545 9ae02555 ths
    QEMU_OPTION_option_rom,
6546 c35734b2 ths
    QEMU_OPTION_semihosting,
6547 c35734b2 ths
    QEMU_OPTION_name,
6548 cd6f1169 bellard
};
6549 cd6f1169 bellard
6550 cd6f1169 bellard
typedef struct QEMUOption {
6551 cd6f1169 bellard
    const char *name;
6552 cd6f1169 bellard
    int flags;
6553 cd6f1169 bellard
    int index;
6554 cd6f1169 bellard
} QEMUOption;
6555 cd6f1169 bellard
6556 cd6f1169 bellard
const QEMUOption qemu_options[] = {
6557 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
6558 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
6559 cd6f1169 bellard
6560 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
6561 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
6562 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
6563 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
6564 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
6565 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
6566 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
6567 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
6568 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
6569 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
6570 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
6571 52ca8d6a bellard
#ifdef TARGET_I386
6572 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
6573 52ca8d6a bellard
#endif
6574 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
6575 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
6576 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
6577 1d14ffa9 bellard
#ifdef HAS_AUDIO
6578 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
6579 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
6580 1d14ffa9 bellard
#endif
6581 cd6f1169 bellard
6582 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
6583 158156d1 bellard
#ifdef CONFIG_SLIRP
6584 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
6585 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
6586 c94c8d64 bellard
#ifndef _WIN32
6587 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
6588 c94c8d64 bellard
#endif
6589 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
6590 158156d1 bellard
#endif
6591 cd6f1169 bellard
6592 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
6593 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
6594 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
6595 cd6f1169 bellard
6596 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
6597 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
6598 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
6599 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
6600 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
6601 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
6602 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
6603 d993e026 bellard
#ifdef USE_KQEMU
6604 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
6605 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
6606 d993e026 bellard
#endif
6607 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6608 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
6609 77d4bc34 bellard
#endif
6610 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
6611 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
6612 20d8a3ed ths
    { "echr", 1, QEMU_OPTION_echr },
6613 82c643ff bellard
    { "monitor", 1, QEMU_OPTION_monitor },
6614 82c643ff bellard
    { "serial", 1, QEMU_OPTION_serial },
6615 6508fe59 bellard
    { "parallel", 1, QEMU_OPTION_parallel },
6616 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
6617 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
6618 667accab ths
#ifdef CONFIG_SDL
6619 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
6620 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
6621 667accab ths
#endif
6622 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
6623 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
6624 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
6625 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
6626 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
6627 96d30e48 ths
6628 1f04275e bellard
    /* temporary options */
6629 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
6630 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
6631 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
6632 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
6633 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
6634 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
6635 8e71621f pbrook
#if defined(TARGET_ARM)
6636 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
6637 8e71621f pbrook
#endif
6638 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
6639 cd6f1169 bellard
    { NULL },
6640 fc01f7e7 bellard
};
6641 fc01f7e7 bellard
6642 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
6643 77fef8c1 bellard
6644 77fef8c1 bellard
/* this stack is only used during signal handling */
6645 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
6646 77fef8c1 bellard
6647 77fef8c1 bellard
static uint8_t *signal_stack;
6648 77fef8c1 bellard
6649 77fef8c1 bellard
#endif
6650 77fef8c1 bellard
6651 5905b2e5 bellard
/* password input */
6652 5905b2e5 bellard
6653 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
6654 5905b2e5 bellard
{
6655 5905b2e5 bellard
    BlockDriverState *bs;
6656 5905b2e5 bellard
6657 5905b2e5 bellard
    if (index < 4) {
6658 5905b2e5 bellard
        bs = bs_table[index];
6659 5905b2e5 bellard
    } else if (index < 6) {
6660 5905b2e5 bellard
        bs = fd_table[index - 4];
6661 5905b2e5 bellard
    } else {
6662 5905b2e5 bellard
        bs = NULL;
6663 5905b2e5 bellard
    }
6664 5905b2e5 bellard
    return bs;
6665 5905b2e5 bellard
}
6666 5905b2e5 bellard
6667 5905b2e5 bellard
static void read_passwords(void)
6668 5905b2e5 bellard
{
6669 5905b2e5 bellard
    BlockDriverState *bs;
6670 5905b2e5 bellard
    int i, j;
6671 5905b2e5 bellard
    char password[256];
6672 5905b2e5 bellard
6673 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
6674 5905b2e5 bellard
        bs = get_bdrv(i);
6675 5905b2e5 bellard
        if (bs && bdrv_is_encrypted(bs)) {
6676 5905b2e5 bellard
            term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
6677 5905b2e5 bellard
            for(j = 0; j < 3; j++) {
6678 5905b2e5 bellard
                monitor_readline("Password: ", 
6679 5905b2e5 bellard
                                 1, password, sizeof(password));
6680 5905b2e5 bellard
                if (bdrv_set_key(bs, password) == 0)
6681 5905b2e5 bellard
                    break;
6682 5905b2e5 bellard
                term_printf("invalid password\n");
6683 5905b2e5 bellard
            }
6684 5905b2e5 bellard
        }
6685 5905b2e5 bellard
    }
6686 5905b2e5 bellard
}
6687 5905b2e5 bellard
6688 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
6689 cc1daa40 bellard
void register_machines(void)
6690 cc1daa40 bellard
{
6691 cc1daa40 bellard
#if defined(TARGET_I386)
6692 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
6693 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
6694 cc1daa40 bellard
#elif defined(TARGET_PPC)
6695 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
6696 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
6697 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
6698 6af0bf9c bellard
#elif defined(TARGET_MIPS)
6699 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
6700 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
6701 cc1daa40 bellard
#elif defined(TARGET_SPARC)
6702 3475187d bellard
#ifdef TARGET_SPARC64
6703 3475187d bellard
    qemu_register_machine(&sun4u_machine);
6704 3475187d bellard
#else
6705 cc1daa40 bellard
    qemu_register_machine(&sun4m_machine);
6706 cc1daa40 bellard
#endif
6707 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6708 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
6709 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
6710 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
6711 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
6712 27c7ca7e bellard
#elif defined(TARGET_SH4)
6713 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
6714 b5ff1b31 bellard
#else
6715 b5ff1b31 bellard
#error unsupported CPU
6716 3475187d bellard
#endif
6717 cc1daa40 bellard
}
6718 cc1daa40 bellard
6719 1d14ffa9 bellard
#ifdef HAS_AUDIO
6720 6a36d84e bellard
struct soundhw soundhw[] = {
6721 fd06c375 bellard
#ifdef TARGET_I386
6722 fd06c375 bellard
    {
6723 fd06c375 bellard
        "pcspk",
6724 fd06c375 bellard
        "PC speaker",
6725 fd06c375 bellard
        0,
6726 fd06c375 bellard
        1,
6727 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
6728 fd06c375 bellard
    },
6729 fd06c375 bellard
#endif
6730 6a36d84e bellard
    {
6731 6a36d84e bellard
        "sb16",
6732 6a36d84e bellard
        "Creative Sound Blaster 16",
6733 6a36d84e bellard
        0,
6734 6a36d84e bellard
        1,
6735 6a36d84e bellard
        { .init_isa = SB16_init }
6736 6a36d84e bellard
    },
6737 6a36d84e bellard
6738 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
6739 6a36d84e bellard
    {
6740 6a36d84e bellard
        "adlib",
6741 1d14ffa9 bellard
#ifdef HAS_YMF262
6742 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
6743 1d14ffa9 bellard
#else
6744 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
6745 1d14ffa9 bellard
#endif
6746 6a36d84e bellard
        0,
6747 6a36d84e bellard
        1,
6748 6a36d84e bellard
        { .init_isa = Adlib_init }
6749 6a36d84e bellard
    },
6750 1d14ffa9 bellard
#endif
6751 6a36d84e bellard
6752 1d14ffa9 bellard
#ifdef CONFIG_GUS
6753 6a36d84e bellard
    {
6754 6a36d84e bellard
        "gus",
6755 6a36d84e bellard
        "Gravis Ultrasound GF1",
6756 6a36d84e bellard
        0,
6757 6a36d84e bellard
        1,
6758 6a36d84e bellard
        { .init_isa = GUS_init }
6759 6a36d84e bellard
    },
6760 1d14ffa9 bellard
#endif
6761 6a36d84e bellard
6762 6a36d84e bellard
    {
6763 6a36d84e bellard
        "es1370",
6764 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
6765 6a36d84e bellard
        0,
6766 6a36d84e bellard
        0,
6767 6a36d84e bellard
        { .init_pci = es1370_init }
6768 6a36d84e bellard
    },
6769 6a36d84e bellard
6770 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
6771 6a36d84e bellard
};
6772 6a36d84e bellard
6773 6a36d84e bellard
static void select_soundhw (const char *optarg)
6774 6a36d84e bellard
{
6775 6a36d84e bellard
    struct soundhw *c;
6776 6a36d84e bellard
6777 6a36d84e bellard
    if (*optarg == '?') {
6778 6a36d84e bellard
    show_valid_cards:
6779 6a36d84e bellard
6780 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
6781 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
6782 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
6783 6a36d84e bellard
        }
6784 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
6785 1d14ffa9 bellard
        exit (*optarg != '?');
6786 1d14ffa9 bellard
    }
6787 1d14ffa9 bellard
    else {
6788 6a36d84e bellard
        size_t l;
6789 1d14ffa9 bellard
        const char *p;
6790 1d14ffa9 bellard
        char *e;
6791 1d14ffa9 bellard
        int bad_card = 0;
6792 1d14ffa9 bellard
6793 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
6794 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6795 6a36d84e bellard
                c->enabled = 1;
6796 6a36d84e bellard
            }
6797 6a36d84e bellard
            return;
6798 6a36d84e bellard
        }
6799 1d14ffa9 bellard
6800 6a36d84e bellard
        p = optarg;
6801 1d14ffa9 bellard
        while (*p) {
6802 1d14ffa9 bellard
            e = strchr (p, ',');
6803 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
6804 6a36d84e bellard
6805 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6806 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
6807 6a36d84e bellard
                    c->enabled = 1;
6808 1d14ffa9 bellard
                    break;
6809 1d14ffa9 bellard
                }
6810 1d14ffa9 bellard
            }
6811 6a36d84e bellard
6812 6a36d84e bellard
            if (!c->name) {
6813 1d14ffa9 bellard
                if (l > 80) {
6814 1d14ffa9 bellard
                    fprintf (stderr,
6815 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
6816 1d14ffa9 bellard
                }
6817 1d14ffa9 bellard
                else {
6818 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
6819 1d14ffa9 bellard
                             (int) l, p);
6820 1d14ffa9 bellard
                }
6821 1d14ffa9 bellard
                bad_card = 1;
6822 1d14ffa9 bellard
            }
6823 1d14ffa9 bellard
            p += l + (e != NULL);
6824 1d14ffa9 bellard
        }
6825 1d14ffa9 bellard
6826 1d14ffa9 bellard
        if (bad_card)
6827 1d14ffa9 bellard
            goto show_valid_cards;
6828 1d14ffa9 bellard
    }
6829 1d14ffa9 bellard
}
6830 1d14ffa9 bellard
#endif
6831 1d14ffa9 bellard
6832 3587d7e6 bellard
#ifdef _WIN32
6833 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
6834 3587d7e6 bellard
{
6835 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
6836 3587d7e6 bellard
    return TRUE;
6837 3587d7e6 bellard
}
6838 3587d7e6 bellard
#endif
6839 3587d7e6 bellard
6840 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
6841 c20709aa bellard
6842 0824d6fc bellard
int main(int argc, char **argv)
6843 0824d6fc bellard
{
6844 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6845 cfc3475a pbrook
    int use_gdbstub;
6846 cfc3475a pbrook
    const char *gdbstub_port;
6847 67b915a5 bellard
#endif
6848 cc1daa40 bellard
    int i, cdrom_index;
6849 1ccde1cb bellard
    int snapshot, linux_boot;
6850 7f7f9873 bellard
    const char *initrd_filename;
6851 96d30e48 ths
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
6852 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
6853 313aa567 bellard
    DisplayState *ds = &display_state;
6854 46d4767d bellard
    int cyls, heads, secs, translation;
6855 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
6856 7c9d8e07 bellard
    int nb_net_clients;
6857 cd6f1169 bellard
    int optind;
6858 cd6f1169 bellard
    const char *r, *optarg;
6859 82c643ff bellard
    CharDriverState *monitor_hd;
6860 82c643ff bellard
    char monitor_device[128];
6861 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
6862 8d11df9e bellard
    int serial_device_index;
6863 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
6864 6508fe59 bellard
    int parallel_device_index;
6865 d63d307f bellard
    const char *loadvm = NULL;
6866 cc1daa40 bellard
    QEMUMachine *machine;
6867 94fc95cd j_mayer
    const char *cpu_model;
6868 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
6869 a594cfbf bellard
    int usb_devices_index;
6870 71e3ceb8 ths
    int fds[2];
6871 93815bc2 ths
    const char *pid_file = NULL;
6872 0bd48850 bellard
6873 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
6874 be995c27 bellard
#ifndef _WIN32
6875 be995c27 bellard
    {
6876 be995c27 bellard
        struct sigaction act;
6877 be995c27 bellard
        sigfillset(&act.sa_mask);
6878 be995c27 bellard
        act.sa_flags = 0;
6879 be995c27 bellard
        act.sa_handler = SIG_IGN;
6880 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
6881 be995c27 bellard
    }
6882 3587d7e6 bellard
#else
6883 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
6884 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
6885 a8e5ac33 bellard
       QEMU to run on a single CPU */
6886 a8e5ac33 bellard
    {
6887 a8e5ac33 bellard
        HANDLE h;
6888 a8e5ac33 bellard
        DWORD mask, smask;
6889 a8e5ac33 bellard
        int i;
6890 a8e5ac33 bellard
        h = GetCurrentProcess();
6891 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
6892 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
6893 a8e5ac33 bellard
                if (mask & (1 << i))
6894 a8e5ac33 bellard
                    break;
6895 a8e5ac33 bellard
            }
6896 a8e5ac33 bellard
            if (i != 32) {
6897 a8e5ac33 bellard
                mask = 1 << i;
6898 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
6899 a8e5ac33 bellard
            }
6900 a8e5ac33 bellard
        }
6901 a8e5ac33 bellard
    }
6902 67b915a5 bellard
#endif
6903 be995c27 bellard
6904 cc1daa40 bellard
    register_machines();
6905 cc1daa40 bellard
    machine = first_machine;
6906 94fc95cd j_mayer
    cpu_model = NULL;
6907 fc01f7e7 bellard
    initrd_filename = NULL;
6908 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
6909 c45886db bellard
        fd_filename[i] = NULL;
6910 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++)
6911 96d30e48 ths
        hd_filename[i] = NULL;
6912 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
6913 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
6914 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6915 b4608c04 bellard
    use_gdbstub = 0;
6916 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
6917 67b915a5 bellard
#endif
6918 33e3963e bellard
    snapshot = 0;
6919 a20dd508 bellard
    nographic = 0;
6920 a20dd508 bellard
    kernel_filename = NULL;
6921 a20dd508 bellard
    kernel_cmdline = "";
6922 cc1daa40 bellard
#ifdef TARGET_PPC
6923 cc1daa40 bellard
    cdrom_index = 1;
6924 cc1daa40 bellard
#else
6925 cc1daa40 bellard
    cdrom_index = 2;
6926 cc1daa40 bellard
#endif
6927 c4b1fcc0 bellard
    cyls = heads = secs = 0;
6928 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
6929 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
6930 c4b1fcc0 bellard
6931 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
6932 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
6933 8d11df9e bellard
        serial_devices[i][0] = '\0';
6934 8d11df9e bellard
    serial_device_index = 0;
6935 8d11df9e bellard
    
6936 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
6937 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
6938 6508fe59 bellard
        parallel_devices[i][0] = '\0';
6939 6508fe59 bellard
    parallel_device_index = 0;
6940 6508fe59 bellard
    
6941 a594cfbf bellard
    usb_devices_index = 0;
6942 a594cfbf bellard
    
6943 7c9d8e07 bellard
    nb_net_clients = 0;
6944 7c9d8e07 bellard
6945 7c9d8e07 bellard
    nb_nics = 0;
6946 702c651c bellard
    /* default mac address of the first network interface */
6947 82c643ff bellard
    
6948 cd6f1169 bellard
    optind = 1;
6949 0824d6fc bellard
    for(;;) {
6950 cd6f1169 bellard
        if (optind >= argc)
6951 0824d6fc bellard
            break;
6952 cd6f1169 bellard
        r = argv[optind];
6953 cd6f1169 bellard
        if (r[0] != '-') {
6954 96d30e48 ths
            hd_filename[0] = argv[optind++];
6955 cd6f1169 bellard
        } else {
6956 cd6f1169 bellard
            const QEMUOption *popt;
6957 cd6f1169 bellard
6958 cd6f1169 bellard
            optind++;
6959 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
6960 dff5efc8 pbrook
            if (r[1] == '-')
6961 dff5efc8 pbrook
                r++;
6962 cd6f1169 bellard
            popt = qemu_options;
6963 cd6f1169 bellard
            for(;;) {
6964 cd6f1169 bellard
                if (!popt->name) {
6965 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
6966 cd6f1169 bellard
                            argv[0], r);
6967 cd6f1169 bellard
                    exit(1);
6968 cd6f1169 bellard
                }
6969 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
6970 cd6f1169 bellard
                    break;
6971 cd6f1169 bellard
                popt++;
6972 cd6f1169 bellard
            }
6973 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
6974 cd6f1169 bellard
                if (optind >= argc) {
6975 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
6976 cd6f1169 bellard
                            argv[0], r);
6977 cd6f1169 bellard
                    exit(1);
6978 cd6f1169 bellard
                }
6979 cd6f1169 bellard
                optarg = argv[optind++];
6980 cd6f1169 bellard
            } else {
6981 cd6f1169 bellard
                optarg = NULL;
6982 cd6f1169 bellard
            }
6983 cd6f1169 bellard
6984 cd6f1169 bellard
            switch(popt->index) {
6985 cc1daa40 bellard
            case QEMU_OPTION_M:
6986 cc1daa40 bellard
                machine = find_machine(optarg);
6987 cc1daa40 bellard
                if (!machine) {
6988 cc1daa40 bellard
                    QEMUMachine *m;
6989 cc1daa40 bellard
                    printf("Supported machines are:\n");
6990 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
6991 cc1daa40 bellard
                        printf("%-10s %s%s\n",
6992 cc1daa40 bellard
                               m->name, m->desc, 
6993 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
6994 cc1daa40 bellard
                    }
6995 cc1daa40 bellard
                    exit(1);
6996 cc1daa40 bellard
                }
6997 cc1daa40 bellard
                break;
6998 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
6999 94fc95cd j_mayer
                /* hw initialization will check this */
7000 94fc95cd j_mayer
                if (optarg[0] == '?') {
7001 94fc95cd j_mayer
#if defined(TARGET_PPC)
7002 94fc95cd j_mayer
                    ppc_cpu_list(stdout, &fprintf);
7003 5adb4839 pbrook
#elif defined(TARGET_ARM)
7004 5adb4839 pbrook
                    arm_cpu_list();
7005 33d68b5f ths
#elif defined(TARGET_MIPS)
7006 33d68b5f ths
                    mips_cpu_list(stdout, &fprintf);
7007 94fc95cd j_mayer
#endif
7008 94fc95cd j_mayer
                    exit(1);
7009 94fc95cd j_mayer
                } else {
7010 94fc95cd j_mayer
                    cpu_model = optarg;
7011 94fc95cd j_mayer
                }
7012 94fc95cd j_mayer
                break;
7013 cd6f1169 bellard
            case QEMU_OPTION_initrd:
7014 fc01f7e7 bellard
                initrd_filename = optarg;
7015 fc01f7e7 bellard
                break;
7016 cd6f1169 bellard
            case QEMU_OPTION_hda:
7017 cd6f1169 bellard
            case QEMU_OPTION_hdb:
7018 cc1daa40 bellard
            case QEMU_OPTION_hdc:
7019 cc1daa40 bellard
            case QEMU_OPTION_hdd:
7020 cc1daa40 bellard
                {
7021 cc1daa40 bellard
                    int hd_index;
7022 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
7023 96d30e48 ths
                    hd_filename[hd_index] = optarg;
7024 96d30e48 ths
                    if (hd_index == cdrom_index)
7025 96d30e48 ths
                        cdrom_index = -1;
7026 cc1daa40 bellard
                }
7027 fc01f7e7 bellard
                break;
7028 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
7029 33e3963e bellard
                snapshot = 1;
7030 33e3963e bellard
                break;
7031 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
7032 330d0414 bellard
                {
7033 330d0414 bellard
                    const char *p;
7034 330d0414 bellard
                    p = optarg;
7035 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
7036 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
7037 46d4767d bellard
                        goto chs_fail;
7038 330d0414 bellard
                    if (*p != ',')
7039 330d0414 bellard
                        goto chs_fail;
7040 330d0414 bellard
                    p++;
7041 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
7042 46d4767d bellard
                    if (heads < 1 || heads > 16)
7043 46d4767d bellard
                        goto chs_fail;
7044 330d0414 bellard
                    if (*p != ',')
7045 330d0414 bellard
                        goto chs_fail;
7046 330d0414 bellard
                    p++;
7047 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
7048 46d4767d bellard
                    if (secs < 1 || secs > 63)
7049 46d4767d bellard
                        goto chs_fail;
7050 46d4767d bellard
                    if (*p == ',') {
7051 46d4767d bellard
                        p++;
7052 46d4767d bellard
                        if (!strcmp(p, "none"))
7053 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
7054 46d4767d bellard
                        else if (!strcmp(p, "lba"))
7055 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
7056 46d4767d bellard
                        else if (!strcmp(p, "auto"))
7057 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
7058 46d4767d bellard
                        else
7059 46d4767d bellard
                            goto chs_fail;
7060 46d4767d bellard
                    } else if (*p != '\0') {
7061 c4b1fcc0 bellard
                    chs_fail:
7062 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
7063 46d4767d bellard
                        exit(1);
7064 c4b1fcc0 bellard
                    }
7065 330d0414 bellard
                }
7066 330d0414 bellard
                break;
7067 cd6f1169 bellard
            case QEMU_OPTION_nographic:
7068 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
7069 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
7070 a20dd508 bellard
                nographic = 1;
7071 a20dd508 bellard
                break;
7072 cd6f1169 bellard
            case QEMU_OPTION_kernel:
7073 a20dd508 bellard
                kernel_filename = optarg;
7074 a20dd508 bellard
                break;
7075 cd6f1169 bellard
            case QEMU_OPTION_append:
7076 a20dd508 bellard
                kernel_cmdline = optarg;
7077 313aa567 bellard
                break;
7078 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
7079 96d30e48 ths
                if (cdrom_index >= 0) {
7080 96d30e48 ths
                    hd_filename[cdrom_index] = optarg;
7081 fa1fb14c ths
                }
7082 36b486bb bellard
                break;
7083 cd6f1169 bellard
            case QEMU_OPTION_boot:
7084 36b486bb bellard
                boot_device = optarg[0];
7085 9e89a4be bellard
                if (boot_device != 'a' && 
7086 eec85c2a ths
#if defined(TARGET_SPARC) || defined(TARGET_I386)
7087 6f7e9aec bellard
                    // Network boot
7088 6f7e9aec bellard
                    boot_device != 'n' &&
7089 6f7e9aec bellard
#endif
7090 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
7091 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
7092 36b486bb bellard
                    exit(1);
7093 36b486bb bellard
                }
7094 36b486bb bellard
                break;
7095 cd6f1169 bellard
            case QEMU_OPTION_fda:
7096 c45886db bellard
                fd_filename[0] = optarg;
7097 c45886db bellard
                break;
7098 cd6f1169 bellard
            case QEMU_OPTION_fdb:
7099 c45886db bellard
                fd_filename[1] = optarg;
7100 c45886db bellard
                break;
7101 52ca8d6a bellard
#ifdef TARGET_I386
7102 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
7103 52ca8d6a bellard
                fd_bootchk = 0;
7104 52ca8d6a bellard
                break;
7105 52ca8d6a bellard
#endif
7106 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
7107 77fef8c1 bellard
                code_copy_enabled = 0;
7108 77fef8c1 bellard
                break;
7109 7c9d8e07 bellard
            case QEMU_OPTION_net:
7110 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
7111 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
7112 c4b1fcc0 bellard
                    exit(1);
7113 c4b1fcc0 bellard
                }
7114 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
7115 7c9d8e07 bellard
                        sizeof(net_clients[0]),
7116 7c9d8e07 bellard
                        optarg);
7117 7c9d8e07 bellard
                nb_net_clients++;
7118 702c651c bellard
                break;
7119 c7f74643 bellard
#ifdef CONFIG_SLIRP
7120 c7f74643 bellard
            case QEMU_OPTION_tftp:
7121 c7f74643 bellard
                tftp_prefix = optarg;
7122 9bf05444 bellard
                break;
7123 47d5d01a ths
            case QEMU_OPTION_bootp:
7124 47d5d01a ths
                bootp_filename = optarg;
7125 47d5d01a ths
                break;
7126 c94c8d64 bellard
#ifndef _WIN32
7127 9d728e8c bellard
            case QEMU_OPTION_smb:
7128 9d728e8c bellard
                net_slirp_smb(optarg);
7129 9d728e8c bellard
                break;
7130 c94c8d64 bellard
#endif
7131 9bf05444 bellard
            case QEMU_OPTION_redir:
7132 9bf05444 bellard
                net_slirp_redir(optarg);                
7133 9bf05444 bellard
                break;
7134 c7f74643 bellard
#endif
7135 1d14ffa9 bellard
#ifdef HAS_AUDIO
7136 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
7137 1d14ffa9 bellard
                AUD_help ();
7138 1d14ffa9 bellard
                exit (0);
7139 1d14ffa9 bellard
                break;
7140 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
7141 1d14ffa9 bellard
                select_soundhw (optarg);
7142 1d14ffa9 bellard
                break;
7143 1d14ffa9 bellard
#endif
7144 cd6f1169 bellard
            case QEMU_OPTION_h:
7145 0824d6fc bellard
                help();
7146 cd6f1169 bellard
                break;
7147 cd6f1169 bellard
            case QEMU_OPTION_m:
7148 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
7149 cd6f1169 bellard
                if (ram_size <= 0)
7150 cd6f1169 bellard
                    help();
7151 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
7152 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
7153 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
7154 cd6f1169 bellard
                    exit(1);
7155 cd6f1169 bellard
                }
7156 cd6f1169 bellard
                break;
7157 cd6f1169 bellard
            case QEMU_OPTION_d:
7158 cd6f1169 bellard
                {
7159 cd6f1169 bellard
                    int mask;
7160 cd6f1169 bellard
                    CPULogItem *item;
7161 cd6f1169 bellard
                    
7162 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
7163 cd6f1169 bellard
                    if (!mask) {
7164 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
7165 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
7166 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
7167 f193c797 bellard
                    }
7168 f193c797 bellard
                    exit(1);
7169 cd6f1169 bellard
                    }
7170 cd6f1169 bellard
                    cpu_set_log(mask);
7171 f193c797 bellard
                }
7172 cd6f1169 bellard
                break;
7173 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7174 cd6f1169 bellard
            case QEMU_OPTION_s:
7175 cd6f1169 bellard
                use_gdbstub = 1;
7176 cd6f1169 bellard
                break;
7177 cd6f1169 bellard
            case QEMU_OPTION_p:
7178 cfc3475a pbrook
                gdbstub_port = optarg;
7179 cd6f1169 bellard
                break;
7180 67b915a5 bellard
#endif
7181 cd6f1169 bellard
            case QEMU_OPTION_L:
7182 cd6f1169 bellard
                bios_dir = optarg;
7183 cd6f1169 bellard
                break;
7184 cd6f1169 bellard
            case QEMU_OPTION_S:
7185 3c07f8e8 pbrook
                autostart = 0;
7186 cd6f1169 bellard
                break;
7187 3d11d0eb bellard
            case QEMU_OPTION_k:
7188 3d11d0eb bellard
                keyboard_layout = optarg;
7189 3d11d0eb bellard
                break;
7190 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
7191 ee22c2f7 bellard
                rtc_utc = 0;
7192 ee22c2f7 bellard
                break;
7193 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
7194 1f04275e bellard
                cirrus_vga_enabled = 1;
7195 1f04275e bellard
                break;
7196 1bfe856e bellard
            case QEMU_OPTION_std_vga:
7197 1bfe856e bellard
                cirrus_vga_enabled = 0;
7198 1bfe856e bellard
                break;
7199 e9b137c2 bellard
            case QEMU_OPTION_g:
7200 e9b137c2 bellard
                {
7201 e9b137c2 bellard
                    const char *p;
7202 e9b137c2 bellard
                    int w, h, depth;
7203 e9b137c2 bellard
                    p = optarg;
7204 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
7205 e9b137c2 bellard
                    if (w <= 0) {
7206 e9b137c2 bellard
                    graphic_error:
7207 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
7208 e9b137c2 bellard
                        exit(1);
7209 e9b137c2 bellard
                    }
7210 e9b137c2 bellard
                    if (*p != 'x')
7211 e9b137c2 bellard
                        goto graphic_error;
7212 e9b137c2 bellard
                    p++;
7213 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
7214 e9b137c2 bellard
                    if (h <= 0)
7215 e9b137c2 bellard
                        goto graphic_error;
7216 e9b137c2 bellard
                    if (*p == 'x') {
7217 e9b137c2 bellard
                        p++;
7218 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
7219 e9b137c2 bellard
                        if (depth != 8 && depth != 15 && depth != 16 && 
7220 e9b137c2 bellard
                            depth != 24 && depth != 32)
7221 e9b137c2 bellard
                            goto graphic_error;
7222 e9b137c2 bellard
                    } else if (*p == '\0') {
7223 e9b137c2 bellard
                        depth = graphic_depth;
7224 e9b137c2 bellard
                    } else {
7225 e9b137c2 bellard
                        goto graphic_error;
7226 e9b137c2 bellard
                    }
7227 e9b137c2 bellard
                    
7228 e9b137c2 bellard
                    graphic_width = w;
7229 e9b137c2 bellard
                    graphic_height = h;
7230 e9b137c2 bellard
                    graphic_depth = depth;
7231 e9b137c2 bellard
                }
7232 e9b137c2 bellard
                break;
7233 20d8a3ed ths
            case QEMU_OPTION_echr:
7234 20d8a3ed ths
                {
7235 20d8a3ed ths
                    char *r;
7236 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
7237 20d8a3ed ths
                    if (r == optarg)
7238 20d8a3ed ths
                        printf("Bad argument to echr\n");
7239 20d8a3ed ths
                    break;
7240 20d8a3ed ths
                }
7241 82c643ff bellard
            case QEMU_OPTION_monitor:
7242 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
7243 82c643ff bellard
                break;
7244 82c643ff bellard
            case QEMU_OPTION_serial:
7245 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
7246 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
7247 8d11df9e bellard
                    exit(1);
7248 8d11df9e bellard
                }
7249 8d11df9e bellard
                pstrcpy(serial_devices[serial_device_index], 
7250 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
7251 8d11df9e bellard
                serial_device_index++;
7252 82c643ff bellard
                break;
7253 6508fe59 bellard
            case QEMU_OPTION_parallel:
7254 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
7255 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
7256 6508fe59 bellard
                    exit(1);
7257 6508fe59 bellard
                }
7258 6508fe59 bellard
                pstrcpy(parallel_devices[parallel_device_index], 
7259 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
7260 6508fe59 bellard
                parallel_device_index++;
7261 6508fe59 bellard
                break;
7262 d63d307f bellard
            case QEMU_OPTION_loadvm:
7263 d63d307f bellard
                loadvm = optarg;
7264 d63d307f bellard
                break;
7265 d63d307f bellard
            case QEMU_OPTION_full_screen:
7266 d63d307f bellard
                full_screen = 1;
7267 d63d307f bellard
                break;
7268 667accab ths
#ifdef CONFIG_SDL
7269 43523e93 ths
            case QEMU_OPTION_no_frame:
7270 43523e93 ths
                no_frame = 1;
7271 43523e93 ths
                break;
7272 667accab ths
            case QEMU_OPTION_no_quit:
7273 667accab ths
                no_quit = 1;
7274 667accab ths
                break;
7275 667accab ths
#endif
7276 f7cce898 bellard
            case QEMU_OPTION_pidfile:
7277 93815bc2 ths
                pid_file = optarg;
7278 f7cce898 bellard
                break;
7279 a09db21f bellard
#ifdef TARGET_I386
7280 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
7281 a09db21f bellard
                win2k_install_hack = 1;
7282 a09db21f bellard
                break;
7283 a09db21f bellard
#endif
7284 d993e026 bellard
#ifdef USE_KQEMU
7285 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
7286 d993e026 bellard
                kqemu_allowed = 0;
7287 d993e026 bellard
                break;
7288 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
7289 89bfc105 bellard
                kqemu_allowed = 2;
7290 89bfc105 bellard
                break;
7291 d993e026 bellard
#endif
7292 bb36d470 bellard
            case QEMU_OPTION_usb:
7293 bb36d470 bellard
                usb_enabled = 1;
7294 bb36d470 bellard
                break;
7295 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
7296 a594cfbf bellard
                usb_enabled = 1;
7297 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
7298 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
7299 a594cfbf bellard
                    exit(1);
7300 a594cfbf bellard
                }
7301 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
7302 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
7303 a594cfbf bellard
                        optarg);
7304 a594cfbf bellard
                usb_devices_index++;
7305 a594cfbf bellard
                break;
7306 6a00d601 bellard
            case QEMU_OPTION_smp:
7307 6a00d601 bellard
                smp_cpus = atoi(optarg);
7308 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
7309 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
7310 6a00d601 bellard
                    exit(1);
7311 6a00d601 bellard
                }
7312 6a00d601 bellard
                break;
7313 24236869 bellard
            case QEMU_OPTION_vnc:
7314 73fc9742 ths
                vnc_display = optarg;
7315 24236869 bellard
                break;
7316 6515b203 bellard
            case QEMU_OPTION_no_acpi:
7317 6515b203 bellard
                acpi_enabled = 0;
7318 6515b203 bellard
                break;
7319 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
7320 d1beab82 bellard
                no_reboot = 1;
7321 d1beab82 bellard
                break;
7322 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
7323 71e3ceb8 ths
                daemonize = 1;
7324 71e3ceb8 ths
                break;
7325 9ae02555 ths
            case QEMU_OPTION_option_rom:
7326 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
7327 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
7328 9ae02555 ths
                    exit(1);
7329 9ae02555 ths
                }
7330 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
7331 9ae02555 ths
                nb_option_roms++;
7332 9ae02555 ths
                break;
7333 8e71621f pbrook
            case QEMU_OPTION_semihosting:
7334 8e71621f pbrook
                semihosting_enabled = 1;
7335 8e71621f pbrook
                break;
7336 c35734b2 ths
            case QEMU_OPTION_name:
7337 c35734b2 ths
                qemu_name = optarg;
7338 c35734b2 ths
                break;
7339 cd6f1169 bellard
            }
7340 0824d6fc bellard
        }
7341 0824d6fc bellard
    }
7342 330d0414 bellard
7343 71e3ceb8 ths
#ifndef _WIN32
7344 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
7345 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
7346 71e3ceb8 ths
        daemonize = 0;
7347 71e3ceb8 ths
    }
7348 71e3ceb8 ths
7349 71e3ceb8 ths
    if (daemonize) {
7350 71e3ceb8 ths
        pid_t pid;
7351 71e3ceb8 ths
7352 71e3ceb8 ths
        if (pipe(fds) == -1)
7353 71e3ceb8 ths
            exit(1);
7354 71e3ceb8 ths
7355 71e3ceb8 ths
        pid = fork();
7356 71e3ceb8 ths
        if (pid > 0) {
7357 71e3ceb8 ths
            uint8_t status;
7358 71e3ceb8 ths
            ssize_t len;
7359 71e3ceb8 ths
7360 71e3ceb8 ths
            close(fds[1]);
7361 71e3ceb8 ths
7362 71e3ceb8 ths
        again:
7363 93815bc2 ths
            len = read(fds[0], &status, 1);
7364 93815bc2 ths
            if (len == -1 && (errno == EINTR))
7365 93815bc2 ths
                goto again;
7366 93815bc2 ths
7367 93815bc2 ths
            if (len != 1)
7368 93815bc2 ths
                exit(1);
7369 93815bc2 ths
            else if (status == 1) {
7370 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
7371 93815bc2 ths
                exit(1);
7372 93815bc2 ths
            } else
7373 93815bc2 ths
                exit(0);
7374 71e3ceb8 ths
        } else if (pid < 0)
7375 93815bc2 ths
            exit(1);
7376 71e3ceb8 ths
7377 71e3ceb8 ths
        setsid();
7378 71e3ceb8 ths
7379 71e3ceb8 ths
        pid = fork();
7380 71e3ceb8 ths
        if (pid > 0)
7381 71e3ceb8 ths
            exit(0);
7382 71e3ceb8 ths
        else if (pid < 0)
7383 71e3ceb8 ths
            exit(1);
7384 71e3ceb8 ths
7385 71e3ceb8 ths
        umask(027);
7386 71e3ceb8 ths
        chdir("/");
7387 71e3ceb8 ths
7388 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
7389 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
7390 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
7391 71e3ceb8 ths
    }
7392 71e3ceb8 ths
#endif
7393 71e3ceb8 ths
7394 93815bc2 ths
    if (pid_file && create_pidfile(pid_file) != 0) {
7395 93815bc2 ths
        if (daemonize) {
7396 93815bc2 ths
            uint8_t status = 1;
7397 93815bc2 ths
            write(fds[1], &status, 1);
7398 93815bc2 ths
        } else
7399 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
7400 93815bc2 ths
        exit(1);
7401 93815bc2 ths
    }
7402 93815bc2 ths
7403 ff3fbb30 bellard
#ifdef USE_KQEMU
7404 ff3fbb30 bellard
    if (smp_cpus > 1)
7405 ff3fbb30 bellard
        kqemu_allowed = 0;
7406 ff3fbb30 bellard
#endif
7407 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
7408 42550fde ths
7409 42550fde ths
    if (!linux_boot &&
7410 d84fe7ae ths
        boot_device != 'n' &&
7411 96d30e48 ths
        hd_filename[0] == '\0' && 
7412 96d30e48 ths
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
7413 c45886db bellard
        fd_filename[0] == '\0')
7414 0824d6fc bellard
        help();
7415 0824d6fc bellard
7416 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
7417 96d30e48 ths
    if (hd_filename[0] == '\0' && boot_device == 'c') {
7418 96d30e48 ths
        if (fd_filename[0] != '\0')
7419 96d30e48 ths
            boot_device = 'a';
7420 96d30e48 ths
        else
7421 96d30e48 ths
            boot_device = 'd';
7422 96d30e48 ths
    }
7423 96d30e48 ths
7424 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
7425 7c9d8e07 bellard
    
7426 634fce96 pbrook
    init_timers();
7427 634fce96 pbrook
    init_timer_alarm();
7428 83f64091 bellard
    qemu_aio_init();
7429 634fce96 pbrook
7430 fd1dff4b bellard
#ifdef _WIN32
7431 fd1dff4b bellard
    socket_init();
7432 fd1dff4b bellard
#endif
7433 fd1dff4b bellard
7434 7c9d8e07 bellard
    /* init network clients */
7435 7c9d8e07 bellard
    if (nb_net_clients == 0) {
7436 7c9d8e07 bellard
        /* if no clients, we use a default config */
7437 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
7438 7c9d8e07 bellard
                "nic");
7439 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
7440 7c9d8e07 bellard
                "user");
7441 7c9d8e07 bellard
        nb_net_clients = 2;
7442 c20709aa bellard
    }
7443 c20709aa bellard
7444 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
7445 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
7446 7c9d8e07 bellard
            exit(1);
7447 702c651c bellard
    }
7448 f1510b2c bellard
7449 eec85c2a ths
#ifdef TARGET_I386
7450 eec85c2a ths
    if (boot_device == 'n') {
7451 eec85c2a ths
        for (i = 0; i < nb_nics; i++) {
7452 eec85c2a ths
            const char *model = nd_table[i].model;
7453 eec85c2a ths
            char buf[1024];
7454 eec85c2a ths
            if (model == NULL)
7455 eec85c2a ths
                model = "ne2k_pci";
7456 eec85c2a ths
            snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
7457 eec85c2a ths
            if (get_image_size(buf) > 0) {
7458 eec85c2a ths
                option_rom[nb_option_roms] = strdup(buf);
7459 eec85c2a ths
                nb_option_roms++;
7460 eec85c2a ths
                break;
7461 eec85c2a ths
            }
7462 eec85c2a ths
        }
7463 eec85c2a ths
        if (i == nb_nics) {
7464 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
7465 eec85c2a ths
            exit(1);
7466 eec85c2a ths
        }
7467 eec85c2a ths
        boot_device = 'c'; /* to prevent confusion by the BIOS */
7468 eec85c2a ths
    }
7469 eec85c2a ths
#endif
7470 eec85c2a ths
7471 0824d6fc bellard
    /* init the memory */
7472 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
7473 9ae02555 ths
7474 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
7475 7f7f9873 bellard
    if (!phys_ram_base) {
7476 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
7477 0824d6fc bellard
        exit(1);
7478 0824d6fc bellard
    }
7479 0824d6fc bellard
7480 96d30e48 ths
    /* we always create the cdrom drive, even if no disk is there */
7481 5905b2e5 bellard
    bdrv_init();
7482 96d30e48 ths
    if (cdrom_index >= 0) {
7483 96d30e48 ths
        bs_table[cdrom_index] = bdrv_new("cdrom");
7484 96d30e48 ths
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
7485 c4b1fcc0 bellard
    }
7486 c4b1fcc0 bellard
7487 96d30e48 ths
    /* open the virtual block devices */
7488 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++) {
7489 96d30e48 ths
        if (hd_filename[i]) {
7490 96d30e48 ths
            if (!bs_table[i]) {
7491 96d30e48 ths
                char buf[64];
7492 96d30e48 ths
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
7493 96d30e48 ths
                bs_table[i] = bdrv_new(buf);
7494 96d30e48 ths
            }
7495 96d30e48 ths
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7496 96d30e48 ths
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
7497 96d30e48 ths
                        hd_filename[i]);
7498 96d30e48 ths
                exit(1);
7499 96d30e48 ths
            }
7500 96d30e48 ths
            if (i == 0 && cyls != 0) {
7501 96d30e48 ths
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
7502 96d30e48 ths
                bdrv_set_translation_hint(bs_table[i], translation);
7503 96d30e48 ths
            }
7504 96d30e48 ths
        }
7505 c4b1fcc0 bellard
    }
7506 c4b1fcc0 bellard
7507 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
7508 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
7509 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
7510 c4b1fcc0 bellard
7511 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
7512 c4b1fcc0 bellard
        if (fd_filename[i]) {
7513 c4b1fcc0 bellard
            if (!fd_table[i]) {
7514 c4b1fcc0 bellard
                char buf[64];
7515 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
7516 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
7517 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
7518 c4b1fcc0 bellard
            }
7519 c4b1fcc0 bellard
            if (fd_filename[i] != '\0') {
7520 83f64091 bellard
                if (bdrv_open(fd_table[i], fd_filename[i],
7521 83f64091 bellard
                              snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7522 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
7523 c4b1fcc0 bellard
                            fd_filename[i]);
7524 c4b1fcc0 bellard
                    exit(1);
7525 c4b1fcc0 bellard
                }
7526 c4b1fcc0 bellard
            }
7527 33e3963e bellard
        }
7528 33e3963e bellard
    }
7529 33e3963e bellard
7530 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
7531 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
7532 8a7ddc38 bellard
7533 330d0414 bellard
    init_ioports();
7534 0824d6fc bellard
7535 313aa567 bellard
    /* terminal init */
7536 a20dd508 bellard
    if (nographic) {
7537 313aa567 bellard
        dumb_display_init(ds);
7538 73fc9742 ths
    } else if (vnc_display != NULL) {
7539 24236869 bellard
        vnc_display_init(ds, vnc_display);
7540 313aa567 bellard
    } else {
7541 5b0753e0 bellard
#if defined(CONFIG_SDL)
7542 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
7543 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
7544 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
7545 313aa567 bellard
#else
7546 313aa567 bellard
        dumb_display_init(ds);
7547 313aa567 bellard
#endif
7548 313aa567 bellard
    }
7549 0824d6fc bellard
7550 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
7551 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
7552 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
7553 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
7554 20d8a3ed ths
                monitor_device[0] = '\0';
7555 20d8a3ed ths
                break;
7556 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
7557 20d8a3ed ths
                monitor_device[0] = '\0';
7558 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
7559 20d8a3ed ths
                break;
7560 20d8a3ed ths
            }
7561 20d8a3ed ths
        }
7562 20d8a3ed ths
    }
7563 20d8a3ed ths
    if (monitor_device[0] != '\0') {
7564 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
7565 20d8a3ed ths
        if (!monitor_hd) {
7566 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
7567 20d8a3ed ths
            exit(1);
7568 20d8a3ed ths
        }
7569 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
7570 82c643ff bellard
    }
7571 82c643ff bellard
7572 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
7573 c03b0f0f bellard
        const char *devname = serial_devices[i];
7574 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7575 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
7576 8d11df9e bellard
            if (!serial_hds[i]) {
7577 8d11df9e bellard
                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
7578 c03b0f0f bellard
                        devname);
7579 8d11df9e bellard
                exit(1);
7580 8d11df9e bellard
            }
7581 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7582 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
7583 8d11df9e bellard
        }
7584 82c643ff bellard
    }
7585 82c643ff bellard
7586 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
7587 c03b0f0f bellard
        const char *devname = parallel_devices[i];
7588 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7589 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
7590 6508fe59 bellard
            if (!parallel_hds[i]) {
7591 6508fe59 bellard
                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
7592 c03b0f0f bellard
                        devname);
7593 6508fe59 bellard
                exit(1);
7594 6508fe59 bellard
            }
7595 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7596 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
7597 6508fe59 bellard
        }
7598 6508fe59 bellard
    }
7599 6508fe59 bellard
7600 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
7601 cc1daa40 bellard
                  ds, fd_filename, snapshot,
7602 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
7603 73332e5c bellard
7604 0d92ed30 pbrook
    /* init USB devices */
7605 0d92ed30 pbrook
    if (usb_enabled) {
7606 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
7607 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
7608 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
7609 0d92ed30 pbrook
                        usb_devices[i]);
7610 0d92ed30 pbrook
            }
7611 0d92ed30 pbrook
        }
7612 0d92ed30 pbrook
    }
7613 0d92ed30 pbrook
7614 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
7615 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
7616 7f7f9873 bellard
7617 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7618 b4608c04 bellard
    if (use_gdbstub) {
7619 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
7620 c636bb66 bellard
           accordingly. */
7621 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
7622 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
7623 c636bb66 bellard
                    gdbstub_port);
7624 8a7ddc38 bellard
            exit(1);
7625 8a7ddc38 bellard
        }
7626 67b915a5 bellard
    } else 
7627 67b915a5 bellard
#endif
7628 d63d307f bellard
    if (loadvm)
7629 faea38e7 bellard
        do_loadvm(loadvm);
7630 d63d307f bellard
7631 67b915a5 bellard
    {
7632 5905b2e5 bellard
        /* XXX: simplify init */
7633 5905b2e5 bellard
        read_passwords();
7634 3c07f8e8 pbrook
        if (autostart) {
7635 5905b2e5 bellard
            vm_start();
7636 5905b2e5 bellard
        }
7637 0824d6fc bellard
    }
7638 ffd843bc ths
7639 71e3ceb8 ths
    if (daemonize) {
7640 71e3ceb8 ths
        uint8_t status = 0;
7641 71e3ceb8 ths
        ssize_t len;
7642 71e3ceb8 ths
        int fd;
7643 71e3ceb8 ths
7644 71e3ceb8 ths
    again1:
7645 71e3ceb8 ths
        len = write(fds[1], &status, 1);
7646 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
7647 71e3ceb8 ths
            goto again1;
7648 71e3ceb8 ths
7649 71e3ceb8 ths
        if (len != 1)
7650 71e3ceb8 ths
            exit(1);
7651 71e3ceb8 ths
7652 71e3ceb8 ths
        fd = open("/dev/null", O_RDWR);
7653 71e3ceb8 ths
        if (fd == -1)
7654 71e3ceb8 ths
            exit(1);
7655 71e3ceb8 ths
7656 71e3ceb8 ths
        dup2(fd, 0);
7657 71e3ceb8 ths
        dup2(fd, 1);
7658 71e3ceb8 ths
        dup2(fd, 2);
7659 71e3ceb8 ths
7660 71e3ceb8 ths
        close(fd);
7661 71e3ceb8 ths
    }
7662 71e3ceb8 ths
7663 8a7ddc38 bellard
    main_loop();
7664 40c3bac3 bellard
    quit_timers();
7665 0824d6fc bellard
    return 0;
7666 0824d6fc bellard
}