Statistics
| Branch: | Revision:

root / vl.c @ e6198a70

History | View | Annotate | Download (231.8 kB)

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

6915 c88676f8 bellard
            /* find if the memory block is available on a virtual
6916 c88676f8 bellard
               block device */
6917 c88676f8 bellard
            sector_num = -1;
6918 e4bcb14c ths
            for(j = 0; j < nb_drives; j++) {
6919 e4bcb14c ths
                sector_num = bdrv_hash_find(drives_table[j].bdrv,
6920 e4bcb14c ths
                                            phys_ram_base + i,
6921 e4bcb14c ths
                                            BDRV_HASH_BLOCK_SIZE);
6922 e4bcb14c ths
                if (sector_num >= 0)
6923 e4bcb14c ths
                    break;
6924 c88676f8 bellard
            }
6925 e4bcb14c ths
            if (j == nb_drives)
6926 c88676f8 bellard
                goto normal_compress;
6927 c88676f8 bellard
            buf[0] = 1;
6928 c88676f8 bellard
            buf[1] = j;
6929 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
6930 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
6931 5fafdf24 ths
        } else
6932 c88676f8 bellard
#endif
6933 c88676f8 bellard
        {
6934 c88676f8 bellard
            //        normal_compress:
6935 c88676f8 bellard
            buf[0] = 0;
6936 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
6937 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
6938 c88676f8 bellard
        }
6939 8a7ddc38 bellard
    }
6940 c88676f8 bellard
    ram_compress_close(s);
6941 8a7ddc38 bellard
}
6942 8a7ddc38 bellard
6943 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
6944 8a7ddc38 bellard
{
6945 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
6946 c88676f8 bellard
    uint8_t buf[10];
6947 c88676f8 bellard
    int i;
6948 8a7ddc38 bellard
6949 c88676f8 bellard
    if (version_id == 1)
6950 c88676f8 bellard
        return ram_load_v1(f, opaque);
6951 c88676f8 bellard
    if (version_id != 2)
6952 8a7ddc38 bellard
        return -EINVAL;
6953 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
6954 8a7ddc38 bellard
        return -EINVAL;
6955 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
6956 c88676f8 bellard
        return -EINVAL;
6957 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
6958 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
6959 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
6960 c88676f8 bellard
            goto error;
6961 c88676f8 bellard
        }
6962 c88676f8 bellard
        if (buf[0] == 0) {
6963 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
6964 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
6965 c88676f8 bellard
                goto error;
6966 c88676f8 bellard
            }
6967 5fafdf24 ths
        } else
6968 c88676f8 bellard
#if 0
6969 c88676f8 bellard
        if (buf[0] == 1) {
6970 c88676f8 bellard
            int bs_index;
6971 c88676f8 bellard
            int64_t sector_num;
6972 c88676f8 bellard

6973 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
6974 c88676f8 bellard
            bs_index = buf[1];
6975 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
6976 e4bcb14c ths
            if (bs_index >= nb_drives) {
6977 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
6978 c88676f8 bellard
                goto error;
6979 c88676f8 bellard
            }
6980 e4bcb14c ths
            if (bdrv_read(drives_table[bs_index].bdrv, sector_num,
6981 e4bcb14c ths
                          phys_ram_base + i,
6982 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
6983 5fafdf24 ths
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n",
6984 c88676f8 bellard
                        bs_index, sector_num);
6985 c88676f8 bellard
                goto error;
6986 c88676f8 bellard
            }
6987 5fafdf24 ths
        } else
6988 c88676f8 bellard
#endif
6989 c88676f8 bellard
        {
6990 c88676f8 bellard
        error:
6991 c88676f8 bellard
            printf("Error block header\n");
6992 c88676f8 bellard
            return -EINVAL;
6993 c88676f8 bellard
        }
6994 8a7ddc38 bellard
    }
6995 c88676f8 bellard
    ram_decompress_close(s);
6996 8a7ddc38 bellard
    return 0;
6997 8a7ddc38 bellard
}
6998 8a7ddc38 bellard
6999 8a7ddc38 bellard
/***********************************************************/
7000 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
7001 83f64091 bellard
7002 83f64091 bellard
struct QEMUBH {
7003 83f64091 bellard
    QEMUBHFunc *cb;
7004 83f64091 bellard
    void *opaque;
7005 83f64091 bellard
    int scheduled;
7006 83f64091 bellard
    QEMUBH *next;
7007 83f64091 bellard
};
7008 83f64091 bellard
7009 83f64091 bellard
static QEMUBH *first_bh = NULL;
7010 83f64091 bellard
7011 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
7012 83f64091 bellard
{
7013 83f64091 bellard
    QEMUBH *bh;
7014 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
7015 83f64091 bellard
    if (!bh)
7016 83f64091 bellard
        return NULL;
7017 83f64091 bellard
    bh->cb = cb;
7018 83f64091 bellard
    bh->opaque = opaque;
7019 83f64091 bellard
    return bh;
7020 83f64091 bellard
}
7021 83f64091 bellard
7022 6eb5733a bellard
int qemu_bh_poll(void)
7023 83f64091 bellard
{
7024 83f64091 bellard
    QEMUBH *bh, **pbh;
7025 6eb5733a bellard
    int ret;
7026 83f64091 bellard
7027 6eb5733a bellard
    ret = 0;
7028 83f64091 bellard
    for(;;) {
7029 83f64091 bellard
        pbh = &first_bh;
7030 83f64091 bellard
        bh = *pbh;
7031 83f64091 bellard
        if (!bh)
7032 83f64091 bellard
            break;
7033 6eb5733a bellard
        ret = 1;
7034 83f64091 bellard
        *pbh = bh->next;
7035 83f64091 bellard
        bh->scheduled = 0;
7036 83f64091 bellard
        bh->cb(bh->opaque);
7037 83f64091 bellard
    }
7038 6eb5733a bellard
    return ret;
7039 83f64091 bellard
}
7040 83f64091 bellard
7041 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
7042 83f64091 bellard
{
7043 83f64091 bellard
    CPUState *env = cpu_single_env;
7044 83f64091 bellard
    if (bh->scheduled)
7045 83f64091 bellard
        return;
7046 83f64091 bellard
    bh->scheduled = 1;
7047 83f64091 bellard
    bh->next = first_bh;
7048 83f64091 bellard
    first_bh = bh;
7049 83f64091 bellard
7050 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
7051 83f64091 bellard
    if (env) {
7052 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
7053 83f64091 bellard
    }
7054 83f64091 bellard
}
7055 83f64091 bellard
7056 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
7057 83f64091 bellard
{
7058 83f64091 bellard
    QEMUBH **pbh;
7059 83f64091 bellard
    if (bh->scheduled) {
7060 83f64091 bellard
        pbh = &first_bh;
7061 83f64091 bellard
        while (*pbh != bh)
7062 83f64091 bellard
            pbh = &(*pbh)->next;
7063 83f64091 bellard
        *pbh = bh->next;
7064 83f64091 bellard
        bh->scheduled = 0;
7065 83f64091 bellard
    }
7066 83f64091 bellard
}
7067 83f64091 bellard
7068 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
7069 83f64091 bellard
{
7070 83f64091 bellard
    qemu_bh_cancel(bh);
7071 83f64091 bellard
    qemu_free(bh);
7072 83f64091 bellard
}
7073 83f64091 bellard
7074 83f64091 bellard
/***********************************************************/
7075 cc1daa40 bellard
/* machine registration */
7076 cc1daa40 bellard
7077 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
7078 cc1daa40 bellard
7079 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
7080 cc1daa40 bellard
{
7081 cc1daa40 bellard
    QEMUMachine **pm;
7082 cc1daa40 bellard
    pm = &first_machine;
7083 cc1daa40 bellard
    while (*pm != NULL)
7084 cc1daa40 bellard
        pm = &(*pm)->next;
7085 cc1daa40 bellard
    m->next = NULL;
7086 cc1daa40 bellard
    *pm = m;
7087 cc1daa40 bellard
    return 0;
7088 cc1daa40 bellard
}
7089 cc1daa40 bellard
7090 9596ebb7 pbrook
static QEMUMachine *find_machine(const char *name)
7091 cc1daa40 bellard
{
7092 cc1daa40 bellard
    QEMUMachine *m;
7093 cc1daa40 bellard
7094 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
7095 cc1daa40 bellard
        if (!strcmp(m->name, name))
7096 cc1daa40 bellard
            return m;
7097 cc1daa40 bellard
    }
7098 cc1daa40 bellard
    return NULL;
7099 cc1daa40 bellard
}
7100 cc1daa40 bellard
7101 cc1daa40 bellard
/***********************************************************/
7102 8a7ddc38 bellard
/* main execution loop */
7103 8a7ddc38 bellard
7104 9596ebb7 pbrook
static void gui_update(void *opaque)
7105 8a7ddc38 bellard
{
7106 740733bb ths
    DisplayState *ds = opaque;
7107 740733bb ths
    ds->dpy_refresh(ds);
7108 740733bb ths
    qemu_mod_timer(ds->gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
7109 8a7ddc38 bellard
}
7110 8a7ddc38 bellard
7111 0bd48850 bellard
struct vm_change_state_entry {
7112 0bd48850 bellard
    VMChangeStateHandler *cb;
7113 0bd48850 bellard
    void *opaque;
7114 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
7115 0bd48850 bellard
};
7116 0bd48850 bellard
7117 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
7118 0bd48850 bellard
7119 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
7120 0bd48850 bellard
                                                     void *opaque)
7121 0bd48850 bellard
{
7122 0bd48850 bellard
    VMChangeStateEntry *e;
7123 0bd48850 bellard
7124 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
7125 0bd48850 bellard
    if (!e)
7126 0bd48850 bellard
        return NULL;
7127 0bd48850 bellard
7128 0bd48850 bellard
    e->cb = cb;
7129 0bd48850 bellard
    e->opaque = opaque;
7130 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
7131 0bd48850 bellard
    return e;
7132 0bd48850 bellard
}
7133 0bd48850 bellard
7134 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
7135 0bd48850 bellard
{
7136 0bd48850 bellard
    LIST_REMOVE (e, entries);
7137 0bd48850 bellard
    qemu_free (e);
7138 0bd48850 bellard
}
7139 0bd48850 bellard
7140 0bd48850 bellard
static void vm_state_notify(int running)
7141 0bd48850 bellard
{
7142 0bd48850 bellard
    VMChangeStateEntry *e;
7143 0bd48850 bellard
7144 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
7145 0bd48850 bellard
        e->cb(e->opaque, running);
7146 0bd48850 bellard
    }
7147 0bd48850 bellard
}
7148 0bd48850 bellard
7149 8a7ddc38 bellard
/* XXX: support several handlers */
7150 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
7151 0bd48850 bellard
static void *vm_stop_opaque;
7152 8a7ddc38 bellard
7153 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
7154 8a7ddc38 bellard
{
7155 8a7ddc38 bellard
    vm_stop_cb = cb;
7156 8a7ddc38 bellard
    vm_stop_opaque = opaque;
7157 8a7ddc38 bellard
    return 0;
7158 8a7ddc38 bellard
}
7159 8a7ddc38 bellard
7160 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
7161 8a7ddc38 bellard
{
7162 8a7ddc38 bellard
    vm_stop_cb = NULL;
7163 8a7ddc38 bellard
}
7164 8a7ddc38 bellard
7165 8a7ddc38 bellard
void vm_start(void)
7166 8a7ddc38 bellard
{
7167 8a7ddc38 bellard
    if (!vm_running) {
7168 8a7ddc38 bellard
        cpu_enable_ticks();
7169 8a7ddc38 bellard
        vm_running = 1;
7170 0bd48850 bellard
        vm_state_notify(1);
7171 efe75411 ths
        qemu_rearm_alarm_timer(alarm_timer);
7172 8a7ddc38 bellard
    }
7173 8a7ddc38 bellard
}
7174 8a7ddc38 bellard
7175 5fafdf24 ths
void vm_stop(int reason)
7176 8a7ddc38 bellard
{
7177 8a7ddc38 bellard
    if (vm_running) {
7178 8a7ddc38 bellard
        cpu_disable_ticks();
7179 8a7ddc38 bellard
        vm_running = 0;
7180 8a7ddc38 bellard
        if (reason != 0) {
7181 8a7ddc38 bellard
            if (vm_stop_cb) {
7182 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
7183 8a7ddc38 bellard
            }
7184 34865134 bellard
        }
7185 0bd48850 bellard
        vm_state_notify(0);
7186 8a7ddc38 bellard
    }
7187 8a7ddc38 bellard
}
7188 8a7ddc38 bellard
7189 bb0c6722 bellard
/* reset/shutdown handler */
7190 bb0c6722 bellard
7191 bb0c6722 bellard
typedef struct QEMUResetEntry {
7192 bb0c6722 bellard
    QEMUResetHandler *func;
7193 bb0c6722 bellard
    void *opaque;
7194 bb0c6722 bellard
    struct QEMUResetEntry *next;
7195 bb0c6722 bellard
} QEMUResetEntry;
7196 bb0c6722 bellard
7197 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
7198 bb0c6722 bellard
static int reset_requested;
7199 bb0c6722 bellard
static int shutdown_requested;
7200 3475187d bellard
static int powerdown_requested;
7201 bb0c6722 bellard
7202 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
7203 bb0c6722 bellard
{
7204 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
7205 bb0c6722 bellard
7206 bb0c6722 bellard
    pre = &first_reset_entry;
7207 bb0c6722 bellard
    while (*pre != NULL)
7208 bb0c6722 bellard
        pre = &(*pre)->next;
7209 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
7210 bb0c6722 bellard
    re->func = func;
7211 bb0c6722 bellard
    re->opaque = opaque;
7212 bb0c6722 bellard
    re->next = NULL;
7213 bb0c6722 bellard
    *pre = re;
7214 bb0c6722 bellard
}
7215 bb0c6722 bellard
7216 52f61fde ths
static void qemu_system_reset(void)
7217 bb0c6722 bellard
{
7218 bb0c6722 bellard
    QEMUResetEntry *re;
7219 bb0c6722 bellard
7220 bb0c6722 bellard
    /* reset all devices */
7221 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
7222 bb0c6722 bellard
        re->func(re->opaque);
7223 bb0c6722 bellard
    }
