Statistics
| Branch: | Revision:

root / vl.c @ 52f61fde

History | View | Annotate | Download (190.2 kB)

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

5588 c88676f8 bellard
            /* find if the memory block is available on a virtual
5589 c88676f8 bellard
               block device */
5590 c88676f8 bellard
            sector_num = -1;
5591 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5592 c88676f8 bellard
                if (bs_table[j]) {
5593 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5594 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5595 c88676f8 bellard
                    if (sector_num >= 0)
5596 c88676f8 bellard
                        break;
5597 c88676f8 bellard
                }
5598 c88676f8 bellard
            }
5599 c88676f8 bellard
            if (j == MAX_DISKS)
5600 c88676f8 bellard
                goto normal_compress;
5601 c88676f8 bellard
            buf[0] = 1;
5602 c88676f8 bellard
            buf[1] = j;
5603 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5604 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5605 c88676f8 bellard
        } else 
5606 c88676f8 bellard
#endif
5607 c88676f8 bellard
        {
5608 c88676f8 bellard
            //        normal_compress:
5609 c88676f8 bellard
            buf[0] = 0;
5610 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5611 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5612 c88676f8 bellard
        }
5613 8a7ddc38 bellard
    }
5614 c88676f8 bellard
    ram_compress_close(s);
5615 8a7ddc38 bellard
}
5616 8a7ddc38 bellard
5617 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5618 8a7ddc38 bellard
{
5619 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5620 c88676f8 bellard
    uint8_t buf[10];
5621 c88676f8 bellard
    int i;
5622 8a7ddc38 bellard
5623 c88676f8 bellard
    if (version_id == 1)
5624 c88676f8 bellard
        return ram_load_v1(f, opaque);
5625 c88676f8 bellard
    if (version_id != 2)
5626 8a7ddc38 bellard
        return -EINVAL;
5627 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5628 8a7ddc38 bellard
        return -EINVAL;
5629 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5630 c88676f8 bellard
        return -EINVAL;
5631 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5632 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5633 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5634 c88676f8 bellard
            goto error;
5635 c88676f8 bellard
        }
5636 c88676f8 bellard
        if (buf[0] == 0) {
5637 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5638 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5639 c88676f8 bellard
                goto error;
5640 c88676f8 bellard
            }
5641 c88676f8 bellard
        } else 
5642 c88676f8 bellard
#if 0
5643 c88676f8 bellard
        if (buf[0] == 1) {
5644 c88676f8 bellard
            int bs_index;
5645 c88676f8 bellard
            int64_t sector_num;
5646 c88676f8 bellard

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