Statistics
| Branch: | Revision:

root / vl.c @ a171fe39

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

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

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