Statistics
| Branch: | Revision:

root / vl.c @ 5a1e8ffb

History | View | Annotate | Download (201.4 kB)

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

5865 c88676f8 bellard
            /* find if the memory block is available on a virtual
5866 c88676f8 bellard
               block device */
5867 c88676f8 bellard
            sector_num = -1;
5868 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5869 c88676f8 bellard
                if (bs_table[j]) {
5870 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5871 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5872 c88676f8 bellard
                    if (sector_num >= 0)
5873 c88676f8 bellard
                        break;
5874 c88676f8 bellard
                }
5875 c88676f8 bellard
            }
5876 c88676f8 bellard
            if (j == MAX_DISKS)
5877 c88676f8 bellard
                goto normal_compress;
5878 c88676f8 bellard
            buf[0] = 1;
5879 c88676f8 bellard
            buf[1] = j;
5880 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5881 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5882 c88676f8 bellard
        } else 
5883 c88676f8 bellard
#endif
5884 c88676f8 bellard
        {
5885 c88676f8 bellard
            //        normal_compress:
5886 c88676f8 bellard
            buf[0] = 0;
5887 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5888 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5889 c88676f8 bellard
        }
5890 8a7ddc38 bellard
    }
5891 c88676f8 bellard
    ram_compress_close(s);
5892 8a7ddc38 bellard
}
5893 8a7ddc38 bellard
5894 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5895 8a7ddc38 bellard
{
5896 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5897 c88676f8 bellard
    uint8_t buf[10];
5898 c88676f8 bellard
    int i;
5899 8a7ddc38 bellard
5900 c88676f8 bellard
    if (version_id == 1)
5901 c88676f8 bellard
        return ram_load_v1(f, opaque);
5902 c88676f8 bellard
    if (version_id != 2)
5903 8a7ddc38 bellard
        return -EINVAL;
5904 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5905 8a7ddc38 bellard
        return -EINVAL;
5906 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5907 c88676f8 bellard
        return -EINVAL;
5908 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5909 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5910 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5911 c88676f8 bellard
            goto error;
5912 c88676f8 bellard
        }
5913 c88676f8 bellard
        if (buf[0] == 0) {
5914 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5915 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5916 c88676f8 bellard
                goto error;
5917 c88676f8 bellard
            }
5918 c88676f8 bellard
        } else 
5919 c88676f8 bellard
#if 0
5920 c88676f8 bellard
        if (buf[0] == 1) {
5921 c88676f8 bellard
            int bs_index;
5922 c88676f8 bellard
            int64_t sector_num;
5923 c88676f8 bellard

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