7224 bb0c6722 bellard
}
7225 bb0c6722 bellard
7226 bb0c6722 bellard
void qemu_system_reset_request(void)
7227 bb0c6722 bellard
{
7228 d1beab82 bellard
    if (no_reboot) {
7229 d1beab82 bellard
        shutdown_requested = 1;
7230 d1beab82 bellard
    } else {
7231 d1beab82 bellard
        reset_requested = 1;
7232 d1beab82 bellard
    }
7233 6a00d601 bellard
    if (cpu_single_env)
7234 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7235 bb0c6722 bellard
}
7236 bb0c6722 bellard
7237 bb0c6722 bellard
void qemu_system_shutdown_request(void)
7238 bb0c6722 bellard
{
7239 bb0c6722 bellard
    shutdown_requested = 1;
7240 6a00d601 bellard
    if (cpu_single_env)
7241 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7242 bb0c6722 bellard
}
7243 bb0c6722 bellard
7244 3475187d bellard
void qemu_system_powerdown_request(void)
7245 3475187d bellard
{
7246 3475187d bellard
    powerdown_requested = 1;
7247 6a00d601 bellard
    if (cpu_single_env)
7248 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
7249 bb0c6722 bellard
}
7250 bb0c6722 bellard
7251 5905b2e5 bellard
void main_loop_wait(int timeout)
7252 8a7ddc38 bellard
{
7253 cafffd40 ths
    IOHandlerRecord *ioh;
7254 e035649e bellard
    fd_set rfds, wfds, xfds;
7255 877cf882 ths
    int ret, nfds;
7256 877cf882 ths
#ifdef _WIN32
7257 877cf882 ths
    int ret2, i;
7258 877cf882 ths
#endif
7259 fd1dff4b bellard
    struct timeval tv;
7260 f331110f bellard
    PollingEntry *pe;
7261 f331110f bellard
7262 c4b1fcc0 bellard
7263 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
7264 f331110f bellard
    ret = 0;
7265 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
7266 f331110f bellard
        ret |= pe->func(pe->opaque);
7267 f331110f bellard
    }
7268 38e205a2 bellard
#ifdef _WIN32
7269 e6b1e558 ths
    if (ret == 0) {
7270 a18e524a bellard
        int err;
7271 a18e524a bellard
        WaitObjects *w = &wait_objects;
7272 3b46e624 ths
7273 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
7274 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
7275 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
7276 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
7277 3b46e624 ths
7278 5fafdf24 ths
            /* Check for additional signaled events */
7279 e6b1e558 ths
            for(i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
7280 3b46e624 ths
7281 e6b1e558 ths
                /* Check if event is signaled */
7282 e6b1e558 ths
                ret2 = WaitForSingleObject(w->events[i], 0);
7283 e6b1e558 ths
                if(ret2 == WAIT_OBJECT_0) {
7284 e6b1e558 ths
                    if (w->func[i])
7285 e6b1e558 ths
                        w->func[i](w->opaque[i]);
7286 e6b1e558 ths
                } else if (ret2 == WAIT_TIMEOUT) {
7287 e6b1e558 ths
                } else {
7288 e6b1e558 ths
                    err = GetLastError();
7289 e6b1e558 ths
                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
7290 3b46e624 ths
                }
7291 3b46e624 ths
            }
7292 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
7293 a18e524a bellard
        } else {
7294 a18e524a bellard
            err = GetLastError();
7295 e6b1e558 ths
            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
7296 a18e524a bellard
        }
7297 f331110f bellard
    }
7298 fd1dff4b bellard
#endif
7299 fd1dff4b bellard
    /* poll any events */
7300 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
7301 fd1dff4b bellard
    nfds = -1;
7302 fd1dff4b bellard
    FD_ZERO(&rfds);
7303 fd1dff4b bellard
    FD_ZERO(&wfds);
7304 e035649e bellard
    FD_ZERO(&xfds);
7305 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
7306 cafffd40 ths
        if (ioh->deleted)
7307 cafffd40 ths
            continue;
7308 fd1dff4b bellard
        if (ioh->fd_read &&
7309 fd1dff4b bellard
            (!ioh->fd_read_poll ||
7310 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
7311 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
7312 fd1dff4b bellard
            if (ioh->fd > nfds)
7313 fd1dff4b bellard
                nfds = ioh->fd;
7314 fd1dff4b bellard
        }
7315 fd1dff4b bellard
        if (ioh->fd_write) {
7316 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
7317 fd1dff4b bellard
            if (ioh->fd > nfds)
7318 fd1dff4b bellard
                nfds = ioh->fd;
7319 fd1dff4b bellard
        }
7320 fd1dff4b bellard
    }
7321 3b46e624 ths
7322 fd1dff4b bellard
    tv.tv_sec = 0;
7323 fd1dff4b bellard
#ifdef _WIN32
7324 fd1dff4b bellard
    tv.tv_usec = 0;
7325 38e205a2 bellard
#else
7326 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
7327 fd1dff4b bellard
#endif
7328 e035649e bellard
#if defined(CONFIG_SLIRP)
7329 e035649e bellard
    if (slirp_inited) {
7330 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
7331 e035649e bellard
    }
7332 e035649e bellard
#endif
7333 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
7334 fd1dff4b bellard
    if (ret > 0) {
7335 cafffd40 ths
        IOHandlerRecord **pioh;
7336 cafffd40 ths
7337 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
7338 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {
7339 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
7340 7c9d8e07 bellard
            }
7341 6ab43fdc ths
            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {
7342 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
7343 c4b1fcc0 bellard
            }
7344 b4608c04 bellard
        }
7345 cafffd40 ths
7346 cafffd40 ths
        /* remove deleted IO handlers */
7347 cafffd40 ths
        pioh = &first_io_handler;
7348 cafffd40 ths
        while (*pioh) {
7349 cafffd40 ths
            ioh = *pioh;
7350 cafffd40 ths
            if (ioh->deleted) {
7351 cafffd40 ths
                *pioh = ioh->next;
7352 cafffd40 ths
                qemu_free(ioh);
7353 5fafdf24 ths
            } else
7354 cafffd40 ths
                pioh = &ioh->next;
7355 cafffd40 ths
        }
7356 fd1dff4b bellard
    }
7357 c20709aa bellard
#if defined(CONFIG_SLIRP)
7358 fd1dff4b bellard
    if (slirp_inited) {
7359 e035649e bellard
        if (ret < 0) {
7360 e035649e bellard
            FD_ZERO(&rfds);
7361 e035649e bellard
            FD_ZERO(&wfds);
7362 e035649e bellard
            FD_ZERO(&xfds);
7363 c20709aa bellard
        }
7364 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
7365 fd1dff4b bellard
    }
7366 c20709aa bellard
#endif
7367 83f64091 bellard
    qemu_aio_poll();
7368 c20709aa bellard
7369 fd1dff4b bellard
    if (vm_running) {
7370 5fafdf24 ths
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
7371 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
7372 fd1dff4b bellard
        /* run dma transfers, if any */
7373 fd1dff4b bellard
        DMA_run();
7374 fd1dff4b bellard
    }
7375 423f0742 pbrook
7376 fd1dff4b bellard
    /* real time timers */
7377 5fafdf24 ths
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
7378 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
7379 423f0742 pbrook
7380 b99dc0d1 balrog
    qemu_rearm_alarm_timer(alarm_timer);
7381 b99dc0d1 balrog
7382 423f0742 pbrook
    /* Check bottom-halves last in case any of the earlier events triggered
7383 423f0742 pbrook
       them.  */
7384 423f0742 pbrook
    qemu_bh_poll();
7385 3b46e624 ths
7386 5905b2e5 bellard
}
7387 5905b2e5 bellard
7388 9596ebb7 pbrook
static int main_loop(void)
7389 5905b2e5 bellard
{
7390 5905b2e5 bellard
    int ret, timeout;
7391 89bfc105 bellard
#ifdef CONFIG_PROFILER
7392 89bfc105 bellard
    int64_t ti;
7393 89bfc105 bellard
#endif
7394 6a00d601 bellard
    CPUState *env;
7395 5905b2e5 bellard
7396 6a00d601 bellard
    cur_cpu = first_cpu;
7397 ee5605e5 balrog
    next_cpu = cur_cpu->next_cpu ?: first_cpu;
7398 5905b2e5 bellard
    for(;;) {
7399 5905b2e5 bellard
        if (vm_running) {
7400 15a76449 bellard
7401 15a76449 bellard
            for(;;) {
7402 15a76449 bellard
                /* get next cpu */
7403 ee5605e5 balrog
                env = next_cpu;
7404 89bfc105 bellard
#ifdef CONFIG_PROFILER
7405 89bfc105 bellard
                ti = profile_getclock();
7406 89bfc105 bellard
#endif
7407 6a00d601 bellard
                ret = cpu_exec(env);
7408 89bfc105 bellard
#ifdef CONFIG_PROFILER
7409 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
7410 89bfc105 bellard
#endif
7411 ee5605e5 balrog
                next_cpu = env->next_cpu ?: first_cpu;
7412 ee5605e5 balrog
                if (event_pending) {
7413 ee5605e5 balrog
                    ret = EXCP_INTERRUPT;
7414 ee5605e5 balrog
                    event_pending = 0;
7415 ee5605e5 balrog
                    break;
7416 ee5605e5 balrog
                }
7417 bd967e05 pbrook
                if (ret == EXCP_HLT) {
7418 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
7419 bd967e05 pbrook
                    cur_cpu = env;
7420 bd967e05 pbrook
                    continue;
7421 bd967e05 pbrook
                }
7422 15a76449 bellard
                if (ret != EXCP_HALTED)
7423 15a76449 bellard
                    break;
7424 15a76449 bellard
                /* all CPUs are halted ? */
7425 bd967e05 pbrook
                if (env == cur_cpu)
7426 15a76449 bellard
                    break;
7427 15a76449 bellard
            }
7428 15a76449 bellard
            cur_cpu = env;
7429 15a76449 bellard
7430 5905b2e5 bellard
            if (shutdown_requested) {
7431 3475187d bellard
                ret = EXCP_INTERRUPT;
7432 5905b2e5 bellard
                break;
7433 5905b2e5 bellard
            }
7434 5905b2e5 bellard
            if (reset_requested) {
7435 5905b2e5 bellard
                reset_requested = 0;
7436 5905b2e5 bellard
                qemu_system_reset();
7437 3475187d bellard
                ret = EXCP_INTERRUPT;
7438 3475187d bellard
            }
7439 3475187d bellard
            if (powerdown_requested) {
7440 3475187d bellard
                powerdown_requested = 0;
7441 3475187d bellard
                qemu_system_powerdown();
7442 3475187d bellard
                ret = EXCP_INTERRUPT;
7443 5905b2e5 bellard
            }
7444 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
7445 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
7446 5905b2e5 bellard
            }
7447 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
7448 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
7449 bd967e05 pbrook
            if (ret == EXCP_HALTED)
7450 5905b2e5 bellard
                timeout = 10;
7451 5905b2e5 bellard
            else
7452 5905b2e5 bellard
                timeout = 0;
7453 5905b2e5 bellard
        } else {
7454 5905b2e5 bellard
            timeout = 10;
7455 5905b2e5 bellard
        }
7456 89bfc105 bellard
#ifdef CONFIG_PROFILER
7457 89bfc105 bellard
        ti = profile_getclock();
7458 89bfc105 bellard
#endif
7459 5905b2e5 bellard
        main_loop_wait(timeout);
7460 89bfc105 bellard
#ifdef CONFIG_PROFILER
7461 89bfc105 bellard
        dev_time += profile_getclock() - ti;
7462 89bfc105 bellard
#endif
7463 b4608c04 bellard
    }
