Statistics
| Branch: | Revision:

root / vl.c @ 39d51eb8

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

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

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