aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-07-14 17:28:13 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-07-14 17:28:13 +0000
commit82c643ff50dfdd82b89e9c5361fd132c79e0872c (patch)
tree9b22a47e17a69e6fc024d7fe047dc05498a53b3c
parent457831f4bcf20d1fd5d80d7a0b946bdaf6f56059 (diff)
char device support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1023 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--hw/pc.c5
-rw-r--r--hw/ppc_chrp.c5
-rw-r--r--hw/ppc_prep.c5
-rw-r--r--hw/serial.c41
-rw-r--r--vl.c347
-rw-r--r--vl.h81
6 files changed, 408 insertions, 76 deletions
diff --git a/hw/pc.c b/hw/pc.c
index 11b2827921..0fd7b87b26 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -324,7 +324,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
const char *initrd_filename)
{
char buf[1024];
- int ret, linux_boot, initrd_size, i, nb_nics1, fd;
+ int ret, linux_boot, initrd_size, i, nb_nics1;
unsigned long bios_offset, vga_bios_offset;
int bios_size, isa_bios_size;
PCIBus *pci_bus;
@@ -471,8 +471,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
pit = pit_init(0x40, 0);
- fd = serial_open_device();
- serial_init(0x3f8, 4, fd);
+ serial_init(0x3f8, 4, serial_hd);
if (pci_enabled) {
for(i = 0; i < nb_nics; i++) {
diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c
index 93835322fb..f532fe1019 100644
--- a/hw/ppc_chrp.c
+++ b/hw/ppc_chrp.c
@@ -126,7 +126,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
openpic_t *openpic;
m48t59_t *nvram;
int PPC_io_memory;
- int ret, linux_boot, i, fd;
+ int ret, linux_boot, i;
unsigned long bios_offset;
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
PCIBus *pci_bus;
@@ -200,8 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
/* XXX: use Mac Serial port */
- fd = serial_open_device();
- serial_init(0x3f8, 4, fd);
+ serial_init(0x3f8, 4, serial_hd);
for(i = 0; i < nb_nics; i++) {
pci_ne2000_init(pci_bus, &nd_table[i]);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 88dcac838d..eeb5a36095 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -415,7 +415,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
char buf[1024];
m48t59_t *nvram;
int PPC_io_memory;
- int ret, linux_boot, i, nb_nics1, fd;
+ int ret, linux_boot, i, nb_nics1;
unsigned long bios_offset;
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
PCIBus *pci_bus;
@@ -492,8 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
// pit = pit_init(0x40, 0);
- fd = serial_open_device();
- serial_init(0x3f8, 4, fd);
+ serial_init(0x3f8, 4, serial_hd);
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
nb_nics1 = NE2000_NB_MAX;
diff --git a/hw/serial.c b/hw/serial.c
index 3cf43f4d16..0fc1ccb9d0 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -84,7 +84,7 @@ struct SerialState {
it can be reset while reading iir */
int thr_ipending;
int irq;
- int out_fd;
+ CharDriverState *chr;
};
static void serial_update_irq(SerialState *s)
@@ -107,7 +107,6 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
SerialState *s = opaque;
unsigned char ch;
- int ret;
addr &= 7;
#ifdef DEBUG_SERIAL
@@ -122,13 +121,8 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s->thr_ipending = 0;
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
-
- if (s->out_fd >= 0) {
- ch = val;
- do {
- ret = write(s->out_fd, &ch, 1);
- } while (ret != 1);
- }
+ ch = val;
+ qemu_chr_write(s->chr, &ch, 1);
s->thr_ipending = 1;
s->lsr |= UART_LSR_THRE;
s->lsr |= UART_LSR_TEMT;
@@ -223,19 +217,19 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
return ret;
}
-int serial_can_receive(SerialState *s)
+static int serial_can_receive(SerialState *s)
{
return !(s->lsr & UART_LSR_DR);
}
-void serial_receive_byte(SerialState *s, int ch)
+static void serial_receive_byte(SerialState *s, int ch)
{
s->rbr = ch;
s->lsr |= UART_LSR_DR;
serial_update_irq(s);
}
-void serial_receive_break(SerialState *s)
+static void serial_receive_break(SerialState *s)
{
s->rbr = 0;
s->lsr |= UART_LSR_BI | UART_LSR_DR;
@@ -254,8 +248,15 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size)
serial_receive_byte(s, buf[0]);
}
+static void serial_event(void *opaque, int event)
+{
+ SerialState *s = opaque;
+ if (event == CHR_EVENT_BREAK)
+ serial_receive_break(s);
+}
+
/* If fd is zero, it means that the serial device uses the console */
-SerialState *serial_init(int base, int irq, int fd)
+SerialState *serial_init(int base, int irq, CharDriverState *chr)
{
SerialState *s;
@@ -268,16 +269,8 @@ SerialState *serial_init(int base, int irq, int fd)
register_ioport_write(base, 8, 1, serial_ioport_write, s);
register_ioport_read(base, 8, 1, serial_ioport_read, s);
-
- if (fd < 0) {
- /* no associated device */
- s->out_fd = -1;
- } else if (fd != 0) {
- qemu_add_fd_read_handler(fd, serial_can_receive1, serial_receive1, s);
- s->out_fd = fd;
- } else {
- serial_console = s;
- s->out_fd = 1;
- }
+ s->chr = chr;
+ qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
+ qemu_chr_add_event_handler(chr, serial_event);
return s;
}
diff --git a/vl.c b/vl.c
index 81782b0855..3d64188b68 100644
--- a/vl.c
+++ b/vl.c
@@ -128,7 +128,6 @@ static char network_script[1024];
int pit_min_timer_count = 0;
int nb_nics;
NetDriverState nd_table[MAX_NICS];
-SerialState *serial_console;
QEMUTimer *gui_timer;
int vm_running;
int audio_enabled = 0;
@@ -139,6 +138,7 @@ int cirrus_vga_enabled = 1;
int graphic_width = 800;
int graphic_height = 600;
int graphic_depth = 15;
+TextConsole *vga_console;
/***********************************************************/
/* x86 ISA bus support */
@@ -298,6 +298,22 @@ char *pstrcat(char *buf, int buf_size, const char *s)
return buf;
}
+int strstart(const char *str, const char *val, const char **ptr)
+{
+ const char *p, *q;
+ p = str;
+ q = val;
+ while (*q != '\0') {
+ if (*p != *q)
+ return 0;
+ p++;
+ q++;
+ }
+ if (ptr)
+ *ptr = p;
+ return 1;
+}
+
/* return the size or -1 if error */
int get_image_size(const char *filename)
{
@@ -949,42 +965,273 @@ void quit_timers(void)
}
/***********************************************************/
-/* serial device */
+/* character device */
-#ifdef _WIN32
+int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
+{
+ return s->chr_write(s, buf, len);
+}
-int serial_open_device(void)
+void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
{
- return -1;
+ char buf[4096];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ qemu_chr_write(s, buf, strlen(buf));
+ va_end(ap);
}
-#else
+void qemu_chr_add_read_handler(CharDriverState *s,
+ IOCanRWHandler *fd_can_read,
+ IOReadHandler *fd_read, void *opaque)
+{
+ s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
+}
+
+void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
+{
+ s->chr_event = chr_event;
+}
-int serial_open_device(void)
+static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
- if (serial_console == NULL && nographic) {
- /* use console for serial port */
- return 0;
+ return len;
+}
+
+static void null_chr_add_read_handler(CharDriverState *chr,
+ IOCanRWHandler *fd_can_read,
+ IOReadHandler *fd_read, void *opaque)
+{
+}
+
+CharDriverState *qemu_chr_open_null(void)
+{
+ CharDriverState *chr;
+
+ chr = qemu_mallocz(sizeof(CharDriverState));
+ if (!chr)
+ return NULL;
+ chr->chr_write = null_chr_write;
+ chr->chr_add_read_handler = null_chr_add_read_handler;
+ return chr;
+}
+
+#ifndef _WIN32
+
+typedef struct {
+ int fd_in, fd_out;
+ /* for nographic stdio only */
+ IOCanRWHandler *fd_can_read;
+ IOReadHandler *fd_read;
+ void *fd_opaque;
+} FDCharDriver;
+
+#define STDIO_MAX_CLIENTS 2
+
+static int stdio_nb_clients;
+static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
+
+static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+ FDCharDriver *s = chr->opaque;
+ return write(s->fd_out, buf, len);
+}
+
+static void fd_chr_add_read_handler(CharDriverState *chr,
+ IOCanRWHandler *fd_can_read,
+ IOReadHandler *fd_read, void *opaque)
+{
+ FDCharDriver *s = chr->opaque;
+
+ if (nographic && s->fd_in == 0) {
+ s->fd_can_read = fd_can_read;
+ s->fd_read = fd_read;
+ s->fd_opaque = opaque;
} else {
-#if 0
- char slave_name[1024];
- int master_fd, slave_fd;
-
- /* Not satisfying */
- if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
- fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
- return -1;
+ qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
+ }
+}
+
+/* open a character device to a unix fd */
+CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
+{
+ CharDriverState *chr;
+ FDCharDriver *s;
+
+ chr = qemu_mallocz(sizeof(CharDriverState));
+ if (!chr)
+ return NULL;
+ s = qemu_mallocz(sizeof(FDCharDriver));
+ if (!s) {
+ free(chr);
+ return NULL;
+ }
+ s->fd_in = fd_in;
+ s->fd_out = fd_out;
+ chr->opaque = s;
+ chr->chr_write = fd_chr_write;
+ chr->chr_add_read_handler = fd_chr_add_read_handler;
+ return chr;
+}
+
+/* for STDIO, we handle the case where several clients use it
+ (nographic mode) */
+
+#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
+
+static int term_got_escape, client_index;
+
+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 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;
+ chr->chr_event(s->fd_opaque, 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 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;
+ FDCharDriver *s;
+
+ chr = stdio_clients[client_index];
+ s = chr->opaque;
+ buf[0] = ch;
+ /* XXX: should queue the char if the device is not
+ ready */
+ if (s->fd_can_read(s->fd_opaque) > 0)
+ s->fd_read(s->fd_opaque, buf, 1);
}
- fprintf(stderr, "Serial port redirected to %s\n", slave_name);
- return master_fd;
-#else
- return -1;
-#endif
}
}
+static int stdio_can_read(void *opaque)
+{
+ /* XXX: not strictly correct */
+ return 1;
+}
+
+static void stdio_read(void *opaque, const uint8_t *buf, int size)
+{
+ int i;
+ for(i = 0; i < size; i++)
+ stdio_received_byte(buf[i]);
+}
+
+CharDriverState *qemu_chr_open_stdio(void)
+{
+ CharDriverState *chr;
+
+ if (nographic) {
+ if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
+ return NULL;
+ chr = qemu_chr_open_fd(0, 1);
+ if (stdio_nb_clients == 0)
+ qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, 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;
+ return chr;
+}
+
+#if defined(__linux__)
+CharDriverState *qemu_chr_open_pty(void)
+{
+ char slave_name[1024];
+ int master_fd, slave_fd;
+
+ /* Not satisfying */
+ if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
+ return NULL;
+ }
+ fprintf(stderr, "char device redirected to %s\n", slave_name);
+ return qemu_chr_open_fd(master_fd, master_fd);
+}
+#else
+CharDriverState *qemu_chr_open_pty(void)
+{
+ return NULL;
+}
#endif
+#endif /* !defined(_WIN32) */
+
+CharDriverState *qemu_chr_open(const char *filename)
+{
+ if (!strcmp(filename, "vc")) {
+ return text_console_init(&display_state);
+ } else if (!strcmp(filename, "null")) {
+ return qemu_chr_open_null();
+ } else
+#ifndef _WIN32
+ if (!strcmp(filename, "pty")) {
+ return qemu_chr_open_pty();
+ } else if (!strcmp(filename, "stdio")) {
+ return qemu_chr_open_stdio();
+ } else
+#endif
+ {
+ return NULL;
+ }
+}
+
/***********************************************************/
/* Linux network device redirectors */
@@ -2106,6 +2353,8 @@ void help(void)
"-initrd file use 'file' as initial ram disk\n"
"\n"
"Debug/Expert options:\n"
+ "-monitor dev redirect the monitor to char device 'dev'\n"
+ "-serial dev redirect the serial port to char device 'dev'\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"
@@ -2121,7 +2370,13 @@ void help(void)
" (default is CL-GD5446 PCI VGA)\n"
#endif
"\n"
- "During emulation, use C-a h to get terminal commands:\n",
+ "During emulation, the following keys are useful:\n"
+ "ctrl-shift-f toggle full screen\n"
+ "ctrl-shift-Fn switch to virtual console 'n'\n"
+ "ctrl-shift toggle mouse and keyboard grab\n"
+ "\n"
+ "When using -nographic, press 'ctrl-a h' to get some help.\n"
+ ,
#ifdef CONFIG_SOFTMMU
"qemu",
#else
@@ -2131,7 +2386,6 @@ void help(void)
DEFAULT_NETWORK_SCRIPT,
DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log");
- term_print_help();
#ifndef CONFIG_SOFTMMU
printf("\n"
"NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
@@ -2184,6 +2438,8 @@ enum {
QEMU_OPTION_cirrusvga,
QEMU_OPTION_g,
QEMU_OPTION_std_vga,
+ QEMU_OPTION_monitor,
+ QEMU_OPTION_serial,
};
typedef struct QEMUOption {
@@ -2235,7 +2491,9 @@ const QEMUOption qemu_options[] = {
{ "localtime", 0, QEMU_OPTION_localtime },
{ "isa", 0, QEMU_OPTION_isa },
{ "std-vga", 0, QEMU_OPTION_std_vga },
-
+ { "monitor", 1, QEMU_OPTION_monitor },
+ { "serial", 1, QEMU_OPTION_serial },
+
/* temporary options */
{ "pci", 0, QEMU_OPTION_pci },
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
@@ -2273,6 +2531,9 @@ int main(int argc, char **argv)
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
int optind;
const char *r, *optarg;
+ CharDriverState *monitor_hd;
+ char monitor_device[128];
+ char serial_device[128];
#if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */
@@ -2297,6 +2558,8 @@ int main(int argc, char **argv)
kernel_cmdline = "";
has_cdrom = 1;
cyls = heads = secs = 0;
+ pstrcpy(monitor_device, sizeof(monitor_device), "vc");
+ pstrcpy(serial_device, sizeof(serial_device), "vc");
nb_tun_fds = 0;
net_if_type = -1;
@@ -2308,7 +2571,7 @@ int main(int argc, char **argv)
macaddr[3] = 0x12;
macaddr[4] = 0x34;
macaddr[5] = 0x56;
-
+
optind = 1;
for(;;) {
if (optind >= argc)
@@ -2375,6 +2638,8 @@ int main(int argc, char **argv)
}
break;
case QEMU_OPTION_nographic:
+ pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
+ pstrcpy(serial_device, sizeof(serial_device), "stdio");
nographic = 1;
break;
case QEMU_OPTION_kernel:
@@ -2561,6 +2826,12 @@ int main(int argc, char **argv)
graphic_depth = depth;
}
break;
+ case QEMU_OPTION_monitor:
+ pstrcpy(monitor_device, sizeof(monitor_device), optarg);
+ break;
+ case QEMU_OPTION_serial:
+ pstrcpy(serial_device, sizeof(serial_device), optarg);
+ break;
}
}
}
@@ -2750,6 +3021,24 @@ int main(int argc, char **argv)
#endif
}
+ vga_console = graphic_console_init(ds);
+
+ 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);
+
+ serial_hd = qemu_chr_open(serial_device);
+ if (!serial_hd) {
+ fprintf(stderr, "qemu: could not open serial device '%s'\n", serial_device);
+ exit(1);
+ }
+ if (!strcmp(serial_device, "vc"))
+ qemu_chr_printf(serial_hd, "serial0 console\n");
+
+
/* setup cpu signal handlers for MMU / self modifying code handling */
#if !defined(CONFIG_SOFTMMU)
@@ -2805,10 +3094,6 @@ int main(int argc, char **argv)
kernel_filename, kernel_cmdline, initrd_filename);
#endif
- /* launched after the device init so that it can display or not a
- banner */
- monitor_init();
-
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
diff --git a/vl.h b/vl.h
index 15004c0104..a37981a500 100644
--- a/vl.h
+++ b/vl.h
@@ -215,8 +215,7 @@ extern const char *bios_dir;
void pstrcpy(char *buf, int buf_size, const char *str);
char *pstrcat(char *buf, int buf_size, const char *s);
-
-int serial_open_device(void);
+int strstart(const char *str, const char *val, const char **ptr);
extern int vm_running;
@@ -265,6 +264,31 @@ void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
void kbd_put_keycode(int keycode);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
+ constants) */
+#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
+#define QEMU_KEY_BACKSPACE 0x007f
+#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
+#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
+#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
+#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
+#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
+#define QEMU_KEY_END QEMU_KEY_ESC1(4)
+#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
+#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
+#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
+
+#define QEMU_KEY_CTRL_UP 0xe400
+#define QEMU_KEY_CTRL_DOWN 0xe401
+#define QEMU_KEY_CTRL_LEFT 0xe402
+#define QEMU_KEY_CTRL_RIGHT 0xe403
+#define QEMU_KEY_CTRL_HOME 0xe404
+#define QEMU_KEY_CTRL_END 0xe405
+#define QEMU_KEY_CTRL_PAGEUP 0xe406
+#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
+
+void kbd_put_keysym(int keysym);
+
/* async I/O support */
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
@@ -274,6 +298,42 @@ int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
IOReadHandler *fd_read, void *opaque);
void qemu_del_fd_read_handler(int fd);
+/* character device */
+
+#define CHR_EVENT_BREAK 0 /* serial break char */
+
+typedef void IOEventHandler(void *opaque, int event);
+
+typedef struct CharDriverState {
+ int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
+ void (*chr_add_read_handler)(struct CharDriverState *s,
+ IOCanRWHandler *fd_can_read,
+ IOReadHandler *fd_read, void *opaque);
+ IOEventHandler *chr_event;
+ void *opaque;
+} CharDriverState;
+
+void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
+void qemu_chr_add_read_handler(CharDriverState *s,
+ IOCanRWHandler *fd_can_read,
+ IOReadHandler *fd_read, void *opaque);
+void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
+
+CharDriverState *serial_hd;
+
+/* consoles */
+
+typedef struct DisplayState DisplayState;
+typedef struct TextConsole TextConsole;
+
+extern TextConsole *vga_console;
+
+TextConsole *graphic_console_init(DisplayState *ds);
+int is_active_console(TextConsole *s);
+CharDriverState *text_console_init(DisplayState *ds);
+void console_select(unsigned int index);
+
/* network redirectors support */
#define MAX_NICS 8
@@ -437,6 +497,7 @@ void bdrv_set_change_cb(BlockDriverState *bs,
void bdrv_info(void);
BlockDriverState *bdrv_find(const char *name);
+void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
/* ISA bus */
@@ -534,14 +595,16 @@ openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
#define VGA_RAM_SIZE (4096 * 1024)
-typedef struct DisplayState {
+struct DisplayState {
uint8_t *data;
int linesize;
int depth;
+ int width;
+ int height;
void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
void (*dpy_resize)(struct DisplayState *s, int w, int h);
void (*dpy_refresh)(struct DisplayState *s);
-} DisplayState;
+};
static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
{
@@ -644,13 +707,7 @@ void rtc_set_date(RTCState *s, const struct tm *tm);
/* serial.c */
typedef struct SerialState SerialState;
-
-extern SerialState *serial_console;
-
-SerialState *serial_init(int base, int irq, int fd);
-int serial_can_receive(SerialState *s);
-void serial_receive_byte(SerialState *s, int ch);
-void serial_receive_break(SerialState *s);
+SerialState *serial_init(int base, int irq, CharDriverState *chr);
/* i8259.c */
@@ -767,7 +824,7 @@ extern ADBBusState adb_bus;
int cuda_init(openpic_t *openpic, int irq);
/* monitor.c */
-void monitor_init(void);
+void monitor_init(CharDriverState *hd, int show_banner);
void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
void term_flush(void);
void term_print_help(void);