Statistics
| Branch: | Revision:

root / vl.c @ 5867c88a

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

5731 c88676f8 bellard
            /* find if the memory block is available on a virtual
5732 c88676f8 bellard
               block device */
5733 c88676f8 bellard
            sector_num = -1;
5734 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5735 c88676f8 bellard
                if (bs_table[j]) {
5736 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5737 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5738 c88676f8 bellard
                    if (sector_num >= 0)
5739 c88676f8 bellard
                        break;
5740 c88676f8 bellard
                }
5741 c88676f8 bellard
            }
5742 c88676f8 bellard
            if (j == MAX_DISKS)
5743 c88676f8 bellard
                goto normal_compress;
5744 c88676f8 bellard
            buf[0] = 1;
5745 c88676f8 bellard
            buf[1] = j;
5746 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5747 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5748 c88676f8 bellard
        } else 
5749 c88676f8 bellard
#endif
5750 c88676f8 bellard
        {
5751 c88676f8 bellard
            //        normal_compress:
5752 c88676f8 bellard
            buf[0] = 0;
5753 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5754 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5755 c88676f8 bellard
        }
5756 8a7ddc38 bellard
    }
5757 c88676f8 bellard
    ram_compress_close(s);
5758 8a7ddc38 bellard
}
5759 8a7ddc38 bellard
5760 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5761 8a7ddc38 bellard
{
5762 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5763 c88676f8 bellard
    uint8_t buf[10];
5764 c88676f8 bellard
    int i;
5765 8a7ddc38 bellard
5766 c88676f8 bellard
    if (version_id == 1)
5767 c88676f8 bellard
        return ram_load_v1(f, opaque);
5768 c88676f8 bellard
    if (version_id != 2)
5769 8a7ddc38 bellard
        return -EINVAL;
5770 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5771 8a7ddc38 bellard
        return -EINVAL;
5772 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5773 c88676f8 bellard
        return -EINVAL;
5774 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5775 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5776 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5777 c88676f8 bellard
            goto error;
5778 c88676f8 bellard
        }
5779 c88676f8 bellard
        if (buf[0] == 0) {
5780 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5781 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5782 c88676f8 bellard
                goto error;
5783 c88676f8 bellard
            }
5784 c88676f8 bellard
        } else 
5785 c88676f8 bellard
#if 0
5786 c88676f8 bellard
        if (buf[0] == 1) {
5787 c88676f8 bellard
            int bs_index;
5788 c88676f8 bellard
            int64_t sector_num;
5789 c88676f8 bellard

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