7464 34865134 bellard
    cpu_disable_ticks();
7465 34865134 bellard
    return ret;
7466 b4608c04 bellard
}
7467 b4608c04 bellard
7468 15f82208 ths
static void help(int exitcode)
7469 0824d6fc bellard
{
7470 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
7471 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
7472 0824d6fc bellard
           "\n"
7473 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
7474 fc01f7e7 bellard
           "\n"
7475 a20dd508 bellard
           "Standard options:\n"
7476 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
7477 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
7478 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
7479 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
7480 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
7481 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
7482 e4bcb14c ths
           "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n"
7483 e4bcb14c ths
           "       [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n"
7484 e4bcb14c ths
           "                use 'file' as a drive image\n"
7485 3e3d5815 balrog
           "-mtdblock file  use 'file' as on-board Flash memory image\n"
7486 a1bb27b1 pbrook
           "-sd file        use 'file' as SecureDigital card image\n"
7487 86f55663 j_mayer
           "-pflash file    use 'file' as a parallel flash image\n"
7488 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
7489 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
7490 667accab ths
#ifdef CONFIG_SDL
7491 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
7492 3780e197 ths
           "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
7493 667accab ths
           "-no-quit        disable SDL window close capability\n"
7494 667accab ths
#endif
7495 52ca8d6a bellard
#ifdef TARGET_I386
7496 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
7497 52ca8d6a bellard
#endif
7498 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
7499 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
7500 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
7501 a171fe39 balrog
           "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"
7502 4ca0074c bellard
#ifndef _WIN32
7503 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
7504 4ca0074c bellard
#endif
7505 1d14ffa9 bellard
#ifdef HAS_AUDIO
7506 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
7507 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
7508 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
7509 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
7510 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
7511 1d14ffa9 bellard
#endif
7512 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
7513 d63d307f bellard
           "-full-screen    start in full screen\n"
7514 a09db21f bellard
#ifdef TARGET_I386
7515 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
7516 a09db21f bellard
#endif
7517 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
7518 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
7519 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7520 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
7521 bb0c6722 bellard
#endif
7522 c35734b2 ths
           "-name string    set the name of the guest\n"
7523 c4b1fcc0 bellard
           "\n"
7524 c4b1fcc0 bellard
           "Network options:\n"
7525 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
7526 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
7527 c20709aa bellard
#ifdef CONFIG_SLIRP
7528 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
7529 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
7530 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
7531 7c9d8e07 bellard
#endif
7532 7fb843f8 bellard
#ifdef _WIN32
7533 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
7534 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
7535 7fb843f8 bellard
#else
7536 b46a8906 ths
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
7537 b46a8906 ths
           "                connect the host TAP network interface to VLAN 'n' and use the\n"
7538 b46a8906 ths
           "                network scripts 'file' (default=%s)\n"
7539 b46a8906 ths
           "                and 'dfile' (default=%s);\n"
7540 b46a8906 ths
           "                use '[down]script=no' to disable script execution;\n"
7541 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
7542 7fb843f8 bellard
#endif
7543 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
7544 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
7545 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
7546 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
7547 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
7548 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
7549 7c9d8e07 bellard
           "\n"
7550 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
7551 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
7552 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
7553 7c9d8e07 bellard
#ifndef _WIN32
7554 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
7555 c94c8d64 bellard
#endif
7556 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
7557 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
7558 c20709aa bellard
#endif
7559 a20dd508 bellard
           "\n"
7560 c4b1fcc0 bellard
           "Linux boot specific:\n"
7561 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
7562 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
7563 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
7564 fc01f7e7 bellard
           "\n"
7565 330d0414 bellard
           "Debug/Expert options:\n"
7566 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
7567 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
7568 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
7569 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
7570 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
7571 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
7572 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
7573 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
7574 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
7575 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
7576 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
7577 d993e026 bellard
#ifdef USE_KQEMU
7578 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
7579 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
7580 d993e026 bellard
#endif
7581 bb0c6722 bellard
#ifdef TARGET_I386
7582 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
7583 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
7584 6515b203 bellard
           "-no-acpi        disable ACPI\n"
7585 bb0c6722 bellard
#endif
7586 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
7587 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
7588 24236869 bellard
           "-vnc display    start a VNC server on display\n"
7589 71e3ceb8 ths
#ifndef _WIN32
7590 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
7591 71e3ceb8 ths
#endif
7592 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
7593 66508601 blueswir1
#ifdef TARGET_SPARC
7594 66508601 blueswir1
           "-prom-env variable=value  set OpenBIOS nvram variables\n"
7595 66508601 blueswir1
#endif
7596 f3dcfada ths
           "-clock          force the use of the given methods for timer alarm.\n"
7597 f3dcfada ths
           "                To see what timers are available use -clock help\n"
7598 0824d6fc bellard
           "\n"
7599 82c643ff bellard
           "During emulation, the following keys are useful:\n"
7600 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
7601 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
7602 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
7603 82c643ff bellard
           "\n"
7604 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
7605 82c643ff bellard
           ,
7606 0db63474 bellard
           "qemu",
7607 a00bad7e bellard
           DEFAULT_RAM_SIZE,
7608 7c9d8e07 bellard
#ifndef _WIN32
7609 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
7610 b46a8906 ths
           DEFAULT_NETWORK_DOWN_SCRIPT,
7611 7c9d8e07 bellard
#endif
7612 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
7613 6e44ba7f bellard
           "/tmp/qemu.log");
7614 15f82208 ths
    exit(exitcode);
