Statistics
| Branch: | Revision:

root / vl.c @ 01d6a890

History | View | Annotate | Download (183.8 kB)

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

5500 c88676f8 bellard
            /* find if the memory block is available on a virtual
5501 c88676f8 bellard
               block device */
5502 c88676f8 bellard
            sector_num = -1;
5503 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5504 c88676f8 bellard
                if (bs_table[j]) {
5505 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5506 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5507 c88676f8 bellard
                    if (sector_num >= 0)
5508 c88676f8 bellard
                        break;
5509 c88676f8 bellard
                }
5510 c88676f8 bellard
            }
5511 c88676f8 bellard
            if (j == MAX_DISKS)
5512 c88676f8 bellard
                goto normal_compress;
5513 c88676f8 bellard
            buf[0] = 1;
5514 c88676f8 bellard
            buf[1] = j;
5515 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5516 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5517 c88676f8 bellard
        } else 
5518 c88676f8 bellard
#endif
5519 c88676f8 bellard
        {
5520 c88676f8 bellard
            //        normal_compress:
5521 c88676f8 bellard
            buf[0] = 0;
5522 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5523 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5524 c88676f8 bellard
        }
5525 8a7ddc38 bellard
    }
5526 c88676f8 bellard
    ram_compress_close(s);
5527 8a7ddc38 bellard
}
5528 8a7ddc38 bellard
5529 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5530 8a7ddc38 bellard
{
5531 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5532 c88676f8 bellard
    uint8_t buf[10];
5533 c88676f8 bellard
    int i;
5534 8a7ddc38 bellard
5535 c88676f8 bellard
    if (version_id == 1)
5536 c88676f8 bellard
        return ram_load_v1(f, opaque);
5537 c88676f8 bellard
    if (version_id != 2)
5538 8a7ddc38 bellard
        return -EINVAL;
5539 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5540 8a7ddc38 bellard
        return -EINVAL;
5541 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5542 c88676f8 bellard
        return -EINVAL;
5543 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5544 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5545 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5546 c88676f8 bellard
            goto error;
5547 c88676f8 bellard
        }
5548 c88676f8 bellard
        if (buf[0] == 0) {
5549 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5550 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5551 c88676f8 bellard
                goto error;
5552 c88676f8 bellard
            }
5553 c88676f8 bellard
        } else 
5554 c88676f8 bellard
#if 0
5555 c88676f8 bellard
        if (buf[0] == 1) {
5556 c88676f8 bellard
            int bs_index;
5557 c88676f8 bellard
            int64_t sector_num;
5558 c88676f8 bellard

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