mirror of
https://git.proxmox.com/git/qemu
synced 2025-06-25 10:57:44 +00:00
char device support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1023 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
457831f4bc
commit
82c643ff50
5
hw/pc.c
5
hw/pc.c
@ -324,7 +324,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
const char *initrd_filename)
|
const char *initrd_filename)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
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;
|
unsigned long bios_offset, vga_bios_offset;
|
||||||
int bios_size, isa_bios_size;
|
int bios_size, isa_bios_size;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
@ -471,8 +471,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
pic_init();
|
pic_init();
|
||||||
pit = pit_init(0x40, 0);
|
pit = pit_init(0x40, 0);
|
||||||
|
|
||||||
fd = serial_open_device();
|
serial_init(0x3f8, 4, serial_hd);
|
||||||
serial_init(0x3f8, 4, fd);
|
|
||||||
|
|
||||||
if (pci_enabled) {
|
if (pci_enabled) {
|
||||||
for(i = 0; i < nb_nics; i++) {
|
for(i = 0; i < nb_nics; i++) {
|
||||||
|
@ -126,7 +126,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
openpic_t *openpic;
|
openpic_t *openpic;
|
||||||
m48t59_t *nvram;
|
m48t59_t *nvram;
|
||||||
int PPC_io_memory;
|
int PPC_io_memory;
|
||||||
int ret, linux_boot, i, fd;
|
int ret, linux_boot, i;
|
||||||
unsigned long bios_offset;
|
unsigned long bios_offset;
|
||||||
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
|
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
@ -200,8 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
pic_init();
|
pic_init();
|
||||||
|
|
||||||
/* XXX: use Mac Serial port */
|
/* XXX: use Mac Serial port */
|
||||||
fd = serial_open_device();
|
serial_init(0x3f8, 4, serial_hd);
|
||||||
serial_init(0x3f8, 4, fd);
|
|
||||||
|
|
||||||
for(i = 0; i < nb_nics; i++) {
|
for(i = 0; i < nb_nics; i++) {
|
||||||
pci_ne2000_init(pci_bus, &nd_table[i]);
|
pci_ne2000_init(pci_bus, &nd_table[i]);
|
||||||
|
@ -415,7 +415,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
m48t59_t *nvram;
|
m48t59_t *nvram;
|
||||||
int PPC_io_memory;
|
int PPC_io_memory;
|
||||||
int ret, linux_boot, i, nb_nics1, fd;
|
int ret, linux_boot, i, nb_nics1;
|
||||||
unsigned long bios_offset;
|
unsigned long bios_offset;
|
||||||
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
|
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
@ -492,8 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
|
|||||||
pic_init();
|
pic_init();
|
||||||
// pit = pit_init(0x40, 0);
|
// pit = pit_init(0x40, 0);
|
||||||
|
|
||||||
fd = serial_open_device();
|
serial_init(0x3f8, 4, serial_hd);
|
||||||
serial_init(0x3f8, 4, fd);
|
|
||||||
nb_nics1 = nb_nics;
|
nb_nics1 = nb_nics;
|
||||||
if (nb_nics1 > NE2000_NB_MAX)
|
if (nb_nics1 > NE2000_NB_MAX)
|
||||||
nb_nics1 = NE2000_NB_MAX;
|
nb_nics1 = NE2000_NB_MAX;
|
||||||
|
41
hw/serial.c
41
hw/serial.c
@ -84,7 +84,7 @@ struct SerialState {
|
|||||||
it can be reset while reading iir */
|
it can be reset while reading iir */
|
||||||
int thr_ipending;
|
int thr_ipending;
|
||||||
int irq;
|
int irq;
|
||||||
int out_fd;
|
CharDriverState *chr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void serial_update_irq(SerialState *s)
|
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;
|
SerialState *s = opaque;
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
int ret;
|
|
||||||
|
|
||||||
addr &= 7;
|
addr &= 7;
|
||||||
#ifdef DEBUG_SERIAL
|
#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->thr_ipending = 0;
|
||||||
s->lsr &= ~UART_LSR_THRE;
|
s->lsr &= ~UART_LSR_THRE;
|
||||||
serial_update_irq(s);
|
serial_update_irq(s);
|
||||||
|
ch = val;
|
||||||
if (s->out_fd >= 0) {
|
qemu_chr_write(s->chr, &ch, 1);
|
||||||
ch = val;
|
|
||||||
do {
|
|
||||||
ret = write(s->out_fd, &ch, 1);
|
|
||||||
} while (ret != 1);
|
|
||||||
}
|
|
||||||
s->thr_ipending = 1;
|
s->thr_ipending = 1;
|
||||||
s->lsr |= UART_LSR_THRE;
|
s->lsr |= UART_LSR_THRE;
|
||||||
s->lsr |= UART_LSR_TEMT;
|
s->lsr |= UART_LSR_TEMT;
|
||||||
@ -223,19 +217,19 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_can_receive(SerialState *s)
|
static int serial_can_receive(SerialState *s)
|
||||||
{
|
{
|
||||||
return !(s->lsr & UART_LSR_DR);
|
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->rbr = ch;
|
||||||
s->lsr |= UART_LSR_DR;
|
s->lsr |= UART_LSR_DR;
|
||||||
serial_update_irq(s);
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_receive_break(SerialState *s)
|
static void serial_receive_break(SerialState *s)
|
||||||
{
|
{
|
||||||
s->rbr = 0;
|
s->rbr = 0;
|
||||||
s->lsr |= UART_LSR_BI | UART_LSR_DR;
|
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]);
|
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 */
|
/* 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;
|
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_write(base, 8, 1, serial_ioport_write, s);
|
||||||
register_ioport_read(base, 8, 1, serial_ioport_read, s);
|
register_ioport_read(base, 8, 1, serial_ioport_read, s);
|
||||||
|
s->chr = chr;
|
||||||
if (fd < 0) {
|
qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
|
||||||
/* no associated device */
|
qemu_chr_add_event_handler(chr, serial_event);
|
||||||
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;
|
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
349
vl.c
349
vl.c
@ -128,7 +128,6 @@ static char network_script[1024];
|
|||||||
int pit_min_timer_count = 0;
|
int pit_min_timer_count = 0;
|
||||||
int nb_nics;
|
int nb_nics;
|
||||||
NetDriverState nd_table[MAX_NICS];
|
NetDriverState nd_table[MAX_NICS];
|
||||||
SerialState *serial_console;
|
|
||||||
QEMUTimer *gui_timer;
|
QEMUTimer *gui_timer;
|
||||||
int vm_running;
|
int vm_running;
|
||||||
int audio_enabled = 0;
|
int audio_enabled = 0;
|
||||||
@ -139,6 +138,7 @@ int cirrus_vga_enabled = 1;
|
|||||||
int graphic_width = 800;
|
int graphic_width = 800;
|
||||||
int graphic_height = 600;
|
int graphic_height = 600;
|
||||||
int graphic_depth = 15;
|
int graphic_depth = 15;
|
||||||
|
TextConsole *vga_console;
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* x86 ISA bus support */
|
/* x86 ISA bus support */
|
||||||
@ -298,6 +298,22 @@ char *pstrcat(char *buf, int buf_size, const char *s)
|
|||||||
return buf;
|
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 */
|
/* return the size or -1 if error */
|
||||||
int get_image_size(const char *filename)
|
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)
|
||||||
|
|
||||||
int serial_open_device(void)
|
|
||||||
{
|
{
|
||||||
return -1;
|
return s->chr_write(s, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
|
||||||
|
|
||||||
int serial_open_device(void)
|
|
||||||
{
|
{
|
||||||
if (serial_console == NULL && nographic) {
|
char buf[4096];
|
||||||
/* use console for serial port */
|
va_list ap;
|
||||||
return 0;
|
va_start(ap, fmt);
|
||||||
} else {
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
#if 0
|
qemu_chr_write(s, buf, strlen(buf));
|
||||||
char slave_name[1024];
|
va_end(ap);
|
||||||
int master_fd, slave_fd;
|
}
|
||||||
|
|
||||||
/* Not satisfying */
|
void qemu_chr_add_read_handler(CharDriverState *s,
|
||||||
if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
|
IOCanRWHandler *fd_can_read,
|
||||||
fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
|
IOReadHandler *fd_read, void *opaque)
|
||||||
return -1;
|
{
|
||||||
}
|
s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
|
||||||
fprintf(stderr, "Serial port redirected to %s\n", slave_name);
|
}
|
||||||
return master_fd;
|
|
||||||
#else
|
void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
|
||||||
return -1;
|
{
|
||||||
#endif
|
s->chr_event = chr_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
|
||||||
|
{
|
||||||
|
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 {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
#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 */
|
/* Linux network device redirectors */
|
||||||
|
|
||||||
@ -2106,6 +2353,8 @@ void help(void)
|
|||||||
"-initrd file use 'file' as initial ram disk\n"
|
"-initrd file use 'file' as initial ram disk\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Debug/Expert options:\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 freeze CPU at startup (use 'c' to start execution)\n"
|
||||||
"-s wait gdb connection to port %d\n"
|
"-s wait gdb connection to port %d\n"
|
||||||
"-p port change gdb connection port\n"
|
"-p port change gdb connection port\n"
|
||||||
@ -2121,7 +2370,13 @@ void help(void)
|
|||||||
" (default is CL-GD5446 PCI VGA)\n"
|
" (default is CL-GD5446 PCI VGA)\n"
|
||||||
#endif
|
#endif
|
||||||
"\n"
|
"\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
|
#ifdef CONFIG_SOFTMMU
|
||||||
"qemu",
|
"qemu",
|
||||||
#else
|
#else
|
||||||
@ -2131,7 +2386,6 @@ void help(void)
|
|||||||
DEFAULT_NETWORK_SCRIPT,
|
DEFAULT_NETWORK_SCRIPT,
|
||||||
DEFAULT_GDBSTUB_PORT,
|
DEFAULT_GDBSTUB_PORT,
|
||||||
"/tmp/qemu.log");
|
"/tmp/qemu.log");
|
||||||
term_print_help();
|
|
||||||
#ifndef CONFIG_SOFTMMU
|
#ifndef CONFIG_SOFTMMU
|
||||||
printf("\n"
|
printf("\n"
|
||||||
"NOTE: this version of QEMU is faster but it needs slightly patched OSes to\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_cirrusvga,
|
||||||
QEMU_OPTION_g,
|
QEMU_OPTION_g,
|
||||||
QEMU_OPTION_std_vga,
|
QEMU_OPTION_std_vga,
|
||||||
|
QEMU_OPTION_monitor,
|
||||||
|
QEMU_OPTION_serial,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct QEMUOption {
|
typedef struct QEMUOption {
|
||||||
@ -2235,6 +2491,8 @@ const QEMUOption qemu_options[] = {
|
|||||||
{ "localtime", 0, QEMU_OPTION_localtime },
|
{ "localtime", 0, QEMU_OPTION_localtime },
|
||||||
{ "isa", 0, QEMU_OPTION_isa },
|
{ "isa", 0, QEMU_OPTION_isa },
|
||||||
{ "std-vga", 0, QEMU_OPTION_std_vga },
|
{ "std-vga", 0, QEMU_OPTION_std_vga },
|
||||||
|
{ "monitor", 1, QEMU_OPTION_monitor },
|
||||||
|
{ "serial", 1, QEMU_OPTION_serial },
|
||||||
|
|
||||||
/* temporary options */
|
/* temporary options */
|
||||||
{ "pci", 0, QEMU_OPTION_pci },
|
{ "pci", 0, QEMU_OPTION_pci },
|
||||||
@ -2273,6 +2531,9 @@ int main(int argc, char **argv)
|
|||||||
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
|
||||||
int optind;
|
int optind;
|
||||||
const char *r, *optarg;
|
const char *r, *optarg;
|
||||||
|
CharDriverState *monitor_hd;
|
||||||
|
char monitor_device[128];
|
||||||
|
char serial_device[128];
|
||||||
|
|
||||||
#if !defined(CONFIG_SOFTMMU)
|
#if !defined(CONFIG_SOFTMMU)
|
||||||
/* we never want that malloc() uses mmap() */
|
/* we never want that malloc() uses mmap() */
|
||||||
@ -2297,6 +2558,8 @@ int main(int argc, char **argv)
|
|||||||
kernel_cmdline = "";
|
kernel_cmdline = "";
|
||||||
has_cdrom = 1;
|
has_cdrom = 1;
|
||||||
cyls = heads = secs = 0;
|
cyls = heads = secs = 0;
|
||||||
|
pstrcpy(monitor_device, sizeof(monitor_device), "vc");
|
||||||
|
pstrcpy(serial_device, sizeof(serial_device), "vc");
|
||||||
|
|
||||||
nb_tun_fds = 0;
|
nb_tun_fds = 0;
|
||||||
net_if_type = -1;
|
net_if_type = -1;
|
||||||
@ -2375,6 +2638,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QEMU_OPTION_nographic:
|
case QEMU_OPTION_nographic:
|
||||||
|
pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
|
||||||
|
pstrcpy(serial_device, sizeof(serial_device), "stdio");
|
||||||
nographic = 1;
|
nographic = 1;
|
||||||
break;
|
break;
|
||||||
case QEMU_OPTION_kernel:
|
case QEMU_OPTION_kernel:
|
||||||
@ -2561,6 +2826,12 @@ int main(int argc, char **argv)
|
|||||||
graphic_depth = depth;
|
graphic_depth = depth;
|
||||||
}
|
}
|
||||||
break;
|
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
|
#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 */
|
/* setup cpu signal handlers for MMU / self modifying code handling */
|
||||||
#if !defined(CONFIG_SOFTMMU)
|
#if !defined(CONFIG_SOFTMMU)
|
||||||
|
|
||||||
@ -2805,10 +3094,6 @@ int main(int argc, char **argv)
|
|||||||
kernel_filename, kernel_cmdline, initrd_filename);
|
kernel_filename, kernel_cmdline, initrd_filename);
|
||||||
#endif
|
#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);
|
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
|
||||||
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
|
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
|
||||||
|
|
||||||
|
81
vl.h
81
vl.h
@ -215,8 +215,7 @@ extern const char *bios_dir;
|
|||||||
|
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str);
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
char *pstrcat(char *buf, int buf_size, const char *s);
|
char *pstrcat(char *buf, int buf_size, const char *s);
|
||||||
|
int strstart(const char *str, const char *val, const char **ptr);
|
||||||
int serial_open_device(void);
|
|
||||||
|
|
||||||
extern int vm_running;
|
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_put_keycode(int keycode);
|
||||||
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
|
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 */
|
/* async I/O support */
|
||||||
|
|
||||||
typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
|
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);
|
IOReadHandler *fd_read, void *opaque);
|
||||||
void qemu_del_fd_read_handler(int fd);
|
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 */
|
/* network redirectors support */
|
||||||
|
|
||||||
#define MAX_NICS 8
|
#define MAX_NICS 8
|
||||||
@ -437,6 +497,7 @@ void bdrv_set_change_cb(BlockDriverState *bs,
|
|||||||
|
|
||||||
void bdrv_info(void);
|
void bdrv_info(void);
|
||||||
BlockDriverState *bdrv_find(const char *name);
|
BlockDriverState *bdrv_find(const char *name);
|
||||||
|
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
|
||||||
|
|
||||||
/* ISA bus */
|
/* ISA bus */
|
||||||
|
|
||||||
@ -534,14 +595,16 @@ openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
|
|||||||
|
|
||||||
#define VGA_RAM_SIZE (4096 * 1024)
|
#define VGA_RAM_SIZE (4096 * 1024)
|
||||||
|
|
||||||
typedef struct DisplayState {
|
struct DisplayState {
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
int linesize;
|
int linesize;
|
||||||
int depth;
|
int depth;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
|
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_resize)(struct DisplayState *s, int w, int h);
|
||||||
void (*dpy_refresh)(struct DisplayState *s);
|
void (*dpy_refresh)(struct DisplayState *s);
|
||||||
} DisplayState;
|
};
|
||||||
|
|
||||||
static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
|
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 */
|
/* serial.c */
|
||||||
|
|
||||||
typedef struct SerialState SerialState;
|
typedef struct SerialState SerialState;
|
||||||
|
SerialState *serial_init(int base, int irq, CharDriverState *chr);
|
||||||
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);
|
|
||||||
|
|
||||||
/* i8259.c */
|
/* i8259.c */
|
||||||
|
|
||||||
@ -767,7 +824,7 @@ extern ADBBusState adb_bus;
|
|||||||
int cuda_init(openpic_t *openpic, int irq);
|
int cuda_init(openpic_t *openpic, int irq);
|
||||||
|
|
||||||
/* monitor.c */
|
/* 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_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
void term_flush(void);
|
void term_flush(void);
|
||||||
void term_print_help(void);
|
void term_print_help(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user