7615 0824d6fc bellard
}
7616 0824d6fc bellard
7617 cd6f1169 bellard
#define HAS_ARG 0x0001
7618 cd6f1169 bellard
7619 cd6f1169 bellard
enum {
7620 cd6f1169 bellard
    QEMU_OPTION_h,
7621 cd6f1169 bellard
7622 cc1daa40 bellard
    QEMU_OPTION_M,
7623 94fc95cd j_mayer
    QEMU_OPTION_cpu,
7624 cd6f1169 bellard
    QEMU_OPTION_fda,
7625 cd6f1169 bellard
    QEMU_OPTION_fdb,
7626 cd6f1169 bellard
    QEMU_OPTION_hda,
7627 cd6f1169 bellard
    QEMU_OPTION_hdb,
7628 cd6f1169 bellard
    QEMU_OPTION_hdc,
7629 cd6f1169 bellard
    QEMU_OPTION_hdd,
7630 e4bcb14c ths
    QEMU_OPTION_drive,
7631 cd6f1169 bellard
    QEMU_OPTION_cdrom,
7632 3e3d5815 balrog
    QEMU_OPTION_mtdblock,
7633 a1bb27b1 pbrook
    QEMU_OPTION_sd,
7634 86f55663 j_mayer
    QEMU_OPTION_pflash,
7635 cd6f1169 bellard
    QEMU_OPTION_boot,
7636 cd6f1169 bellard
    QEMU_OPTION_snapshot,
7637 52ca8d6a bellard
#ifdef TARGET_I386
7638 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
7639 52ca8d6a bellard
#endif
7640 cd6f1169 bellard
    QEMU_OPTION_m,
7641 cd6f1169 bellard
    QEMU_OPTION_nographic,
7642 a171fe39 balrog
    QEMU_OPTION_portrait,
7643 1d14ffa9 bellard
#ifdef HAS_AUDIO
7644 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
7645 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
7646 1d14ffa9 bellard
#endif
7647 cd6f1169 bellard
7648 7c9d8e07 bellard
    QEMU_OPTION_net,
7649 c7f74643 bellard
    QEMU_OPTION_tftp,
7650 47d5d01a ths
    QEMU_OPTION_bootp,
7651 9d728e8c bellard
    QEMU_OPTION_smb,
7652 9bf05444 bellard
    QEMU_OPTION_redir,
7653 cd6f1169 bellard
7654 cd6f1169 bellard
    QEMU_OPTION_kernel,
7655 cd6f1169 bellard
    QEMU_OPTION_append,
7656 cd6f1169 bellard
    QEMU_OPTION_initrd,
7657 cd6f1169 bellard
7658 cd6f1169 bellard
    QEMU_OPTION_S,
7659 cd6f1169 bellard
    QEMU_OPTION_s,
7660 cd6f1169 bellard
    QEMU_OPTION_p,
7661 cd6f1169 bellard
    QEMU_OPTION_d,
7662 cd6f1169 bellard
    QEMU_OPTION_hdachs,
7663 cd6f1169 bellard
    QEMU_OPTION_L,
7664 1192dad8 j_mayer
    QEMU_OPTION_bios,
7665 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
7666 3d11d0eb bellard
    QEMU_OPTION_k,
7667 ee22c2f7 bellard
    QEMU_OPTION_localtime,
7668 1f04275e bellard
    QEMU_OPTION_cirrusvga,
7669 d34cab9f ths
    QEMU_OPTION_vmsvga,
7670 e9b137c2 bellard
    QEMU_OPTION_g,
7671 1bfe856e bellard
    QEMU_OPTION_std_vga,
7672 20d8a3ed ths
    QEMU_OPTION_echr,
7673 82c643ff bellard
    QEMU_OPTION_monitor,
7674 82c643ff bellard
    QEMU_OPTION_serial,
7675 6508fe59 bellard
    QEMU_OPTION_parallel,
7676 d63d307f bellard
    QEMU_OPTION_loadvm,
7677 d63d307f bellard
    QEMU_OPTION_full_screen,
7678 43523e93 ths
    QEMU_OPTION_no_frame,
7679 3780e197 ths
    QEMU_OPTION_alt_grab,
7680 667accab ths
    QEMU_OPTION_no_quit,
7681 f7cce898 bellard
    QEMU_OPTION_pidfile,
7682 d993e026 bellard
    QEMU_OPTION_no_kqemu,
7683 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
7684 a09db21f bellard
    QEMU_OPTION_win2k_hack,
7685 bb36d470 bellard
    QEMU_OPTION_usb,
7686 a594cfbf bellard
    QEMU_OPTION_usbdevice,
7687 6a00d601 bellard
    QEMU_OPTION_smp,
7688 24236869 bellard
    QEMU_OPTION_vnc,
7689 6515b203 bellard
    QEMU_OPTION_no_acpi,
7690 d1beab82 bellard
    QEMU_OPTION_no_reboot,
7691 9467cd46 balrog
    QEMU_OPTION_show_cursor,
7692 71e3ceb8 ths
    QEMU_OPTION_daemonize,
7693 9ae02555 ths
    QEMU_OPTION_option_rom,
7694 c35734b2 ths
    QEMU_OPTION_semihosting,
7695 c35734b2 ths
    QEMU_OPTION_name,
7696 66508601 blueswir1
    QEMU_OPTION_prom_env,
7697 2b8f2d41 balrog
    QEMU_OPTION_old_param,
7698 f3dcfada ths
    QEMU_OPTION_clock,
7699 7e0af5d0 bellard
    QEMU_OPTION_startdate,
7700 cd6f1169 bellard
};
7701 cd6f1169 bellard
7702 cd6f1169 bellard
typedef struct QEMUOption {
7703 cd6f1169 bellard
    const char *name;
7704 cd6f1169 bellard
    int flags;
7705 cd6f1169 bellard
    int index;
7706 cd6f1169 bellard
} QEMUOption;
7707 cd6f1169 bellard
7708 cd6f1169 bellard
const QEMUOption qemu_options[] = {
7709 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
7710 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
7711 cd6f1169 bellard
7712 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
7713 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
7714 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
7715 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
7716 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
7717 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
7718 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
7719 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
7720 e4bcb14c ths
    { "drive", HAS_ARG, QEMU_OPTION_drive },
7721 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
7722 3e3d5815 balrog
    { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
7723 a1bb27b1 pbrook
    { "sd", HAS_ARG, QEMU_OPTION_sd },
7724 86f55663 j_mayer
    { "pflash", HAS_ARG, QEMU_OPTION_pflash },
7725 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
7726 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
7727 52ca8d6a bellard
#ifdef TARGET_I386
7728 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
7729 52ca8d6a bellard
#endif
7730 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
7731 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
7732 a171fe39 balrog
    { "portrait", 0, QEMU_OPTION_portrait },
7733 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
7734 1d14ffa9 bellard
#ifdef HAS_AUDIO
7735 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
7736 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
7737 1d14ffa9 bellard
#endif
7738 cd6f1169 bellard
7739 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
7740 158156d1 bellard
#ifdef CONFIG_SLIRP
7741 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
7742 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
7743 c94c8d64 bellard
#ifndef _WIN32
7744 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
7745 c94c8d64 bellard
#endif
7746 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
7747 158156d1 bellard
#endif
7748 cd6f1169 bellard
7749 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
7750 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
7751 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
7752 cd6f1169 bellard
7753 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
7754 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
7755 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
7756 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
7757 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
7758 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
7759 1192dad8 j_mayer
    { "bios", HAS_ARG, QEMU_OPTION_bios },
7760 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
7761 d993e026 bellard
#ifdef USE_KQEMU
7762 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
7763 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
7764 d993e026 bellard
#endif
7765 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
7766 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
7767 77d4bc34 bellard
#endif
7768 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
7769 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
7770 8b6e0729 balrog
    { "echr", HAS_ARG, QEMU_OPTION_echr },
7771 8b6e0729 balrog
    { "monitor", HAS_ARG, QEMU_OPTION_monitor },
7772 8b6e0729 balrog
    { "serial", HAS_ARG, QEMU_OPTION_serial },
7773 8b6e0729 balrog
    { "parallel", HAS_ARG, QEMU_OPTION_parallel },
7774 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
7775 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
7776 667accab ths
#ifdef CONFIG_SDL
7777 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
7778 3780e197 ths
    { "alt-grab", 0, QEMU_OPTION_alt_grab },
7779 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
7780 667accab ths
#endif
7781 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
7782 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
7783 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
7784 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
7785 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
7786 96d30e48 ths
7787 1f04275e bellard
    /* temporary options */
7788 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
7789 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
7790 d34cab9f ths
    { "vmwarevga", 0, QEMU_OPTION_vmsvga },
7791 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
7792 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
7793 9467cd46 balrog
    { "show-cursor", 0, QEMU_OPTION_show_cursor },
7794 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
7795 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
7796 a87295e8 pbrook
#if defined(TARGET_ARM) || defined(TARGET_M68K)
7797 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
7798 8e71621f pbrook
#endif
7799 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
7800 66508601 blueswir1
#if defined(TARGET_SPARC)
7801 66508601 blueswir1
    { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
7802 66508601 blueswir1
#endif
7803 2b8f2d41 balrog
#if defined(TARGET_ARM)
7804 2b8f2d41 balrog
    { "old-param", 0, QEMU_OPTION_old_param },
7805 2b8f2d41 balrog
#endif
7806 f3dcfada ths
    { "clock", HAS_ARG, QEMU_OPTION_clock },
7807 7e0af5d0 bellard
    { "startdate", HAS_ARG, QEMU_OPTION_startdate },
7808 cd6f1169 bellard
    { NULL },
7809 fc01f7e7 bellard
};
7810 fc01f7e7 bellard
7811 5905b2e5 bellard
/* password input */
7812 5905b2e5 bellard
7813 2bac6019 balrog
int qemu_key_check(BlockDriverState *bs, const char *name)
7814 2bac6019 balrog
{
7815 2bac6019 balrog
    char password[256];
7816 2bac6019 balrog
    int i;
7817 2bac6019 balrog
7818 2bac6019 balrog
    if (!bdrv_is_encrypted(bs))
7819 2bac6019 balrog
        return 0;
7820 2bac6019 balrog
7821 2bac6019 balrog
    term_printf("%s is encrypted.\n", name);
7822 2bac6019 balrog
    for(i = 0; i < 3; i++) {
7823 2bac6019 balrog
        monitor_readline("Password: ", 1, password, sizeof(password));
7824 2bac6019 balrog
        if (bdrv_set_key(bs, password) == 0)
7825 2bac6019 balrog
            return 0;
7826 2bac6019 balrog
        term_printf("invalid password\n");
7827 2bac6019 balrog
    }
7828 2bac6019 balrog
    return -EPERM;
7829 2bac6019 balrog
}
7830 2bac6019 balrog
7831 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
7832 5905b2e5 bellard
{
7833 e4bcb14c ths
    if (index > nb_drives)
7834 e4bcb14c ths
        return NULL;
7835 e4bcb14c ths
    return drives_table[index].bdrv;
7836 5905b2e5 bellard
}
7837 5905b2e5 bellard
7838 5905b2e5 bellard
static void read_passwords(void)
7839 5905b2e5 bellard
{
7840 5905b2e5 bellard
    BlockDriverState *bs;
7841 2bac6019 balrog
    int i;
7842 5905b2e5 bellard
7843 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
7844 5905b2e5 bellard
        bs = get_bdrv(i);
7845 2bac6019 balrog
        if (bs)
7846 2bac6019 balrog
            qemu_key_check(bs, bdrv_get_device_name(bs));
7847 5905b2e5 bellard
    }
7848 5905b2e5 bellard
}
7849 5905b2e5 bellard
7850 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
7851 9596ebb7 pbrook
static void register_machines(void)
7852 cc1daa40 bellard
{
7853 cc1daa40 bellard
#if defined(TARGET_I386)
7854 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
7855 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
7856 cc1daa40 bellard
#elif defined(TARGET_PPC)
7857 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
7858 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
7859 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
7860 1a6c0886 j_mayer
    qemu_register_machine(&ref405ep_machine);
7861 1a6c0886 j_mayer
    qemu_register_machine(&taihu_machine);
7862 6af0bf9c bellard
#elif defined(TARGET_MIPS)
7863 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
7864 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
7865 ad6fe1d2 ths
    qemu_register_machine(&mips_pica61_machine);
7866 6bf5b4e8 ths
    qemu_register_machine(&mips_mipssim_machine);
7867 cc1daa40 bellard
#elif defined(TARGET_SPARC)
7868 3475187d bellard
#ifdef TARGET_SPARC64
7869 3475187d bellard
    qemu_register_machine(&sun4u_machine);
7870 3475187d bellard
#else
7871 36cd9210 blueswir1
    qemu_register_machine(&ss5_machine);
7872 e0353fe2 blueswir1
    qemu_register_machine(&ss10_machine);
7873 6a3b9cc9 blueswir1
    qemu_register_machine(&ss600mp_machine);
7874 ae40972f blueswir1
    qemu_register_machine(&ss20_machine);
7875 cc1daa40 bellard
#endif
7876 b5ff1b31 bellard
#elif defined(TARGET_ARM)
7877 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
7878 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
7879 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
7880 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
7881 b00052e4 balrog
    qemu_register_machine(&akitapda_machine);
7882 b00052e4 balrog
    qemu_register_machine(&spitzpda_machine);
7883 b00052e4 balrog
    qemu_register_machine(&borzoipda_machine);
7884 b00052e4 balrog
    qemu_register_machine(&terrierpda_machine);
7885 c3d2689d balrog
    qemu_register_machine(&palmte_machine);
7886 9ee6e8bb pbrook
    qemu_register_machine(&lm3s811evb_machine);
7887 9ee6e8bb pbrook
    qemu_register_machine(&lm3s6965evb_machine);
7888 05ee37eb balrog
    qemu_register_machine(&connex_machine);
7889 3e3f6754 balrog
    qemu_register_machine(&verdex_machine);
7890 ef056e43 balrog
    qemu_register_machine(&mainstone2_machine);
7891 27c7ca7e bellard
#elif defined(TARGET_SH4)
7892 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
7893 0d78f544 ths
    qemu_register_machine(&r2d_machine);
7894 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
7895 eddf68a6 j_mayer
    /* XXX: TODO */
7896 0633879f pbrook
#elif defined(TARGET_M68K)
7897 20dcee94 pbrook
    qemu_register_machine(&mcf5208evb_machine);
7898 0633879f pbrook
    qemu_register_machine(&an5206_machine);
7899 ca02f319 pbrook
    qemu_register_machine(&dummy_m68k_machine);
7900 f1ccf904 ths
#elif defined(TARGET_CRIS)
7901 f1ccf904 ths
    qemu_register_machine(&bareetraxfs_machine);
7902 b5ff1b31 bellard
#else
7903 b5ff1b31 bellard
#error unsupported CPU
7904 3475187d bellard
#endif
7905 cc1daa40 bellard
}
7906 cc1daa40 bellard
7907 1d14ffa9 bellard
#ifdef HAS_AUDIO
7908 6a36d84e bellard
struct soundhw soundhw[] = {
7909 b00052e4 balrog
#ifdef HAS_AUDIO_CHOICE
7910 fd06c375 bellard
#ifdef TARGET_I386
7911 fd06c375 bellard
    {
7912 fd06c375 bellard
        "pcspk",
7913 fd06c375 bellard
        "PC speaker",
7914 fd06c375 bellard
        0,
7915 fd06c375 bellard
        1,
7916 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
7917 fd06c375 bellard
    },
7918 fd06c375 bellard
#endif
7919 6a36d84e bellard
    {
7920 6a36d84e bellard
        "sb16",
7921 6a36d84e bellard
        "Creative Sound Blaster 16",
7922 6a36d84e bellard
        0,
7923 6a36d84e bellard
        1,
7924 6a36d84e bellard
        { .init_isa = SB16_init }
7925 6a36d84e bellard
    },
7926 6a36d84e bellard
7927 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
7928 6a36d84e bellard
    {
7929 6a36d84e bellard
        "adlib",
7930 1d14ffa9 bellard
#ifdef HAS_YMF262
7931 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
7932 1d14ffa9 bellard
#else
7933 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
7934 1d14ffa9 bellard
#endif
7935 6a36d84e bellard
        0,
7936 6a36d84e bellard
        1,
7937 6a36d84e bellard
        { .init_isa = Adlib_init }
7938 6a36d84e bellard
    },
7939 1d14ffa9 bellard
#endif
7940 6a36d84e bellard
7941 1d14ffa9 bellard
#ifdef CONFIG_GUS
7942 6a36d84e bellard
    {
7943 6a36d84e bellard
        "gus",
7944 6a36d84e bellard
        "Gravis Ultrasound GF1",
7945 6a36d84e bellard
        0,
7946 6a36d84e bellard
        1,
7947 6a36d84e bellard
        { .init_isa = GUS_init }
7948 6a36d84e bellard
    },
7949 1d14ffa9 bellard
#endif
7950 6a36d84e bellard
7951 6a36d84e bellard
    {
7952 6a36d84e bellard
        "es1370",
7953 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
7954 6a36d84e bellard
        0,
7955 6a36d84e bellard
        0,
7956 6a36d84e bellard
        { .init_pci = es1370_init }
7957 6a36d84e bellard
    },
7958 b00052e4 balrog
#endif
7959 6a36d84e bellard
7960 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
7961 6a36d84e bellard
};
7962 6a36d84e bellard
7963 6a36d84e bellard
static void select_soundhw (const char *optarg)
7964 6a36d84e bellard
{
7965 6a36d84e bellard
    struct soundhw *c;
7966 6a36d84e bellard
7967 6a36d84e bellard
    if (*optarg == '?') {
7968 6a36d84e bellard
    show_valid_cards:
7969 6a36d84e bellard
7970 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
7971 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
7972 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
7973 6a36d84e bellard
        }
7974 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
7975 1d14ffa9 bellard
        exit (*optarg != '?');
7976 1d14ffa9 bellard
    }
7977 1d14ffa9 bellard
    else {
7978 6a36d84e bellard
        size_t l;
7979 1d14ffa9 bellard
        const char *p;
7980 1d14ffa9 bellard
        char *e;
7981 1d14ffa9 bellard
        int bad_card = 0;
7982 1d14ffa9 bellard
7983 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
7984 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7985 6a36d84e bellard
                c->enabled = 1;
7986 6a36d84e bellard
            }
7987 6a36d84e bellard
            return;
7988 6a36d84e bellard
        }
7989 1d14ffa9 bellard
7990 6a36d84e bellard
        p = optarg;
