/*
* QEMU System Emulator
*
- * Copyright (c) 2003-2006 Fabrice Bellard
+ * Copyright (c) 2003-2007 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
#include <malloc.h>
#include <linux/rtc.h>
#include <linux/ppdev.h>
+#include <linux/parport.h>
+#else
+#include <sys/stat.h>
+#include <sys/ethernet.h>
+#include <sys/sockio.h>
+#include <arpa/inet.h>
+#include <netinet/arp.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h> // must come after ip.h
+#include <netinet/udp.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
+#include <syslog.h>
+#include <stropts.h>
#endif
#endif
#endif
/* point to the block driver where the snapshots are managed */
BlockDriverState *bs_snapshots;
int vga_ram_size;
-int bios_size;
static DisplayState display_state;
int nographic;
const char* keyboard_layout = NULL;
int vm_running;
int rtc_utc = 1;
int cirrus_vga_enabled = 1;
+int vmsvga_enabled = 0;
#ifdef TARGET_SPARC
int graphic_width = 1024;
int graphic_height = 768;
#endif
int graphic_depth = 15;
int full_screen = 0;
+int no_frame = 0;
int no_quit = 0;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
int nb_option_roms;
int semihosting_enabled = 0;
int autostart = 1;
+const char *qemu_name;
/***********************************************************/
/* x86 ISA bus support */
uint32_t default_ioport_readb(void *opaque, uint32_t address)
{
#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inb: port=0x%04x\n", address);
+ fprintf(stderr, "unused inb: port=0x%04x\n", address);
#endif
return 0xff;
}
void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
{
#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
+ fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
#endif
}
uint32_t default_ioport_readl(void *opaque, uint32_t address)
{
#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inl: port=0x%04x\n", address);
+ fprintf(stderr, "unused inl: port=0x%04x\n", address);
#endif
return 0xffffffff;
}
void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
{
#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
+ fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
#endif
}
return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
}
+void (*kbd_mouse_set)(int x, int y, int on) = NULL;
+void (*kbd_cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
+ uint8_t *image, uint8_t *mask) = NULL;
+
void do_info_mice(void)
{
QEMUPutMouseEntry *cursor;
return chr;
}
+/* MUX driver for serial I/O splitting */
+static int term_timestamps;
+static int64_t term_timestamps_start;
+#define MAX_MUX 4
+typedef struct {
+ IOCanRWHandler *chr_can_read[MAX_MUX];
+ IOReadHandler *chr_read[MAX_MUX];
+ IOEventHandler *chr_event[MAX_MUX];
+ void *ext_opaque[MAX_MUX];
+ CharDriverState *drv;
+ int mux_cnt;
+ int term_got_escape;
+ int max_size;
+} MuxDriver;
+
+
+static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+ MuxDriver *d = chr->opaque;
+ int ret;
+ if (!term_timestamps) {
+ ret = d->drv->chr_write(d->drv, buf, len);
+ } else {
+ int i;
+
+ ret = 0;
+ for(i = 0; i < len; i++) {
+ ret += d->drv->chr_write(d->drv, buf+i, 1);
+ if (buf[i] == '\n') {
+ char buf1[64];
+ int64_t ti;
+ int secs;
+
+ ti = get_clock();
+ if (term_timestamps_start == -1)
+ term_timestamps_start = ti;
+ ti -= term_timestamps_start;
+ secs = ti / 1000000000;
+ snprintf(buf1, sizeof(buf1),
+ "[%02d:%02d:%02d.%03d] ",
+ secs / 3600,
+ (secs / 60) % 60,
+ secs % 60,
+ (int)((ti / 1000000) % 1000));
+ d->drv->chr_write(d->drv, buf1, strlen(buf1));
+ }
+ }
+ }
+ return ret;
+}
+
+static char *mux_help[] = {
+ "% h print this help\n\r",
+ "% x exit emulator\n\r",
+ "% s save disk data back to file (if -snapshot)\n\r",
+ "% t toggle console timestamps\n\r"
+ "% b send break (magic sysrq)\n\r",
+ "% c switch between console and monitor\n\r",
+ "% % sends %\n\r",
+ NULL
+};
+
+static int term_escape_char = 0x01; /* ctrl-a is used for escape */
+static void mux_print_help(CharDriverState *chr)
+{
+ int i, j;
+ char ebuf[15] = "Escape-Char";
+ char cbuf[50] = "\n\r";
+
+ if (term_escape_char > 0 && term_escape_char < 26) {
+ sprintf(cbuf,"\n\r");
+ sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
+ } else {
+ sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char);
+ }
+ chr->chr_write(chr, cbuf, strlen(cbuf));
+ for (i = 0; mux_help[i] != NULL; i++) {
+ for (j=0; mux_help[i][j] != '\0'; j++) {
+ if (mux_help[i][j] == '%')
+ chr->chr_write(chr, ebuf, strlen(ebuf));
+ else
+ chr->chr_write(chr, &mux_help[i][j], 1);
+ }
+ }
+}
+
+static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
+{
+ if (d->term_got_escape) {
+ d->term_got_escape = 0;
+ if (ch == term_escape_char)
+ goto send_char;
+ switch(ch) {
+ case '?':
+ case 'h':
+ mux_print_help(chr);
+ break;
+ case 'x':
+ {
+ char *term = "QEMU: Terminated\n\r";
+ chr->chr_write(chr,term,strlen(term));
+ exit(0);
+ break;
+ }
+ case 's':
+ {
+ int i;
+ for (i = 0; i < MAX_DISKS; i++) {
+ if (bs_table[i])
+ bdrv_commit(bs_table[i]);
+ }
+ }
+ break;
+ case 'b':
+ if (chr->chr_event)
+ chr->chr_event(chr->opaque, CHR_EVENT_BREAK);
+ break;
+ case 'c':
+ /* Switch to the next registered device */
+ chr->focus++;
+ if (chr->focus >= d->mux_cnt)
+ chr->focus = 0;
+ break;
+ case 't':
+ term_timestamps = !term_timestamps;
+ term_timestamps_start = -1;
+ break;
+ }
+ } else if (ch == term_escape_char) {
+ d->term_got_escape = 1;
+ } else {
+ send_char:
+ return 1;
+ }
+ return 0;
+}
+
+static int mux_chr_can_read(void *opaque)
+{
+ CharDriverState *chr = opaque;
+ MuxDriver *d = chr->opaque;
+ if (d->chr_can_read[chr->focus])
+ return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
+ return 0;
+}
+
+static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
+{
+ CharDriverState *chr = opaque;
+ MuxDriver *d = chr->opaque;
+ int i;
+ for(i = 0; i < size; i++)
+ if (mux_proc_byte(chr, d, buf[i]))
+ d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
+}
+
+static void mux_chr_event(void *opaque, int event)
+{
+ CharDriverState *chr = opaque;
+ MuxDriver *d = chr->opaque;
+ int i;
+
+ /* Send the event to all registered listeners */
+ for (i = 0; i < d->mux_cnt; i++)
+ if (d->chr_event[i])
+ d->chr_event[i](d->ext_opaque[i], event);
+}
+
+static void mux_chr_update_read_handler(CharDriverState *chr)
+{
+ MuxDriver *d = chr->opaque;
+
+ if (d->mux_cnt >= MAX_MUX) {
+ fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
+ return;
+ }
+ d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
+ d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
+ d->chr_read[d->mux_cnt] = chr->chr_read;
+ d->chr_event[d->mux_cnt] = chr->chr_event;
+ /* Fix up the real driver with mux routines */
+ if (d->mux_cnt == 0) {
+ qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
+ mux_chr_event, chr);
+ }
+ chr->focus = d->mux_cnt;
+ d->mux_cnt++;
+}
+
+CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
+{
+ CharDriverState *chr;
+ MuxDriver *d;
+
+ chr = qemu_mallocz(sizeof(CharDriverState));
+ if (!chr)
+ return NULL;
+ d = qemu_mallocz(sizeof(MuxDriver));
+ if (!d) {
+ free(chr);
+ return NULL;
+ }
+
+ chr->opaque = d;
+ d->drv = drv;
+ chr->focus = -1;
+ chr->chr_write = mux_chr_write;
+ chr->chr_update_read_handler = mux_chr_update_read_handler;
+ return chr;
+}
+
+
#ifdef _WIN32
static void socket_cleanup(void)
int max_size;
} FDCharDriver;
-#define STDIO_MAX_CLIENTS 2
-
-static int stdio_nb_clients;
-static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
+#define STDIO_MAX_CLIENTS 1
+static int stdio_nb_clients = 0;
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
/* for STDIO, we handle the case where several clients use it
(nographic mode) */
-#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
-
#define TERM_FIFO_MAX_SIZE 1
-static int term_got_escape, client_index;
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
static int term_fifo_size;
-static int term_timestamps;
-static int64_t term_timestamps_start;
-
-void term_print_help(void)
-{
- printf("\n"
- "C-a h print this help\n"
- "C-a x exit emulator\n"
- "C-a s save disk data back to file (if -snapshot)\n"
- "C-a b send break (magic sysrq)\n"
- "C-a t toggle console timestamps\n"
- "C-a c switch between console and monitor\n"
- "C-a C-a send C-a\n"
- );
-}
-
-/* called when a char is received */
-static void stdio_received_byte(int ch)
-{
- if (term_got_escape) {
- term_got_escape = 0;
- switch(ch) {
- case 'h':
- term_print_help();
- break;
- case 'x':
- exit(0);
- break;
- case 's':
- {
- int i;
- for (i = 0; i < MAX_DISKS; i++) {
- if (bs_table[i])
- bdrv_commit(bs_table[i]);
- }
- }
- break;
- case 'b':
- if (client_index < stdio_nb_clients) {
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = stdio_clients[client_index];
- s = chr->opaque;
- qemu_chr_event(chr, CHR_EVENT_BREAK);
- }
- break;
- case 'c':
- client_index++;
- if (client_index >= stdio_nb_clients)
- client_index = 0;
- if (client_index == 0) {
- /* send a new line in the monitor to get the prompt */
- ch = '\r';
- goto send_char;
- }
- break;
- case 't':
- term_timestamps = !term_timestamps;
- term_timestamps_start = -1;
- break;
- case TERM_ESCAPE:
- goto send_char;
- }
- } else if (ch == TERM_ESCAPE) {
- term_got_escape = 1;
- } else {
- send_char:
- if (client_index < stdio_nb_clients) {
- uint8_t buf[1];
- CharDriverState *chr;
-
- chr = stdio_clients[client_index];
- if (qemu_chr_can_read(chr) > 0) {
- buf[0] = ch;
- qemu_chr_read(chr, buf, 1);
- } else if (term_fifo_size == 0) {
- term_fifo[term_fifo_size++] = ch;
- }
- }
- }
-}
static int stdio_read_poll(void *opaque)
{
- CharDriverState *chr;
+ CharDriverState *chr = opaque;
- if (client_index < stdio_nb_clients) {
- chr = stdio_clients[client_index];
- /* try to flush the queue if needed */
- if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
- qemu_chr_read(chr, term_fifo, 1);
- term_fifo_size = 0;
- }
- /* see if we can absorb more chars */
- if (term_fifo_size == 0)
- return 1;
- else
- return 0;
- } else {
- return 1;
+ /* try to flush the queue if needed */
+ if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
+ qemu_chr_read(chr, term_fifo, 1);
+ term_fifo_size = 0;
}
+ /* see if we can absorb more chars */
+ if (term_fifo_size == 0)
+ return 1;
+ else
+ return 0;
}
static void stdio_read(void *opaque)
{
int size;
uint8_t buf[1];
-
+ CharDriverState *chr = opaque;
+
size = read(0, buf, 1);
if (size == 0) {
/* stdin has been closed. Remove it from the active list. */
qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
return;
}
- if (size > 0)
- stdio_received_byte(buf[0]);
-}
-
-static int stdio_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- FDCharDriver *s = chr->opaque;
- if (!term_timestamps) {
- return unix_write(s->fd_out, buf, len);
- } else {
- int i;
- char buf1[64];
-
- for(i = 0; i < len; i++) {
- unix_write(s->fd_out, buf + i, 1);
- if (buf[i] == '\n') {
- int64_t ti;
- int secs;
-
- ti = get_clock();
- if (term_timestamps_start == -1)
- term_timestamps_start = ti;
- ti -= term_timestamps_start;
- secs = ti / 1000000000;
- snprintf(buf1, sizeof(buf1),
- "[%02d:%02d:%02d.%03d] ",
- secs / 3600,
- (secs / 60) % 60,
- secs % 60,
- (int)((ti / 1000000) % 1000));
- unix_write(s->fd_out, buf1, strlen(buf1));
- }
+ if (size > 0) {
+ if (qemu_chr_can_read(chr) > 0) {
+ qemu_chr_read(chr, buf, 1);
+ } else if (term_fifo_size == 0) {
+ term_fifo[term_fifo_size++] = buf[0];
}
- return len;
}
}
{
CharDriverState *chr;
- if (nographic) {
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- chr->chr_write = stdio_write;
- if (stdio_nb_clients == 0)
- qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, NULL);
- client_index = stdio_nb_clients;
- } else {
- if (stdio_nb_clients != 0)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- }
- stdio_clients[stdio_nb_clients++] = chr;
- if (stdio_nb_clients == 1) {
- /* set the terminal in raw mode */
- term_init();
- }
+ if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
+ return NULL;
+ chr = qemu_chr_open_fd(0, 1);
+ qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
+ stdio_nb_clients++;
+ term_init();
+
return chr;
}
return chr;
}
+typedef struct {
+ int fd;
+ int mode;
+} ParallelCharDriver;
+
+static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
+{
+ if (s->mode != mode) {
+ int m = mode;
+ if (ioctl(s->fd, PPSETMODE, &m) < 0)
+ return 0;
+ s->mode = mode;
+ }
+ return 1;
+}
+
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
{
- int fd = (int)chr->opaque;
+ ParallelCharDriver *drv = chr->opaque;
+ int fd = drv->fd;
uint8_t b;
switch(cmd) {
case CHR_IOCTL_PP_READ_CONTROL:
if (ioctl(fd, PPRCONTROL, &b) < 0)
return -ENOTSUP;
- *(uint8_t *)arg = b;
+ /* Linux gives only the lowest bits, and no way to know data
+ direction! For better compatibility set the fixed upper
+ bits. */
+ *(uint8_t *)arg = b | 0xc0;
break;
case CHR_IOCTL_PP_WRITE_CONTROL:
b = *(uint8_t *)arg;
return -ENOTSUP;
*(uint8_t *)arg = b;
break;
+ case CHR_IOCTL_PP_EPP_READ_ADDR:
+ if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
+ struct ParallelIOArg *parg = arg;
+ int n = read(fd, parg->buffer, parg->count);
+ if (n != parg->count) {
+ return -EIO;
+ }
+ }
+ break;
+ case CHR_IOCTL_PP_EPP_READ:
+ if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
+ struct ParallelIOArg *parg = arg;
+ int n = read(fd, parg->buffer, parg->count);
+ if (n != parg->count) {
+ return -EIO;
+ }
+ }
+ break;
+ case CHR_IOCTL_PP_EPP_WRITE_ADDR:
+ if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
+ struct ParallelIOArg *parg = arg;
+ int n = write(fd, parg->buffer, parg->count);
+ if (n != parg->count) {
+ return -EIO;
+ }
+ }
+ break;
+ case CHR_IOCTL_PP_EPP_WRITE:
+ if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
+ struct ParallelIOArg *parg = arg;
+ int n = write(fd, parg->buffer, parg->count);
+ if (n != parg->count) {
+ return -EIO;
+ }
+ }
+ break;
default:
return -ENOTSUP;
}
return 0;
}
+static void pp_close(CharDriverState *chr)
+{
+ ParallelCharDriver *drv = chr->opaque;
+ int fd = drv->fd;
+
+ pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
+ ioctl(fd, PPRELEASE);
+ close(fd);
+ qemu_free(drv);
+}
+
static CharDriverState *qemu_chr_open_pp(const char *filename)
{
CharDriverState *chr;
+ ParallelCharDriver *drv;
int fd;
fd = open(filename, O_RDWR);
return NULL;
}
+ drv = qemu_mallocz(sizeof(ParallelCharDriver));
+ if (!drv) {
+ close(fd);
+ return NULL;
+ }
+ drv->fd = fd;
+ drv->mode = IEEE1284_MODE_COMPAT;
+
chr = qemu_mallocz(sizeof(CharDriverState));
if (!chr) {
+ qemu_free(drv);
close(fd);
return NULL;
}
- chr->opaque = (void *)fd;
chr->chr_write = null_chr_write;
chr->chr_ioctl = pp_ioctl;
+ chr->chr_close = pp_close;
+ chr->opaque = drv;
qemu_chr_reset(chr);
static int win_chr_poll(void *opaque);
static int win_chr_pipe_poll(void *opaque);
-static void win_chr_close2(WinCharState *s)
+static void win_chr_close(CharDriverState *chr)
{
+ WinCharState *s = chr->opaque;
+
if (s->hsend) {
CloseHandle(s->hsend);
s->hsend = NULL;
s->hcom = NULL;
}
if (s->fpipe)
- qemu_del_polling_cb(win_chr_pipe_poll, s);
+ qemu_del_polling_cb(win_chr_pipe_poll, chr);
else
- qemu_del_polling_cb(win_chr_poll, s);
+ qemu_del_polling_cb(win_chr_poll, chr);
}
-static void win_chr_close(CharDriverState *chr)
+static int win_chr_init(CharDriverState *chr, const char *filename)
{
WinCharState *s = chr->opaque;
- win_chr_close2(s);
-}
-
-static int win_chr_init(WinCharState *s, const char *filename)
-{
COMMCONFIG comcfg;
COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
COMSTAT comstat;
fprintf(stderr, "Failed ClearCommError\n");
goto fail;
}
- qemu_add_polling_cb(win_chr_poll, s);
+ qemu_add_polling_cb(win_chr_poll, chr);
return 0;
fail:
- win_chr_close2(s);
+ win_chr_close(chr);
return -1;
}
return len1 - len;
}
-static int win_chr_read_poll(WinCharState *s)
+static int win_chr_read_poll(CharDriverState *chr)
{
- s->max_size = qemu_chr_can_read(s->chr);
+ WinCharState *s = chr->opaque;
+
+ s->max_size = qemu_chr_can_read(chr);
return s->max_size;
}
-static void win_chr_readfile(WinCharState *s)
+static void win_chr_readfile(CharDriverState *chr)
{
+ WinCharState *s = chr->opaque;
int ret, err;
uint8_t buf[1024];
DWORD size;
}
if (size > 0) {
- qemu_chr_read(s->chr, buf, size);
+ qemu_chr_read(chr, buf, size);
}
}
-static void win_chr_read(WinCharState *s)
+static void win_chr_read(CharDriverState *chr)
{
+ WinCharState *s = chr->opaque;
+
if (s->len > s->max_size)
s->len = s->max_size;
if (s->len == 0)
return;
- win_chr_readfile(s);
+ win_chr_readfile(chr);
}
static int win_chr_poll(void *opaque)
{
- WinCharState *s = opaque;
+ CharDriverState *chr = opaque;
+ WinCharState *s = chr->opaque;
COMSTAT status;
DWORD comerr;
ClearCommError(s->hcom, &comerr, &status);
if (status.cbInQue > 0) {
s->len = status.cbInQue;
- win_chr_read_poll(s);
- win_chr_read(s);
+ win_chr_read_poll(chr);
+ win_chr_read(chr);
return 1;
}
return 0;
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
- if (win_chr_init(s, filename) < 0) {
+ if (win_chr_init(chr, filename) < 0) {
free(s);
free(chr);
return NULL;
static int win_chr_pipe_poll(void *opaque)
{
- WinCharState *s = opaque;
+ CharDriverState *chr = opaque;
+ WinCharState *s = chr->opaque;
DWORD size;
PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
if (size > 0) {
s->len = size;
- win_chr_read_poll(s);
- win_chr_read(s);
+ win_chr_read_poll(chr);
+ win_chr_read(chr);
return 1;
}
return 0;
}
-static int win_chr_pipe_init(WinCharState *s, const char *filename)
+static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
{
+ WinCharState *s = chr->opaque;
OVERLAPPED ov;
int ret;
DWORD size;
CloseHandle(ov.hEvent);
ov.hEvent = NULL;
}
- qemu_add_polling_cb(win_chr_pipe_poll, s);
+ qemu_add_polling_cb(win_chr_pipe_poll, chr);
return 0;
fail:
- win_chr_close2(s);
+ win_chr_close(chr);
return -1;
}
chr->chr_write = win_chr_write;
chr->chr_close = win_chr_close;
- if (win_chr_pipe_init(s, filename) < 0) {
+ if (win_chr_pipe_init(chr, filename) < 0) {
free(s);
free(chr);
return NULL;
if (err == EINTR || err == EWOULDBLOCK) {
} else if (err == EINPROGRESS) {
break;
+#ifdef _WIN32
+ } else if (err == WSAEALREADY) {
+ break;
+#endif
} else {
goto fail;
}
if (strstart(filename, "udp:", &p)) {
return qemu_chr_open_udp(p);
} else
+ if (strstart(filename, "mon:", &p)) {
+ CharDriverState *drv = qemu_chr_open(p);
+ if (drv) {
+ drv = qemu_chr_open_mux(drv);
+ monitor_init(drv, !nographic);
+ return drv;
+ }
+ printf("Unable to open driver: %s\n", p);
+ return 0;
+ } else
#ifndef _WIN32
if (strstart(filename, "unix:", &p)) {
return qemu_chr_open_tcp(p, 0, 1);
uint8_t buf[4096];
int size;
+#ifdef __sun__
+ struct strbuf sbuf;
+ int f = 0;
+ sbuf.maxlen = sizeof(buf);
+ sbuf.buf = buf;
+ size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
+#else
size = read(s->fd, buf, sizeof(buf));
+#endif
if (size > 0) {
qemu_send_packet(s->vc, buf, size);
}
return fd;
}
#elif defined(__sun__)
+#define TUNNEWPPA (('T'<<16) | 0x0001)
+/*
+ * Allocate TAP device, returns opened fd.
+ * Stores dev name in the first arg(must be large enough).
+ */
+int tap_alloc(char *dev)
+{
+ int tap_fd, if_fd, ppa = -1;
+ static int ip_fd = 0;
+ char *ptr;
+
+ static int arp_fd = 0;
+ int ip_muxid, arp_muxid;
+ struct strioctl strioc_if, strioc_ppa;
+ int link_type = I_PLINK;;
+ struct lifreq ifr;
+ char actual_name[32] = "";
+
+ memset(&ifr, 0x0, sizeof(ifr));
+
+ if( *dev ){
+ ptr = dev;
+ while( *ptr && !isdigit((int)*ptr) ) ptr++;
+ ppa = atoi(ptr);
+ }
+
+ /* Check if IP device was opened */
+ if( ip_fd )
+ close(ip_fd);
+
+ if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
+ syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
+ return -1;
+ }
+
+ if( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+ syslog(LOG_ERR, "Can't open /dev/tap");
+ return -1;
+ }
+
+ /* Assign a new PPA and get its unit number. */
+ strioc_ppa.ic_cmd = TUNNEWPPA;
+ strioc_ppa.ic_timout = 0;
+ strioc_ppa.ic_len = sizeof(ppa);
+ strioc_ppa.ic_dp = (char *)&ppa;
+ if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
+ syslog (LOG_ERR, "Can't assign new interface");
+
+ if( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0){
+ syslog(LOG_ERR, "Can't open /dev/tap (2)");
+ return -1;
+ }
+ if(ioctl(if_fd, I_PUSH, "ip") < 0){
+ syslog(LOG_ERR, "Can't push IP module");
+ return -1;
+ }
+
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
+ syslog(LOG_ERR, "Can't get flags\n");
+
+ snprintf (actual_name, 32, "tap%d", ppa);
+ strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
+
+ ifr.lifr_ppa = ppa;
+ /* Assign ppa according to the unit number returned by tun device */
+
+ if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
+ syslog (LOG_ERR, "Can't set PPA %d", ppa);
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
+ syslog (LOG_ERR, "Can't get flags\n");
+ /* Push arp module to if_fd */
+ if (ioctl (if_fd, I_PUSH, "arp") < 0)
+ syslog (LOG_ERR, "Can't push ARP module (2)");
+
+ /* Push arp module to ip_fd */
+ if (ioctl (ip_fd, I_POP, NULL) < 0)
+ syslog (LOG_ERR, "I_POP failed\n");
+ if (ioctl (ip_fd, I_PUSH, "arp") < 0)
+ syslog (LOG_ERR, "Can't push ARP module (3)\n");
+ /* Open arp_fd */
+ if ((arp_fd = open ("/dev/tap", O_RDWR, 0)) < 0)
+ syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
+
+ /* Set ifname to arp */
+ strioc_if.ic_cmd = SIOCSLIFNAME;
+ strioc_if.ic_timout = 0;
+ strioc_if.ic_len = sizeof(ifr);
+ strioc_if.ic_dp = (char *)𝔦
+ if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
+ syslog (LOG_ERR, "Can't set ifname to arp\n");
+ }
+
+ if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
+ syslog(LOG_ERR, "Can't link TAP device to IP");
+ return -1;
+ }
+
+ if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
+ syslog (LOG_ERR, "Can't link TAP device to ARP");
+
+ close (if_fd);
+
+ memset(&ifr, 0x0, sizeof(ifr));
+ strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
+ ifr.lifr_ip_muxid = ip_muxid;
+ ifr.lifr_arp_muxid = arp_muxid;
+
+ if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
+ {
+ ioctl (ip_fd, I_PUNLINK , arp_muxid);
+ ioctl (ip_fd, I_PUNLINK, ip_muxid);
+ syslog (LOG_ERR, "Can't set multiplexor id");
+ }
+
+ sprintf(dev, "tap%d", ppa);
+ return tap_fd;
+}
+
static int tap_open(char *ifname, int ifname_size)
{
- fprintf(stderr, "warning: tap_open not yet implemented\n");
- return -1;
+ char dev[10]="";
+ int fd;
+ if( (fd = tap_alloc(dev)) < 0 ){
+ fprintf(stderr, "Cannot allocate TAP device\n");
+ return -1;
+ }
+ pstrcpy(ifname, ifname_size, dev);
+ fcntl(fd, F_SETFL, O_NONBLOCK);
+ return fd;
}
#else
static int tap_open(char *ifname, int ifname_size)
if (fd < 0)
return -1;
- if (!setup_script)
+ if (!setup_script || !strcmp(setup_script, "no"))
setup_script = "";
if (setup_script[0] != '\0') {
/* try to launch network init script */
pid = fork();
if (pid >= 0) {
if (pid == 0) {
+ int open_max = sysconf (_SC_OPEN_MAX), i;
+ for (i = 0; i < open_max; i++)
+ if (i != STDIN_FILENO &&
+ i != STDOUT_FILENO &&
+ i != STDERR_FILENO &&
+ i != fd)
+ close(i);
+
parg = args;
*parg++ = (char *)setup_script;
*parg++ = ifname;
if (err == EINTR || err == EWOULDBLOCK) {
} else if (err == EINPROGRESS) {
break;
+#ifdef _WIN32
+ } else if (err == WSAEALREADY) {
+ break;
+#endif
} else {
perror("connect");
closesocket(fd);
}
}
-/***********************************************************/
-/* pid file */
-
-static char *pid_filename;
-
-/* Remove PID file. Called on normal exit */
-
-static void remove_pidfile(void)
-{
- unlink (pid_filename);
-}
-
-static void create_pidfile(const char *filename)
-{
- struct stat pidstat;
- FILE *f;
-
- /* Try to write our PID to the named file */
- if (stat(filename, &pidstat) < 0) {
- if (errno == ENOENT) {
- if ((f = fopen (filename, "w")) == NULL) {
- perror("Opening pidfile");
- exit(1);
- }
- fprintf(f, "%d\n", getpid());
- fclose(f);
- pid_filename = qemu_strdup(filename);
- if (!pid_filename) {
- fprintf(stderr, "Could not save PID filename");
- exit(1);
- }
- atexit(remove_pidfile);
- }
- } else {
- fprintf(stderr, "%s already exists. Remove it and try again.\n",
- filename);
- exit(1);
- }
-}
-
/***********************************************************/
/* dumb display */
IOCanRWHandler *fd_read_poll;
IOHandler *fd_read;
IOHandler *fd_write;
+ int deleted;
void *opaque;
/* temporary data */
struct pollfd *ufd;
if (ioh == NULL)
break;
if (ioh->fd == fd) {
- *pioh = ioh->next;
- qemu_free(ioh);
+ ioh->deleted = 1;
break;
}
pioh = &ioh->next;
ioh->fd_read = fd_read;
ioh->fd_write = fd_write;
ioh->opaque = opaque;
+ ioh->deleted = 0;
}
return 0;
}
void main_loop_wait(int timeout)
{
- IOHandlerRecord *ioh, *ioh_next;
+ IOHandlerRecord *ioh;
fd_set rfds, wfds, xfds;
int ret, nfds;
struct timeval tv;
FD_ZERO(&wfds);
FD_ZERO(&xfds);
for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+ if (ioh->deleted)
+ continue;
if (ioh->fd_read &&
(!ioh->fd_read_poll ||
ioh->fd_read_poll(ioh->opaque) != 0)) {
#endif
ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
if (ret > 0) {
- /* XXX: better handling of removal */
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
- ioh_next = ioh->next;
+ IOHandlerRecord **pioh;
+
+ for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+ if (ioh->deleted)
+ continue;
if (FD_ISSET(ioh->fd, &rfds)) {
ioh->fd_read(ioh->opaque);
}
ioh->fd_write(ioh->opaque);
}
}
+
+ /* remove deleted IO handlers */
+ pioh = &first_io_handler;
+ while (*pioh) {
+ ioh = *pioh;
+ if (ioh->deleted) {
+ *pioh = ioh->next;
+ qemu_free(ioh);
+ } else
+ pioh = &ioh->next;
+ }
}
#if defined(CONFIG_SLIRP)
if (slirp_inited) {
#ifdef CONFIG_PROFILER
qemu_time += profile_getclock() - ti;
#endif
+ if (ret == EXCP_HLT) {
+ /* Give the next CPU a chance to run. */
+ cur_cpu = env;
+ continue;
+ }
if (ret != EXCP_HALTED)
break;
/* all CPUs are halted ? */
- if (env == cur_cpu) {
- ret = EXCP_HLT;
+ if (env == cur_cpu)
break;
- }
}
cur_cpu = env;
if (ret == EXCP_DEBUG) {
vm_stop(EXCP_DEBUG);
}
- /* if hlt instruction, we wait until the next IRQ */
+ /* If all cpus are halted then wait until the next IRQ */
/* XXX: use timeout computed from timers */
- if (ret == EXCP_HLT)
+ if (ret == EXCP_HALTED)
timeout = 10;
else
timeout = 0;
void help(void)
{
- printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2006 Fabrice Bellard\n"
+ printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
"usage: %s [options] [disk_image]\n"
"\n"
"'disk_image' is a raw hard image image for IDE hard disk 0\n"
"\n"
"Standard options:\n"
"-M machine select emulated machine (-M ? for list)\n"
+ "-cpu cpu select CPU (-cpu ? for list)\n"
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
"-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
"-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
"-snapshot write to temporary files instead of disk image files\n"
#ifdef CONFIG_SDL
+ "-no-frame open SDL window without a frame and window decorations\n"
"-no-quit disable SDL window close capability\n"
#endif
#ifdef TARGET_I386
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
"-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
#endif
+ "-name string set the name of the guest\n"
"\n"
"Network options:\n"
"-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
"-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
" connect the host TAP network interface to VLAN 'n' and use\n"
" the network script 'file' (default=%s);\n"
+ " use 'script=no' to disable script execution;\n"
" use 'fd=h' to connect to an already opened TAP interface\n"
#endif
"-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" is provided, the default is '-net nic -net user'\n"
"\n"
#ifdef CONFIG_SLIRP
- "-tftp prefix allow tftp access to files starting with prefix [-net user]\n"
+ "-tftp dir allow tftp access to files in dir [-net user]\n"
+ "-bootp file advertise file in BOOTP replies\n"
#ifndef _WIN32
"-smb dir allow SMB access to files in 'dir' [-net user]\n"
#endif
"-parallel dev redirect the parallel port to char device 'dev'\n"
"-pidfile file Write PID to 'file'\n"
"-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port %d\n"
- "-p port change gdb connection port\n"
+ "-s wait gdb connection to port\n"
+ "-p port set gdb connection port [default=%s]\n"
"-d item1,... output log to %s (use -d ? for a list of log items)\n"
"-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
" translation (t=none or lba) (usually qemu can guess them)\n"
QEMU_OPTION_h,
QEMU_OPTION_M,
+ QEMU_OPTION_cpu,
QEMU_OPTION_fda,
QEMU_OPTION_fdb,
QEMU_OPTION_hda,
QEMU_OPTION_net,
QEMU_OPTION_tftp,
+ QEMU_OPTION_bootp,
QEMU_OPTION_smb,
QEMU_OPTION_redir,
QEMU_OPTION_k,
QEMU_OPTION_localtime,
QEMU_OPTION_cirrusvga,
+ QEMU_OPTION_vmsvga,
QEMU_OPTION_g,
QEMU_OPTION_std_vga,
+ QEMU_OPTION_echr,
QEMU_OPTION_monitor,
QEMU_OPTION_serial,
QEMU_OPTION_parallel,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
+ QEMU_OPTION_no_frame,
QEMU_OPTION_no_quit,
QEMU_OPTION_pidfile,
QEMU_OPTION_no_kqemu,
QEMU_OPTION_no_reboot,
QEMU_OPTION_daemonize,
QEMU_OPTION_option_rom,
- QEMU_OPTION_semihosting
+ QEMU_OPTION_semihosting,
+ QEMU_OPTION_name,
};
typedef struct QEMUOption {
{ "help", 0, QEMU_OPTION_h },
{ "M", HAS_ARG, QEMU_OPTION_M },
+ { "cpu", HAS_ARG, QEMU_OPTION_cpu },
{ "fda", HAS_ARG, QEMU_OPTION_fda },
{ "fdb", HAS_ARG, QEMU_OPTION_fdb },
{ "hda", HAS_ARG, QEMU_OPTION_hda },
{ "net", HAS_ARG, QEMU_OPTION_net},
#ifdef CONFIG_SLIRP
{ "tftp", HAS_ARG, QEMU_OPTION_tftp },
+ { "bootp", HAS_ARG, QEMU_OPTION_bootp },
#ifndef _WIN32
{ "smb", HAS_ARG, QEMU_OPTION_smb },
#endif
#endif
{ "localtime", 0, QEMU_OPTION_localtime },
{ "std-vga", 0, QEMU_OPTION_std_vga },
+ { "echr", 1, QEMU_OPTION_echr },
{ "monitor", 1, QEMU_OPTION_monitor },
{ "serial", 1, QEMU_OPTION_serial },
{ "parallel", 1, QEMU_OPTION_parallel },
{ "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
{ "full-screen", 0, QEMU_OPTION_full_screen },
#ifdef CONFIG_SDL
+ { "no-frame", 0, QEMU_OPTION_no_frame },
{ "no-quit", 0, QEMU_OPTION_no_quit },
#endif
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
/* temporary options */
{ "usb", 0, QEMU_OPTION_usb },
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
+ { "vmwarevga", 0, QEMU_OPTION_vmsvga },
{ "no-acpi", 0, QEMU_OPTION_no_acpi },
{ "no-reboot", 0, QEMU_OPTION_no_reboot },
{ "daemonize", 0, QEMU_OPTION_daemonize },
#if defined(TARGET_ARM)
{ "semihosting", 0, QEMU_OPTION_semihosting },
#endif
+ { "name", HAS_ARG, QEMU_OPTION_name },
{ NULL },
};
#ifdef TARGET_SPARC64
qemu_register_machine(&sun4u_machine);
#else
- qemu_register_machine(&sun4m_machine);
+ qemu_register_machine(&ss5_machine);
+ qemu_register_machine(&ss10_machine);
#endif
#elif defined(TARGET_ARM)
- qemu_register_machine(&integratorcp926_machine);
- qemu_register_machine(&integratorcp1026_machine);
+ qemu_register_machine(&integratorcp_machine);
qemu_register_machine(&versatilepb_machine);
qemu_register_machine(&versatileab_machine);
qemu_register_machine(&realview_machine);
#elif defined(TARGET_SH4)
qemu_register_machine(&shix_machine);
+#elif defined(TARGET_ALPHA)
+ /* XXX: TODO */
#else
#error unsupported CPU
#endif
int main(int argc, char **argv)
{
#ifdef CONFIG_GDBSTUB
- int use_gdbstub, gdbstub_port;
+ int use_gdbstub;
+ const char *gdbstub_port;
#endif
int i, cdrom_index;
int snapshot, linux_boot;
int parallel_device_index;
const char *loadvm = NULL;
QEMUMachine *machine;
+ const char *cpu_model;
char usb_devices[MAX_USB_CMDLINE][128];
int usb_devices_index;
int fds[2];
+ const char *pid_file = NULL;
LIST_INIT (&vm_change_state_head);
#ifndef _WIN32
register_machines();
machine = first_machine;
+ cpu_model = NULL;
initrd_filename = NULL;
for(i = 0; i < MAX_FD; i++)
fd_filename[i] = NULL;
hd_filename[i] = NULL;
ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
vga_ram_size = VGA_RAM_SIZE;
- bios_size = BIOS_SIZE;
#ifdef CONFIG_GDBSTUB
use_gdbstub = 0;
gdbstub_port = DEFAULT_GDBSTUB_PORT;
exit(1);
}
break;
+ case QEMU_OPTION_cpu:
+ /* hw initialization will check this */
+ if (optarg[0] == '?') {
+#if defined(TARGET_PPC)
+ ppc_cpu_list(stdout, &fprintf);
+#elif defined(TARGET_ARM)
+ arm_cpu_list();
+#elif defined(TARGET_MIPS)
+ mips_cpu_list(stdout, &fprintf);
+#elif defined(TARGET_SPARC)
+ sparc_cpu_list(stdout, &fprintf);
+#endif
+ exit(1);
+ } else {
+ cpu_model = optarg;
+ }
+ break;
case QEMU_OPTION_initrd:
initrd_filename = optarg;
break;
}
break;
case QEMU_OPTION_nographic:
- pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
+ pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
+ pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
nographic = 1;
break;
case QEMU_OPTION_kernel:
case QEMU_OPTION_tftp:
tftp_prefix = optarg;
break;
+ case QEMU_OPTION_bootp:
+ bootp_filename = optarg;
+ break;
#ifndef _WIN32
case QEMU_OPTION_smb:
net_slirp_smb(optarg);
use_gdbstub = 1;
break;
case QEMU_OPTION_p:
- gdbstub_port = atoi(optarg);
+ gdbstub_port = optarg;
break;
#endif
case QEMU_OPTION_L:
break;
case QEMU_OPTION_cirrusvga:
cirrus_vga_enabled = 1;
+ vmsvga_enabled = 0;
+ break;
+ case QEMU_OPTION_vmsvga:
+ cirrus_vga_enabled = 0;
+ vmsvga_enabled = 1;
break;
case QEMU_OPTION_std_vga:
cirrus_vga_enabled = 0;
+ vmsvga_enabled = 0;
break;
case QEMU_OPTION_g:
{
graphic_depth = depth;
}
break;
+ case QEMU_OPTION_echr:
+ {
+ char *r;
+ term_escape_char = strtol(optarg, &r, 0);
+ if (r == optarg)
+ printf("Bad argument to echr\n");
+ break;
+ }
case QEMU_OPTION_monitor:
pstrcpy(monitor_device, sizeof(monitor_device), optarg);
break;
full_screen = 1;
break;
#ifdef CONFIG_SDL
+ case QEMU_OPTION_no_frame:
+ no_frame = 1;
+ break;
case QEMU_OPTION_no_quit:
no_quit = 1;
break;
#endif
case QEMU_OPTION_pidfile:
- create_pidfile(optarg);
+ pid_file = optarg;
break;
#ifdef TARGET_I386
case QEMU_OPTION_win2k_hack:
case QEMU_OPTION_semihosting:
semihosting_enabled = 1;
break;
+ case QEMU_OPTION_name:
+ qemu_name = optarg;
+ break;
}
}
}
close(fds[1]);
again:
- len = read(fds[0], &status, 1);
- if (len == -1 && (errno == EINTR))
- goto again;
-
- if (len != 1 || status != 0)
- exit(1);
- else
- exit(0);
+ len = read(fds[0], &status, 1);
+ if (len == -1 && (errno == EINTR))
+ goto again;
+
+ if (len != 1)
+ exit(1);
+ else if (status == 1) {
+ fprintf(stderr, "Could not acquire pidfile\n");
+ exit(1);
+ } else
+ exit(0);
} else if (pid < 0)
- exit(1);
+ exit(1);
setsid();
}
#endif
+ if (pid_file && qemu_create_pidfile(pid_file) != 0) {
+ if (daemonize) {
+ uint8_t status = 1;
+ write(fds[1], &status, 1);
+ } else
+ fprintf(stderr, "Could not acquire pid file\n");
+ exit(1);
+ }
+
#ifdef USE_KQEMU
if (smp_cpus > 1)
kqemu_allowed = 0;
linux_boot = (kernel_filename != NULL);
if (!linux_boot &&
+ boot_device != 'n' &&
hd_filename[0] == '\0' &&
(cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
fd_filename[0] == '\0')
#endif
/* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
- for (i = 0; i < nb_option_roms; i++) {
- int ret = get_image_size(option_rom[i]);
- if (ret == -1) {
- fprintf(stderr, "Could not load option rom '%s'\n", option_rom[i]);
- exit(1);
- }
- phys_ram_size += ret;
- }
+ phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
phys_ram_base = qemu_vmalloc(phys_ram_size);
if (!phys_ram_base) {
vnc_display_init(ds, vnc_display);
} else {
#if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen);
+ sdl_display_init(ds, full_screen, no_frame);
#elif defined(CONFIG_COCOA)
cocoa_display_init(ds, full_screen);
#else
#endif
}
- monitor_hd = qemu_chr_open(monitor_device);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
+ /* Maintain compatibility with multiple stdio monitors */
+ if (!strcmp(monitor_device,"stdio")) {
+ for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+ if (!strcmp(serial_devices[i],"mon:stdio")) {
+ monitor_device[0] = '\0';
+ break;
+ } else if (!strcmp(serial_devices[i],"stdio")) {
+ monitor_device[0] = '\0';
+ pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
+ break;
+ }
+ }
+ }
+ if (monitor_device[0] != '\0') {
+ monitor_hd = qemu_chr_open(monitor_device);
+ if (!monitor_hd) {
+ fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
+ exit(1);
+ }
+ monitor_init(monitor_hd, !nographic);
}
- monitor_init(monitor_hd, !nographic);
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
machine->init(ram_size, vga_ram_size, boot_device,
ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
+ kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
/* init USB devices */
if (usb_enabled) {
#ifdef CONFIG_GDBSTUB
if (use_gdbstub) {
+ /* XXX: use standard host:port notation and modify options
+ accordingly. */
if (gdbserver_start(gdbstub_port) < 0) {
- fprintf(stderr, "Could not open gdbserver socket on port %d\n",
+ fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
gdbstub_port);
exit(1);
- } else {
- printf("Waiting gdb connection on port %d\n", gdbstub_port);
}
} else
#endif