7991 1d14ffa9 bellard
        while (*p) {
7992 1d14ffa9 bellard
            e = strchr (p, ',');
7993 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
7994 6a36d84e bellard
7995 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
7996 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
7997 6a36d84e bellard
                    c->enabled = 1;
7998 1d14ffa9 bellard
                    break;
7999 1d14ffa9 bellard
                }
8000 1d14ffa9 bellard
            }
8001 6a36d84e bellard
8002 6a36d84e bellard
            if (!c->name) {
8003 1d14ffa9 bellard
                if (l > 80) {
8004 1d14ffa9 bellard
                    fprintf (stderr,
8005 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
8006 1d14ffa9 bellard
                }
8007 1d14ffa9 bellard
                else {
8008 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
8009 1d14ffa9 bellard
                             (int) l, p);
8010 1d14ffa9 bellard
                }
8011 1d14ffa9 bellard
                bad_card = 1;
8012 1d14ffa9 bellard
            }
8013 1d14ffa9 bellard
            p += l + (e != NULL);
8014 1d14ffa9 bellard
        }
8015 1d14ffa9 bellard
8016 1d14ffa9 bellard
        if (bad_card)
8017 1d14ffa9 bellard
            goto show_valid_cards;
8018 1d14ffa9 bellard
    }
8019 1d14ffa9 bellard
}
8020 1d14ffa9 bellard
#endif
8021 1d14ffa9 bellard
8022 3587d7e6 bellard
#ifdef _WIN32
8023 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
8024 3587d7e6 bellard
{
8025 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
8026 3587d7e6 bellard
    return TRUE;
8027 3587d7e6 bellard
}
8028 3587d7e6 bellard
#endif
8029 3587d7e6 bellard
8030 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
8031 c20709aa bellard
8032 0824d6fc bellard
int main(int argc, char **argv)
8033 0824d6fc bellard
{
8034 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8035 cfc3475a pbrook
    int use_gdbstub;
8036 cfc3475a pbrook
    const char *gdbstub_port;
8037 67b915a5 bellard
#endif
8038 28c5af54 j_mayer
    uint32_t boot_devices_bitmap = 0;
8039 e4bcb14c ths
    int i;
8040 28c5af54 j_mayer
    int snapshot, linux_boot, net_boot;
8041 7f7f9873 bellard
    const char *initrd_filename;
8042 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
8043 28c5af54 j_mayer
    const char *boot_devices = "";
8044 313aa567 bellard
    DisplayState *ds = &display_state;
8045 46d4767d bellard
    int cyls, heads, secs, translation;
8046 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
8047 7c9d8e07 bellard
    int nb_net_clients;
8048 e4bcb14c ths
    int hda_index;
8049 cd6f1169 bellard
    int optind;
8050 cd6f1169 bellard
    const char *r, *optarg;
8051 82c643ff bellard
    CharDriverState *monitor_hd;
8052 82c643ff bellard
    char monitor_device[128];
8053 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
8054 8d11df9e bellard
    int serial_device_index;
8055 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
8056 6508fe59 bellard
    int parallel_device_index;
8057 d63d307f bellard
    const char *loadvm = NULL;
8058 cc1daa40 bellard
    QEMUMachine *machine;
8059 94fc95cd j_mayer
    const char *cpu_model;
8060 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
8061 a594cfbf bellard
    int usb_devices_index;
8062 71e3ceb8 ths
    int fds[2];
8063 93815bc2 ths
    const char *pid_file = NULL;
8064 833c7174 blueswir1
    VLANState *vlan;
8065 0bd48850 bellard
8066 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
8067 be995c27 bellard
#ifndef _WIN32
8068 be995c27 bellard
    {
8069 be995c27 bellard
        struct sigaction act;
8070 be995c27 bellard
        sigfillset(&act.sa_mask);
8071 be995c27 bellard
        act.sa_flags = 0;
8072 be995c27 bellard
        act.sa_handler = SIG_IGN;
8073 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
8074 be995c27 bellard
    }
8075 3587d7e6 bellard
#else
8076 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
8077 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
8078 a8e5ac33 bellard
       QEMU to run on a single CPU */
8079 a8e5ac33 bellard
    {
8080 a8e5ac33 bellard
        HANDLE h;
8081 a8e5ac33 bellard
        DWORD mask, smask;
8082 a8e5ac33 bellard
        int i;
8083 a8e5ac33 bellard
        h = GetCurrentProcess();
8084 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
8085 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
8086 a8e5ac33 bellard
                if (mask & (1 << i))
8087 a8e5ac33 bellard
                    break;
8088 a8e5ac33 bellard
            }
8089 a8e5ac33 bellard
            if (i != 32) {
8090 a8e5ac33 bellard
                mask = 1 << i;
8091 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
8092 a8e5ac33 bellard
            }
8093 a8e5ac33 bellard
        }
8094 a8e5ac33 bellard
    }
8095 67b915a5 bellard
#endif
8096 be995c27 bellard
8097 cc1daa40 bellard
    register_machines();
8098 cc1daa40 bellard
    machine = first_machine;
8099 94fc95cd j_mayer
    cpu_model = NULL;
8100 fc01f7e7 bellard
    initrd_filename = NULL;
8101 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
8102 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
8103 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8104 b4608c04 bellard
    use_gdbstub = 0;
8105 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
8106 67b915a5 bellard
#endif
8107 33e3963e bellard
    snapshot = 0;
8108 a20dd508 bellard
    nographic = 0;
8109 a20dd508 bellard
    kernel_filename = NULL;
8110 a20dd508 bellard
    kernel_cmdline = "";
8111 c4b1fcc0 bellard
    cyls = heads = secs = 0;
8112 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
8113 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
8114 c4b1fcc0 bellard
8115 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
8116 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
8117 8d11df9e bellard
        serial_devices[i][0] = '\0';
8118 8d11df9e bellard
    serial_device_index = 0;
8119 3b46e624 ths
8120 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
8121 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
8122 6508fe59 bellard
        parallel_devices[i][0] = '\0';
8123 6508fe59 bellard
    parallel_device_index = 0;
8124 3b46e624 ths
8125 a594cfbf bellard
    usb_devices_index = 0;
8126 3b46e624 ths
8127 7c9d8e07 bellard
    nb_net_clients = 0;
8128 e4bcb14c ths
    nb_drives = 0;
8129 e4bcb14c ths
    nb_drives_opt = 0;
8130 e4bcb14c ths
    hda_index = -1;
8131 7c9d8e07 bellard
8132 7c9d8e07 bellard
    nb_nics = 0;
8133 702c651c bellard
    /* default mac address of the first network interface */
8134 3b46e624 ths
8135 cd6f1169 bellard
    optind = 1;
8136 0824d6fc bellard
    for(;;) {
8137 cd6f1169 bellard
        if (optind >= argc)
8138 0824d6fc bellard
            break;
8139 cd6f1169 bellard
        r = argv[optind];
8140 cd6f1169 bellard
        if (r[0] != '-') {
8141 e4bcb14c ths
            hda_index = drive_add(HD_ALIAS, argv[optind++], 0);
8142 cd6f1169 bellard
        } else {
8143 cd6f1169 bellard
            const QEMUOption *popt;
8144 cd6f1169 bellard
8145 cd6f1169 bellard
            optind++;
8146 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
8147 dff5efc8 pbrook
            if (r[1] == '-')
8148 dff5efc8 pbrook
                r++;
8149 cd6f1169 bellard
            popt = qemu_options;
8150 cd6f1169 bellard
            for(;;) {
8151 cd6f1169 bellard
                if (!popt->name) {
8152 5fafdf24 ths
                    fprintf(stderr, "%s: invalid option -- '%s'\n",
8153 cd6f1169 bellard
                            argv[0], r);
8154 cd6f1169 bellard
                    exit(1);
8155 cd6f1169 bellard
                }
8156 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
8157 cd6f1169 bellard
                    break;
8158 cd6f1169 bellard
                popt++;
8159 cd6f1169 bellard
            }
8160 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
8161 cd6f1169 bellard
                if (optind >= argc) {
8162 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
8163 cd6f1169 bellard
                            argv[0], r);
8164 cd6f1169 bellard
                    exit(1);
8165 cd6f1169 bellard
                }
8166 cd6f1169 bellard
                optarg = argv[optind++];
8167 cd6f1169 bellard
            } else {
8168 cd6f1169 bellard
                optarg = NULL;
8169 cd6f1169 bellard
            }
8170 cd6f1169 bellard
8171 cd6f1169 bellard
            switch(popt->index) {
8172 cc1daa40 bellard
            case QEMU_OPTION_M:
8173 cc1daa40 bellard
                machine = find_machine(optarg);
8174 cc1daa40 bellard
                if (!machine) {
8175 cc1daa40 bellard
                    QEMUMachine *m;
8176 cc1daa40 bellard
                    printf("Supported machines are:\n");
8177 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
8178 cc1daa40 bellard
                        printf("%-10s %s%s\n",
8179 5fafdf24 ths
                               m->name, m->desc,
8180 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
8181 cc1daa40 bellard
                    }
8182 15f82208 ths
                    exit(*optarg != '?');
8183 cc1daa40 bellard
                }
8184 cc1daa40 bellard
                break;
8185 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
8186 94fc95cd j_mayer
                /* hw initialization will check this */
8187 15f82208 ths
                if (*optarg == '?') {
8188 c732abe2 j_mayer
/* XXX: implement xxx_cpu_list for targets that still miss it */
8189 c732abe2 j_mayer
#if defined(cpu_list)
8190 c732abe2 j_mayer
                    cpu_list(stdout, &fprintf);
8191 94fc95cd j_mayer
#endif
8192 15f82208 ths
                    exit(0);
8193 94fc95cd j_mayer
                } else {
8194 94fc95cd j_mayer
                    cpu_model = optarg;
8195 94fc95cd j_mayer
                }
8196 94fc95cd j_mayer
                break;
8197 cd6f1169 bellard
            case QEMU_OPTION_initrd:
8198 fc01f7e7 bellard
                initrd_filename = optarg;
8199 fc01f7e7 bellard
                break;
8200 cd6f1169 bellard
            case QEMU_OPTION_hda:
8201 e4bcb14c ths
                if (cyls == 0)
8202 e4bcb14c ths
                    hda_index = drive_add(HD_ALIAS, optarg, 0);
8203 e4bcb14c ths
                else
8204 e4bcb14c ths
                    hda_index = drive_add(HD_ALIAS
8205 e4bcb14c ths
                             ",cyls=%d,heads=%d,secs=%d%s",
8206 e4bcb14c ths
                             optarg, 0, cyls, heads, secs,
8207 e4bcb14c ths
                             translation == BIOS_ATA_TRANSLATION_LBA ?
8208 e4bcb14c ths
                                 ",trans=lba" :
8209 e4bcb14c ths
                             translation == BIOS_ATA_TRANSLATION_NONE ?
8210 e4bcb14c ths
                                 ",trans=none" : "");
8211 e4bcb14c ths
                 break;
8212 cd6f1169 bellard
            case QEMU_OPTION_hdb:
8213 cc1daa40 bellard
            case QEMU_OPTION_hdc:
8214 cc1daa40 bellard
            case QEMU_OPTION_hdd:
8215 e4bcb14c ths
                drive_add(HD_ALIAS, optarg, popt->index - QEMU_OPTION_hda);
8216 fc01f7e7 bellard
                break;
8217 e4bcb14c ths
            case QEMU_OPTION_drive:
8218 e4bcb14c ths
                drive_add("%s", optarg);
8219 e4bcb14c ths
                break;
8220 3e3d5815 balrog
            case QEMU_OPTION_mtdblock:
8221 e4bcb14c ths
                drive_add(MTD_ALIAS, optarg);
8222 3e3d5815 balrog
                break;
8223 a1bb27b1 pbrook
            case QEMU_OPTION_sd:
8224 9d413d1d balrog
                drive_add("file=\"%s\"," SD_ALIAS, optarg);
8225 a1bb27b1 pbrook
                break;
8226 86f55663 j_mayer
            case QEMU_OPTION_pflash:
8227 e4bcb14c ths
                drive_add(PFLASH_ALIAS, optarg);
8228 86f55663 j_mayer
                break;
8229 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
8230 33e3963e bellard
                snapshot = 1;
8231 33e3963e bellard
                break;
8232 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
8233 330d0414 bellard
                {
8234 330d0414 bellard
                    const char *p;
8235 330d0414 bellard
                    p = optarg;
8236 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
8237 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
8238 46d4767d bellard
                        goto chs_fail;
8239 330d0414 bellard
                    if (*p != ',')
8240 330d0414 bellard
                        goto chs_fail;
8241 330d0414 bellard
                    p++;
8242 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
8243 46d4767d bellard
                    if (heads < 1 || heads > 16)
8244 46d4767d bellard
                        goto chs_fail;
8245 330d0414 bellard
                    if (*p != ',')
8246 330d0414 bellard
                        goto chs_fail;
8247 330d0414 bellard
                    p++;
8248 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
8249 46d4767d bellard
                    if (secs < 1 || secs > 63)
8250 46d4767d bellard
                        goto chs_fail;
8251 46d4767d bellard
                    if (*p == ',') {
8252 46d4767d bellard
                        p++;
8253 46d4767d bellard
                        if (!strcmp(p, "none"))
8254 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
8255 46d4767d bellard
                        else if (!strcmp(p, "lba"))
8256 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
8257 46d4767d bellard
                        else if (!strcmp(p, "auto"))
8258 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
8259 46d4767d bellard
                        else
8260 46d4767d bellard
                            goto chs_fail;
8261 46d4767d bellard
                    } else if (*p != '\0') {
8262 c4b1fcc0 bellard
                    chs_fail:
8263 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
8264 46d4767d bellard
                        exit(1);
8265 c4b1fcc0 bellard
                    }
8266 e4bcb14c ths
                    if (hda_index != -1)
8267 e4bcb14c ths
                        snprintf(drives_opt[hda_index] +
8268 e4bcb14c ths
                                 strlen(drives_opt[hda_index]),
8269 e4bcb14c ths
                                 sizeof(drives_opt[0]) -
8270 e4bcb14c ths
                                 strlen(drives_opt[hda_index]),
8271 e4bcb14c ths
                                 ",cyls=%d,heads=%d,secs=%d%s",
8272 e4bcb14c ths
                                 cyls, heads, secs,
8273 e4bcb14c ths
                                 translation == BIOS_ATA_TRANSLATION_LBA ?
8274 e4bcb14c ths
                                         ",trans=lba" :
8275 e4bcb14c ths
                                 translation == BIOS_ATA_TRANSLATION_NONE ?
8276 e4bcb14c ths
                                     ",trans=none" : "");
8277 330d0414 bellard
                }
8278 330d0414 bellard
                break;
8279 cd6f1169 bellard
            case QEMU_OPTION_nographic:
8280 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
8281 a39437aa ths
                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
8282 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
8283 a20dd508 bellard
                nographic = 1;
8284 a20dd508 bellard
                break;
8285 a171fe39 balrog
            case QEMU_OPTION_portrait:
8286 a171fe39 balrog
                graphic_rotate = 1;
8287 a171fe39 balrog
                break;
8288 cd6f1169 bellard
            case QEMU_OPTION_kernel:
8289 a20dd508 bellard
                kernel_filename = optarg;
8290 a20dd508 bellard
                break;
8291 cd6f1169 bellard
            case QEMU_OPTION_append:
8292 a20dd508 bellard
                kernel_cmdline = optarg;
8293 313aa567 bellard
                break;
8294 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
8295 e4bcb14c ths
                drive_add("file=\"%s\"," CDROM_ALIAS, optarg);
8296 36b486bb bellard
                break;
8297 cd6f1169 bellard
            case QEMU_OPTION_boot:
8298 28c5af54 j_mayer
                boot_devices = optarg;
8299 28c5af54 j_mayer
                /* We just do some generic consistency checks */
8300 28c5af54 j_mayer
                {
8301 28c5af54 j_mayer
                    /* Could easily be extended to 64 devices if needed */
8302 60fe76f3 ths
                    const char *p;
8303 28c5af54 j_mayer
                    
8304 28c5af54 j_mayer
                    boot_devices_bitmap = 0;
8305 28c5af54 j_mayer
                    for (p = boot_devices; *p != '\0'; p++) {
8306 28c5af54 j_mayer
                        /* Allowed boot devices are:
8307 28c5af54 j_mayer
                         * a b     : floppy disk drives
8308 28c5af54 j_mayer
                         * c ... f : IDE disk drives
8309 28c5af54 j_mayer
                         * g ... m : machine implementation dependant drives
8310 28c5af54 j_mayer
                         * n ... p : network devices
8311 28c5af54 j_mayer
                         * It's up to each machine implementation to check
8312 28c5af54 j_mayer
                         * if the given boot devices match the actual hardware
8313 28c5af54 j_mayer
                         * implementation and firmware features.
8314 28c5af54 j_mayer
                         */
8315 28c5af54 j_mayer
                        if (*p < 'a' || *p > 'q') {
8316 28c5af54 j_mayer
                            fprintf(stderr, "Invalid boot device '%c'\n", *p);
8317 28c5af54 j_mayer
                            exit(1);
8318 28c5af54 j_mayer
                        }
8319 28c5af54 j_mayer
                        if (boot_devices_bitmap & (1 << (*p - 'a'))) {
8320 28c5af54 j_mayer
                            fprintf(stderr,
8321 28c5af54 j_mayer
                                    "Boot device '%c' was given twice\n",*p);
8322 28c5af54 j_mayer
                            exit(1);
8323 28c5af54 j_mayer
                        }
8324 28c5af54 j_mayer
                        boot_devices_bitmap |= 1 << (*p - 'a');
8325 28c5af54 j_mayer
                    }
8326 36b486bb bellard
                }
8327 36b486bb bellard
                break;
8328 cd6f1169 bellard
            case QEMU_OPTION_fda:
8329 cd6f1169 bellard
            case QEMU_OPTION_fdb:
8330 e4bcb14c ths
                drive_add("file=\"%s\"," FD_ALIAS, optarg,
8331 e4bcb14c ths
                          popt->index - QEMU_OPTION_fda);
8332 c45886db bellard
                break;
8333 52ca8d6a bellard
#ifdef TARGET_I386
8334 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
8335 52ca8d6a bellard
                fd_bootchk = 0;
8336 52ca8d6a bellard
                break;
8337 52ca8d6a bellard
#endif
8338 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
8339 77fef8c1 bellard
                code_copy_enabled = 0;
8340 77fef8c1 bellard
                break;
8341 7c9d8e07 bellard
            case QEMU_OPTION_net:
8342 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
8343 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
8344 c4b1fcc0 bellard
                    exit(1);
8345 c4b1fcc0 bellard
                }
8346 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
8347 7c9d8e07 bellard
                        sizeof(net_clients[0]),
8348 7c9d8e07 bellard
                        optarg);
8349 7c9d8e07 bellard
                nb_net_clients++;
8350 702c651c bellard
                break;
8351 c7f74643 bellard
#ifdef CONFIG_SLIRP
8352 c7f74643 bellard
            case QEMU_OPTION_tftp:
8353 c7f74643 bellard
                tftp_prefix = optarg;
8354 9bf05444 bellard
                break;
8355 47d5d01a ths
            case QEMU_OPTION_bootp:
8356 47d5d01a ths
                bootp_filename = optarg;
8357 47d5d01a ths
                break;
8358 c94c8d64 bellard
#ifndef _WIN32
8359 9d728e8c bellard
            case QEMU_OPTION_smb:
8360 9d728e8c bellard
                net_slirp_smb(optarg);
8361 9d728e8c bellard
                break;
8362 c94c8d64 bellard
#endif
8363 9bf05444 bellard
            case QEMU_OPTION_redir:
8364 3b46e624 ths
                net_slirp_redir(optarg);
8365 9bf05444 bellard
                break;
8366 c7f74643 bellard
#endif
8367 1d14ffa9 bellard
#ifdef HAS_AUDIO
8368 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
8369 1d14ffa9 bellard
                AUD_help ();
8370 1d14ffa9 bellard
                exit (0);
8371 1d14ffa9 bellard
                break;
8372 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
8373 1d14ffa9 bellard
                select_soundhw (optarg);
8374 1d14ffa9 bellard
                break;
8375 1d14ffa9 bellard
#endif
8376 cd6f1169 bellard
            case QEMU_OPTION_h:
8377 15f82208 ths
                help(0);
8378 cd6f1169 bellard
                break;
8379 cd6f1169 bellard
            case QEMU_OPTION_m:
8380 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
8381 cd6f1169 bellard
                if (ram_size <= 0)
8382 15f82208 ths
                    help(1);
8383 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
8384 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
8385 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
8386 cd6f1169 bellard
                    exit(1);
8387 cd6f1169 bellard
                }
8388 cd6f1169 bellard
                break;
8389 cd6f1169 bellard
            case QEMU_OPTION_d:
8390 cd6f1169 bellard
                {
8391 cd6f1169 bellard
                    int mask;
8392 cd6f1169 bellard
                    CPULogItem *item;
8393 3b46e624 ths
8394 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
8395 cd6f1169 bellard
                    if (!mask) {
8396 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
8397 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
8398 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
8399 f193c797 bellard
                    }
8400 f193c797 bellard
                    exit(1);
8401 cd6f1169 bellard
                    }
8402 cd6f1169 bellard
                    cpu_set_log(mask);
8403 f193c797 bellard
                }
8404 cd6f1169 bellard
                break;
8405 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8406 cd6f1169 bellard
            case QEMU_OPTION_s:
8407 cd6f1169 bellard
                use_gdbstub = 1;
8408 cd6f1169 bellard
                break;
8409 cd6f1169 bellard
            case QEMU_OPTION_p:
8410 cfc3475a pbrook
                gdbstub_port = optarg;
8411 cd6f1169 bellard
                break;
8412 67b915a5 bellard
#endif
8413 cd6f1169 bellard
            case QEMU_OPTION_L:
8414 cd6f1169 bellard
                bios_dir = optarg;
8415 cd6f1169 bellard
                break;
8416 1192dad8 j_mayer
            case QEMU_OPTION_bios:
8417 1192dad8 j_mayer
                bios_name = optarg;
8418 1192dad8 j_mayer
                break;
8419 cd6f1169 bellard
            case QEMU_OPTION_S:
8420 3c07f8e8 pbrook
                autostart = 0;
8421 cd6f1169 bellard
                break;
8422 3d11d0eb bellard
            case QEMU_OPTION_k:
8423 3d11d0eb bellard
                keyboard_layout = optarg;
8424 3d11d0eb bellard
                break;
8425 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
8426 ee22c2f7 bellard
                rtc_utc = 0;
8427 ee22c2f7 bellard
                break;
8428 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
8429 1f04275e bellard
                cirrus_vga_enabled = 1;
8430 d34cab9f ths
                vmsvga_enabled = 0;
8431 d34cab9f ths
                break;
8432 d34cab9f ths
            case QEMU_OPTION_vmsvga:
8433 d34cab9f ths
                cirrus_vga_enabled = 0;
8434 d34cab9f ths
                vmsvga_enabled = 1;
8435 1f04275e bellard
                break;
8436 1bfe856e bellard
            case QEMU_OPTION_std_vga:
8437 1bfe856e bellard
                cirrus_vga_enabled = 0;
8438 d34cab9f ths
                vmsvga_enabled = 0;
8439 1bfe856e bellard
                break;
8440 e9b137c2 bellard
            case QEMU_OPTION_g:
8441 e9b137c2 bellard
                {
8442 e9b137c2 bellard
                    const char *p;
8443 e9b137c2 bellard
                    int w, h, depth;
8444 e9b137c2 bellard
                    p = optarg;
8445 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
8446 e9b137c2 bellard
                    if (w <= 0) {
8447 e9b137c2 bellard
                    graphic_error:
8448 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
8449 e9b137c2 bellard
                        exit(1);
8450 e9b137c2 bellard
                    }
8451 e9b137c2 bellard
                    if (*p != 'x')
8452 e9b137c2 bellard
                        goto graphic_error;
8453 e9b137c2 bellard
                    p++;
8454 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
8455 e9b137c2 bellard
                    if (h <= 0)
8456 e9b137c2 bellard
                        goto graphic_error;
8457 e9b137c2 bellard
                    if (*p == 'x') {
8458 e9b137c2 bellard
                        p++;
8459 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
8460 5fafdf24 ths
                        if (depth != 8 && depth != 15 && depth != 16 &&
8461 e9b137c2 bellard
                            depth != 24 && depth != 32)
8462 e9b137c2 bellard
                            goto graphic_error;
8463 e9b137c2 bellard
                    } else if (*p == '\0') {
8464 e9b137c2 bellard
                        depth = graphic_depth;
8465 e9b137c2 bellard
                    } else {
8466 e9b137c2 bellard
                        goto graphic_error;
8467 e9b137c2 bellard
                    }
8468 3b46e624 ths
8469 e9b137c2 bellard
                    graphic_width = w;
8470 e9b137c2 bellard
                    graphic_height = h;
8471 e9b137c2 bellard
                    graphic_depth = depth;
8472 e9b137c2 bellard
                }
8473 e9b137c2 bellard
                break;
8474 20d8a3ed ths
            case QEMU_OPTION_echr:
8475 20d8a3ed ths
                {
8476 20d8a3ed ths
                    char *r;
8477 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
8478 20d8a3ed ths
                    if (r == optarg)
8479 20d8a3ed ths
                        printf("Bad argument to echr\n");
8480 20d8a3ed ths
                    break;
8481 20d8a3ed ths
                }
8482 82c643ff bellard
            case QEMU_OPTION_monitor:
8483 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
8484 82c643ff bellard
                break;
8485 82c643ff bellard
            case QEMU_OPTION_serial:
8486 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
8487 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
8488 8d11df9e bellard
                    exit(1);
8489 8d11df9e bellard
                }
8490 5fafdf24 ths
                pstrcpy(serial_devices[serial_device_index],
8491 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
8492 8d11df9e bellard
                serial_device_index++;
8493 82c643ff bellard
                break;
8494 6508fe59 bellard
            case QEMU_OPTION_parallel:
8495 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
8496 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
8497 6508fe59 bellard
                    exit(1);
8498 6508fe59 bellard
                }
8499 5fafdf24 ths
                pstrcpy(parallel_devices[parallel_device_index],
8500 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
8501 6508fe59 bellard
                parallel_device_index++;
8502 6508fe59 bellard
                break;
8503 d63d307f bellard
            case QEMU_OPTION_loadvm:
8504 d63d307f bellard
                loadvm = optarg;
8505 d63d307f bellard
                break;
8506 d63d307f bellard
            case QEMU_OPTION_full_screen:
8507 d63d307f bellard
                full_screen = 1;
8508 d63d307f bellard
                break;
8509 667accab ths
#ifdef CONFIG_SDL
8510 43523e93 ths
            case QEMU_OPTION_no_frame:
8511 43523e93 ths
                no_frame = 1;
8512 43523e93 ths
                break;
8513 3780e197 ths
            case QEMU_OPTION_alt_grab:
8514 3780e197 ths
                alt_grab = 1;
8515 3780e197 ths
                break;
8516 667accab ths
            case QEMU_OPTION_no_quit:
8517 667accab ths
                no_quit = 1;
8518 667accab ths
                break;
8519 667accab ths
#endif
8520 f7cce898 bellard
            case QEMU_OPTION_pidfile:
8521 93815bc2 ths
                pid_file = optarg;
8522 f7cce898 bellard
                break;
8523 a09db21f bellard
#ifdef TARGET_I386
8524 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
8525 a09db21f bellard
                win2k_install_hack = 1;
8526 a09db21f bellard
                break;
8527 a09db21f bellard
#endif
8528 d993e026 bellard
#ifdef USE_KQEMU
8529 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
8530 d993e026 bellard
                kqemu_allowed = 0;
8531 d993e026 bellard
                break;
8532 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
8533 89bfc105 bellard
                kqemu_allowed = 2;
8534 89bfc105 bellard
                break;
8535 d993e026 bellard
#endif
8536 bb36d470 bellard
            case QEMU_OPTION_usb:
8537 bb36d470 bellard
                usb_enabled = 1;
8538 bb36d470 bellard
                break;
8539 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
8540 a594cfbf bellard
                usb_enabled = 1;
8541 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
8542 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
8543 a594cfbf bellard
                    exit(1);
8544 a594cfbf bellard
                }
8545 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
8546 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
8547 a594cfbf bellard
                        optarg);
8548 a594cfbf bellard
                usb_devices_index++;
8549 a594cfbf bellard
                break;
8550 6a00d601 bellard
            case QEMU_OPTION_smp:
8551 6a00d601 bellard
                smp_cpus = atoi(optarg);
8552 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
8553 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
8554 6a00d601 bellard
                    exit(1);
8555 6a00d601 bellard
                }
8556 6a00d601 bellard
                break;
8557 24236869 bellard
            case QEMU_OPTION_vnc:
8558 73fc9742 ths
                vnc_display = optarg;
8559 24236869 bellard
                break;
8560 6515b203 bellard
            case QEMU_OPTION_no_acpi:
8561 6515b203 bellard
                acpi_enabled = 0;
8562 6515b203 bellard
                break;
8563 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
8564 d1beab82 bellard
                no_reboot = 1;
8565 d1beab82 bellard
                break;
8566 9467cd46 balrog
            case QEMU_OPTION_show_cursor:
8567 9467cd46 balrog
                cursor_hide = 0;
8568 9467cd46 balrog
                break;
8569 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
8570 71e3ceb8 ths
                daemonize = 1;
8571 71e3ceb8 ths
                break;
8572 9ae02555 ths
            case QEMU_OPTION_option_rom:
8573 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
8574 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
8575 9ae02555 ths
                    exit(1);
8576 9ae02555 ths
                }
8577 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
8578 9ae02555 ths
                nb_option_roms++;
8579 9ae02555 ths
                break;
8580 8e71621f pbrook
            case QEMU_OPTION_semihosting:
8581 8e71621f pbrook
                semihosting_enabled = 1;
8582 8e71621f pbrook
                break;
8583 c35734b2 ths
            case QEMU_OPTION_name:
8584 c35734b2 ths
                qemu_name = optarg;
8585 c35734b2 ths
                break;
8586 66508601 blueswir1
#ifdef TARGET_SPARC
8587 66508601 blueswir1
            case QEMU_OPTION_prom_env:
8588 66508601 blueswir1
                if (nb_prom_envs >= MAX_PROM_ENVS) {
8589 66508601 blueswir1
                    fprintf(stderr, "Too many prom variables\n");
8590 66508601 blueswir1
                    exit(1);
8591 66508601 blueswir1
                }
8592 66508601 blueswir1
                prom_envs[nb_prom_envs] = optarg;
8593 66508601 blueswir1
                nb_prom_envs++;
8594 66508601 blueswir1
                break;
8595 66508601 blueswir1
#endif
8596 2b8f2d41 balrog
#ifdef TARGET_ARM
8597 2b8f2d41 balrog
            case QEMU_OPTION_old_param:
8598 2b8f2d41 balrog
                old_param = 1;
8599 2b8f2d41 balrog
#endif
8600 f3dcfada ths
            case QEMU_OPTION_clock:
8601 f3dcfada ths
                configure_alarms(optarg);
8602 f3dcfada ths
                break;
8603 7e0af5d0 bellard
            case QEMU_OPTION_startdate:
8604 7e0af5d0 bellard
                {
8605 7e0af5d0 bellard
                    struct tm tm;
8606 7e0af5d0 bellard
                    if (!strcmp(optarg, "now")) {
8607 7e0af5d0 bellard
                        rtc_start_date = -1;
8608 7e0af5d0 bellard
                    } else {
8609 7e0af5d0 bellard
                        if (sscanf(optarg, "%d-%d-%dT%d:%d:%d",
8610 7e0af5d0 bellard
                               &tm.tm_year,
8611 7e0af5d0 bellard
                               &tm.tm_mon,
8612 7e0af5d0 bellard
                               &tm.tm_mday,
8613 7e0af5d0 bellard
                               &tm.tm_hour,
8614 7e0af5d0 bellard
                               &tm.tm_min,
8615 7e0af5d0 bellard
                               &tm.tm_sec) == 6) {
8616 7e0af5d0 bellard
                            /* OK */
8617 7e0af5d0 bellard
                        } else if (sscanf(optarg, "%d-%d-%d",
8618 7e0af5d0 bellard
                                          &tm.tm_year,
8619 7e0af5d0 bellard
                                          &tm.tm_mon,
8620 7e0af5d0 bellard
                                          &tm.tm_mday) == 3) {
8621 7e0af5d0 bellard
                            tm.tm_hour = 0;
8622 7e0af5d0 bellard
                            tm.tm_min = 0;
8623 7e0af5d0 bellard
                            tm.tm_sec = 0;
8624 7e0af5d0 bellard
                        } else {
8625 7e0af5d0 bellard
                            goto date_fail;
8626 7e0af5d0 bellard
                        }
8627 7e0af5d0 bellard
                        tm.tm_year -= 1900;
8628 7e0af5d0 bellard
                        tm.tm_mon--;
8629 3c6b2088 bellard
                        rtc_start_date = mktimegm(&tm);
8630 7e0af5d0 bellard
                        if (rtc_start_date == -1) {
8631 7e0af5d0 bellard
                        date_fail:
8632 7e0af5d0 bellard
                            fprintf(stderr, "Invalid date format. Valid format are:\n"
8633 7e0af5d0 bellard
                                    "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
8634 7e0af5d0 bellard
                            exit(1);
8635 7e0af5d0 bellard
                        }
8636 7e0af5d0 bellard
                    }
8637 7e0af5d0 bellard
                }
8638 7e0af5d0 bellard
                break;
8639 cd6f1169 bellard
            }
8640 0824d6fc bellard
        }
8641 0824d6fc bellard
    }
8642 330d0414 bellard
8643 71e3ceb8 ths
#ifndef _WIN32
8644 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
8645 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
8646 71e3ceb8 ths
        daemonize = 0;
8647 71e3ceb8 ths
    }
8648 71e3ceb8 ths
8649 71e3ceb8 ths
    if (daemonize) {
8650 71e3ceb8 ths
        pid_t pid;
8651 71e3ceb8 ths
8652 71e3ceb8 ths
        if (pipe(fds) == -1)
8653 71e3ceb8 ths
            exit(1);
8654 71e3ceb8 ths
8655 71e3ceb8 ths
        pid = fork();
8656 71e3ceb8 ths
        if (pid > 0) {
8657 71e3ceb8 ths
            uint8_t status;
8658 71e3ceb8 ths
            ssize_t len;
8659 71e3ceb8 ths
8660 71e3ceb8 ths
            close(fds[1]);
8661 71e3ceb8 ths
8662 71e3ceb8 ths
        again:
8663 93815bc2 ths
            len = read(fds[0], &status, 1);
8664 93815bc2 ths
            if (len == -1 && (errno == EINTR))
8665 93815bc2 ths
                goto again;
8666 93815bc2 ths
8667 93815bc2 ths
            if (len != 1)
8668 93815bc2 ths
                exit(1);
8669 93815bc2 ths
            else if (status == 1) {
8670 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
8671 93815bc2 ths
                exit(1);
8672 93815bc2 ths
            } else
8673 93815bc2 ths
                exit(0);
8674 71e3ceb8 ths
        } else if (pid < 0)
8675 93815bc2 ths
            exit(1);
8676 71e3ceb8 ths
8677 71e3ceb8 ths
        setsid();
8678 71e3ceb8 ths
8679 71e3ceb8 ths
        pid = fork();
8680 71e3ceb8 ths
        if (pid > 0)
8681 71e3ceb8 ths
            exit(0);
8682 71e3ceb8 ths
        else if (pid < 0)
8683 71e3ceb8 ths
            exit(1);
8684 71e3ceb8 ths
8685 71e3ceb8 ths
        umask(027);
8686 71e3ceb8 ths
        chdir("/");
8687 71e3ceb8 ths
8688 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
8689 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
8690 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
8691 71e3ceb8 ths
    }
8692 71e3ceb8 ths
#endif
8693 71e3ceb8 ths
8694 aa26bb2d ths
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
8695 93815bc2 ths
        if (daemonize) {
8696 93815bc2 ths
            uint8_t status = 1;
8697 93815bc2 ths
            write(fds[1], &status, 1);
8698 93815bc2 ths
        } else
8699 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
8700 93815bc2 ths
        exit(1);
8701 93815bc2 ths
    }
8702 93815bc2 ths
8703 ff3fbb30 bellard
#ifdef USE_KQEMU
8704 ff3fbb30 bellard
    if (smp_cpus > 1)
8705 ff3fbb30 bellard
        kqemu_allowed = 0;
8706 ff3fbb30 bellard
#endif
8707 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
8708 7317b8ca balrog
    net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
8709 6c41b272 balrog
8710 28c5af54 j_mayer
    /* XXX: this should not be: some embedded targets just have flash */
8711 28c5af54 j_mayer
    if (!linux_boot && net_boot == 0 &&
8712 e4bcb14c ths
        nb_drives_opt == 0)
8713 15f82208 ths
        help(1);
8714 0824d6fc bellard
8715 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
8716 28c5af54 j_mayer
    if (!boot_devices[0]) {
8717 e4bcb14c ths
        boot_devices = "cad";
8718 96d30e48 ths
    }
8719 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
8720 3b46e624 ths
8721 634fce96 pbrook
    init_timers();
8722 634fce96 pbrook
    init_timer_alarm();
8723 83f64091 bellard
    qemu_aio_init();
8724 634fce96 pbrook
8725 fd1dff4b bellard
#ifdef _WIN32
8726 fd1dff4b bellard
    socket_init();
8727 fd1dff4b bellard
#endif
8728 fd1dff4b bellard
8729 7c9d8e07 bellard
    /* init network clients */
8730 7c9d8e07 bellard
    if (nb_net_clients == 0) {
8731 7c9d8e07 bellard
        /* if no clients, we use a default config */
8732 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
8733 7c9d8e07 bellard
                "nic");
8734 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
8735 7c9d8e07 bellard
                "user");
8736 7c9d8e07 bellard
        nb_net_clients = 2;
8737 c20709aa bellard
    }
8738 c20709aa bellard
8739 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
8740 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
8741 7c9d8e07 bellard
            exit(1);
8742 702c651c bellard
    }
8743 833c7174 blueswir1
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8744 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0 && vlan->nb_host_devs == 0)
8745 833c7174 blueswir1
            continue;
8746 833c7174 blueswir1
        if (vlan->nb_guest_devs == 0) {
8747 833c7174 blueswir1
            fprintf(stderr, "Invalid vlan (%d) with no nics\n", vlan->id);
8748 833c7174 blueswir1
            exit(1);
8749 833c7174 blueswir1
        }
8750 833c7174 blueswir1
        if (vlan->nb_host_devs == 0)
8751 833c7174 blueswir1
            fprintf(stderr,
8752 833c7174 blueswir1
                    "Warning: vlan %d is not connected to host network\n",
8753 833c7174 blueswir1
                    vlan->id);
8754 833c7174 blueswir1
    }
8755 f1510b2c bellard
8756 eec85c2a ths
#ifdef TARGET_I386
8757 ed494d87 balrog
    /* XXX: this should be moved in the PC machine instantiation code */
8758 28c5af54 j_mayer
    if (net_boot != 0) {
8759 28c5af54 j_mayer
        int netroms = 0;
8760 28c5af54 j_mayer
        for (i = 0; i < nb_nics && i < 4; i++) {
8761 eec85c2a ths
            const char *model = nd_table[i].model;
8762 eec85c2a ths
            char buf[1024];
8763 28c5af54 j_mayer
            if (net_boot & (1 << i)) {
8764 28c5af54 j_mayer
                if (model == NULL)
8765 28c5af54 j_mayer
                    model = "ne2k_pci";
8766 28c5af54 j_mayer
                snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
8767 28c5af54 j_mayer
                if (get_image_size(buf) > 0) {
8768 28c5af54 j_mayer
                    if (nb_option_roms >= MAX_OPTION_ROMS) {
8769 28c5af54 j_mayer
                        fprintf(stderr, "Too many option ROMs\n");
8770 28c5af54 j_mayer
                        exit(1);
8771 28c5af54 j_mayer
                    }
8772 28c5af54 j_mayer
                    option_rom[nb_option_roms] = strdup(buf);
8773 28c5af54 j_mayer
                    nb_option_roms++;
8774 28c5af54 j_mayer
                    netroms++;
8775 28c5af54 j_mayer
                }
8776 28c5af54 j_mayer
            }
8777 eec85c2a ths
        }
8778 28c5af54 j_mayer
        if (netroms == 0) {
8779 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
8780 eec85c2a ths
            exit(1);
8781 eec85c2a ths
        }
8782 eec85c2a ths
    }
8783 eec85c2a ths
#endif
8784 eec85c2a ths
8785 0824d6fc bellard
    /* init the memory */
8786 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
8787 9ae02555 ths
8788 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
8789 7f7f9873 bellard
    if (!phys_ram_base) {
8790 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
8791 0824d6fc bellard
        exit(1);
8792 0824d6fc bellard
    }
8793 0824d6fc bellard
8794 5905b2e5 bellard
    bdrv_init();
8795 c4b1fcc0 bellard
8796 e4bcb14c ths
    /* we always create the cdrom drive, even if no disk is there */
8797 c4b1fcc0 bellard
8798 e4bcb14c ths
    if (nb_drives_opt < MAX_DRIVES)
8799 e4bcb14c ths
        drive_add(CDROM_ALIAS);
8800 c4b1fcc0 bellard
8801 9d413d1d balrog
    /* we always create at least one floppy */
8802 33e3963e bellard
8803 e4bcb14c ths
    if (nb_drives_opt < MAX_DRIVES)
8804 e4bcb14c ths
        drive_add(FD_ALIAS, 0);
8805 86f55663 j_mayer
8806 9d413d1d balrog
    /* we always create one sd slot, even if no card is in it */
8807 9d413d1d balrog
8808 9d413d1d balrog
    if (nb_drives_opt < MAX_DRIVES)
8809 9d413d1d balrog
        drive_add(SD_ALIAS);
8810 9d413d1d balrog
8811 e4bcb14c ths
    /* open the virtual block devices */
8812 e4bcb14c ths
8813 e4bcb14c ths
    for(i = 0; i < nb_drives_opt; i++)
8814 e4bcb14c ths
        if (drive_init(drives_opt[i], snapshot, machine) == -1)
8815 e4bcb14c ths
            exit(1);
8816 3e3d5815 balrog
8817 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
8818 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
8819 8a7ddc38 bellard
8820 330d0414 bellard
    init_ioports();
8821 0824d6fc bellard
8822 313aa567 bellard
    /* terminal init */
8823 740733bb ths
    memset(&display_state, 0, sizeof(display_state));
8824 a20dd508 bellard
    if (nographic) {
8825 2ff89790 ths
        /* nearly nothing to do */
8826 2ff89790 ths
        dumb_display_init(ds);
8827 73fc9742 ths
    } else if (vnc_display != NULL) {
8828 71cab5ca ths
        vnc_display_init(ds);
8829 71cab5ca ths
        if (vnc_display_open(ds, vnc_display) < 0)
8830 71cab5ca ths
            exit(1);
8831 313aa567 bellard
    } else {
8832 5b0753e0 bellard
#if defined(CONFIG_SDL)
8833 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
8834 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
8835 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
8836 67276f53 pbrook
#else
8837 67276f53 pbrook
        dumb_display_init(ds);
8838 313aa567 bellard
#endif
8839 313aa567 bellard
    }
8840 0824d6fc bellard
8841 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
8842 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
8843 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
8844 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
8845 20d8a3ed ths
                monitor_device[0] = '\0';
8846 20d8a3ed ths
                break;
8847 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
8848 20d8a3ed ths
                monitor_device[0] = '\0';
8849 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
8850 20d8a3ed ths
                break;
8851 20d8a3ed ths
            }
8852 20d8a3ed ths
        }
8853 20d8a3ed ths
    }
8854 20d8a3ed ths
    if (monitor_device[0] != '\0') {
8855 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
8856 20d8a3ed ths
        if (!monitor_hd) {
8857 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
8858 20d8a3ed ths
            exit(1);
8859 20d8a3ed ths
        }
8860 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
8861 82c643ff bellard
    }
8862 82c643ff bellard
8863 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
8864 c03b0f0f bellard
        const char *devname = serial_devices[i];
8865 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8866 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
8867 8d11df9e bellard
            if (!serial_hds[i]) {
8868 5fafdf24 ths
                fprintf(stderr, "qemu: could not open serial device '%s'\n",
8869 c03b0f0f bellard
                        devname);
8870 8d11df9e bellard
                exit(1);
8871 8d11df9e bellard
            }
8872 af3a9031 ths
            if (strstart(devname, "vc", 0))
8873 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
8874 8d11df9e bellard
        }
8875 82c643ff bellard
    }
8876 82c643ff bellard
8877 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
8878 c03b0f0f bellard
        const char *devname = parallel_devices[i];
8879 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
8880 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
8881 6508fe59 bellard
            if (!parallel_hds[i]) {
8882 5fafdf24 ths
                fprintf(stderr, "qemu: could not open parallel device '%s'\n",
8883 c03b0f0f bellard
                        devname);
8884 6508fe59 bellard
                exit(1);
8885 6508fe59 bellard
            }
8886 af3a9031 ths
            if (strstart(devname, "vc", 0))
8887 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
8888 6508fe59 bellard
        }
8889 6508fe59 bellard
    }
8890 6508fe59 bellard
8891 b881c2c6 blueswir1
    machine->init(ram_size, vga_ram_size, boot_devices, ds,
8892 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
8893 73332e5c bellard
8894 0d92ed30 pbrook
    /* init USB devices */
8895 0d92ed30 pbrook
    if (usb_enabled) {
8896 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
8897 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
8898 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
8899 0d92ed30 pbrook
                        usb_devices[i]);
8900 0d92ed30 pbrook
            }
8901 0d92ed30 pbrook
        }
8902 0d92ed30 pbrook
    }
8903 0d92ed30 pbrook
8904 740733bb ths
    if (display_state.dpy_refresh) {
8905 740733bb ths
        display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
8906 740733bb ths
        qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
8907 740733bb ths
    }
8908 7f7f9873 bellard
8909 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
8910 b4608c04 bellard
    if (use_gdbstub) {
8911 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
8912 c636bb66 bellard
           accordingly. */
8913 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
8914 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
8915 c636bb66 bellard
                    gdbstub_port);
8916 8a7ddc38 bellard
            exit(1);
8917 8a7ddc38 bellard
        }
8918 45669e00 balrog
    }
8919 67b915a5 bellard
#endif
8920 45669e00 balrog
8921 d63d307f bellard
    if (loadvm)
8922 faea38e7 bellard
        do_loadvm(loadvm);
8923 d63d307f bellard
8924 67b915a5 bellard
    {
8925 5905b2e5 bellard
        /* XXX: simplify init */
8926 5905b2e5 bellard
        read_passwords();
8927 3c07f8e8 pbrook
        if (autostart) {
8928 5905b2e5 bellard
            vm_start();
8929 5905b2e5 bellard
        }
8930 0824d6fc bellard
    }
8931 ffd843bc ths
8932 71e3ceb8 ths
    if (daemonize) {
8933 71e3ceb8 ths
        uint8_t status = 0;
8934 71e3ceb8 ths
        ssize_t len;
8935 71e3ceb8 ths
        int fd;
8936 71e3ceb8 ths
8937 71e3ceb8 ths
    again1:
8938 71e3ceb8 ths
        len = write(fds[1], &status, 1);
8939 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
8940 71e3ceb8 ths
            goto again1;
8941 71e3ceb8 ths
8942 71e3ceb8 ths
        if (len != 1)
8943 71e3ceb8 ths
            exit(1);
8944 71e3ceb8 ths
8945 aeb30be6 balrog
        TFR(fd = open("/dev/null", O_RDWR));
8946 71e3ceb8 ths
        if (fd == -1)
8947 71e3ceb8 ths
            exit(1);
8948 71e3ceb8 ths
8949 71e3ceb8 ths
        dup2(fd, 0);
8950 71e3ceb8 ths
        dup2(fd, 1);
8951 71e3ceb8 ths
        dup2(fd, 2);
8952 71e3ceb8 ths
8953 71e3ceb8 ths
        close(fd);
8954 71e3ceb8 ths
    }
8955 71e3ceb8 ths
8956 8a7ddc38 bellard
    main_loop();
8957 40c3bac3 bellard
    quit_timers();
8958 b46a8906 ths
8959 7d294b61 ths
#if !defined(_WIN32)
8960 b46a8906 ths
    /* close network clients */
8961 b46a8906 ths
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
8962 b46a8906 ths
        VLANClientState *vc;
8963 b46a8906 ths
8964 7d294b61 ths
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
8965 b46a8906 ths
            if (vc->fd_read == tap_receive) {
8966 b46a8906 ths
                char ifname[64];
8967 b46a8906 ths
                TAPState *s = vc->opaque;
8968 b46a8906 ths
8969 b46a8906 ths
                if (sscanf(vc->info_str, "tap: ifname=%63s ", ifname) == 1 &&
8970 b46a8906 ths
                    s->down_script[0])
8971 b46a8906 ths
                    launch_script(s->down_script, ifname, s->fd);
8972 b46a8906 ths
            }
8973 4fddf62a ths
        }
8974 7d294b61 ths
    }
8975 7d294b61 ths
#endif
8976 0824d6fc bellard
    return 0;
8977 0824d6fc bellard
}