aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/pc.c11
-rw-r--r--hw/ppc_chrp.c2
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--vl.c137
-rw-r--r--vl.h8
5 files changed, 88 insertions, 72 deletions
diff --git a/hw/pc.c b/hw/pc.c
index 0fd7b87b26..f59ea2397f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -314,9 +314,12 @@ static const int ide_irq[2] = { 14, 15 };
#define NE2000_NB_MAX 6
-static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
+static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
+static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
+
/* PC hardware initialisation */
void pc_init(int ram_size, int vga_ram_size, int boot_device,
DisplayState *ds, const char **fd_filename, int snapshot,
@@ -471,7 +474,11 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
pit = pit_init(0x40, 0);
- serial_init(0x3f8, 4, serial_hd);
+ for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+ if (serial_hds[i]) {
+ serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+ }
+ }
if (pci_enabled) {
for(i = 0; i < nb_nics; i++) {
diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c
index f532fe1019..cf3a5f32fa 100644
--- a/hw/ppc_chrp.c
+++ b/hw/ppc_chrp.c
@@ -200,7 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
/* XXX: use Mac Serial port */
- serial_init(0x3f8, 4, serial_hd);
+ serial_init(0x3f8, 4, serial_hds[0]);
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 eeb5a36095..c93b72faeb 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -492,7 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
pic_init();
// pit = pit_init(0x40, 0);
- serial_init(0x3f8, 4, serial_hd);
+ serial_init(0x3f8, 4, serial_hds[0]);
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
nb_nics1 = NE2000_NB_MAX;
diff --git a/vl.c b/vl.c
index 646d1ff947..4d274478eb 100644
--- a/vl.c
+++ b/vl.c
@@ -128,6 +128,7 @@ int graphic_width = 800;
int graphic_height = 600;
int graphic_depth = 15;
TextConsole *vga_console;
+CharDriverState *serial_hds[MAX_SERIAL_PORTS];
/***********************************************************/
/* x86 ISA bus support */
@@ -1166,6 +1167,43 @@ static void stdio_read(void *opaque, const uint8_t *buf, int size)
stdio_received_byte(buf[i]);
}
+/* init terminal so that we can grab keys */
+static struct termios oldtty;
+static int old_fd0_flags;
+
+static void term_exit(void)
+{
+ tcsetattr (0, TCSANOW, &oldtty);
+ fcntl(0, F_SETFL, old_fd0_flags);
+}
+
+static void term_init(void)
+{
+ struct termios tty;
+
+ tcgetattr (0, &tty);
+ oldtty = tty;
+ old_fd0_flags = fcntl(0, F_GETFL);
+
+ tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+ |INLCR|IGNCR|ICRNL|IXON);
+ tty.c_oflag |= OPOST;
+ tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+ /* if graphical mode, we allow Ctrl-C handling */
+ if (nographic)
+ tty.c_lflag &= ~ISIG;
+ tty.c_cflag &= ~(CSIZE|PARENB);
+ tty.c_cflag |= CS8;
+ tty.c_cc[VMIN] = 1;
+ tty.c_cc[VTIME] = 0;
+
+ tcsetattr (0, TCSANOW, &tty);
+
+ atexit(term_exit);
+
+ fcntl(0, F_SETFL, O_NONBLOCK);
+}
+
CharDriverState *qemu_chr_open_stdio(void)
{
CharDriverState *chr;
@@ -1183,6 +1221,10 @@ CharDriverState *qemu_chr_open_stdio(void)
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();
+ }
return chr;
}
@@ -1449,57 +1491,6 @@ static int net_fd_init(NetDriverState *nd, int fd)
/***********************************************************/
/* dumb display */
-#ifdef _WIN32
-
-static void term_exit(void)
-{
-}
-
-static void term_init(void)
-{
-}
-
-#else
-
-/* init terminal so that we can grab keys */
-static struct termios oldtty;
-static int old_fd0_flags;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
- fcntl(0, F_SETFL, old_fd0_flags);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
- old_fd0_flags = fcntl(0, F_GETFL);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- /* if graphical mode, we allow Ctrl-C handling */
- if (nographic)
- tty.c_lflag &= ~ISIG;
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- atexit(term_exit);
-
- fcntl(0, F_SETFL, O_NONBLOCK);
-}
-
-#endif
-
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
{
}
@@ -1531,7 +1522,8 @@ static void host_segv_handler(int host_signum, siginfo_t *info,
{
if (cpu_signal_handler(host_signum, info, puc))
return;
- term_exit();
+ if (stdio_nb_clients > 0)
+ term_exit();
abort();
}
#endif
@@ -2568,8 +2560,9 @@ int main(int argc, char **argv)
const char *r, *optarg;
CharDriverState *monitor_hd;
char monitor_device[128];
- char serial_device[128];
-
+ char serial_devices[MAX_SERIAL_PORTS][128];
+ int serial_device_index;
+
#if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */
mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
@@ -2594,8 +2587,12 @@ int main(int argc, char **argv)
has_cdrom = 1;
cyls = heads = secs = 0;
pstrcpy(monitor_device, sizeof(monitor_device), "vc");
- pstrcpy(serial_device, sizeof(serial_device), "vc");
+ pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
+ for(i = 1; i < MAX_SERIAL_PORTS; i++)
+ serial_devices[i][0] = '\0';
+ serial_device_index = 0;
+
nb_tun_fds = 0;
net_if_type = -1;
nb_nics = 1;
@@ -2674,7 +2671,7 @@ 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");
+ pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
nographic = 1;
break;
case QEMU_OPTION_kernel:
@@ -2865,7 +2862,13 @@ int main(int argc, char **argv)
pstrcpy(monitor_device, sizeof(monitor_device), optarg);
break;
case QEMU_OPTION_serial:
- pstrcpy(serial_device, sizeof(serial_device), optarg);
+ if (serial_device_index >= MAX_SERIAL_PORTS) {
+ fprintf(stderr, "qemu: too many serial ports\n");
+ exit(1);
+ }
+ pstrcpy(serial_devices[serial_device_index],
+ sizeof(serial_devices[0]), optarg);
+ serial_device_index++;
break;
}
}
@@ -3066,14 +3069,18 @@ int main(int argc, char **argv)
}
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);
+ for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+ if (serial_devices[i][0] != '\0') {
+ serial_hds[i] = qemu_chr_open(serial_devices[i]);
+ if (!serial_hds[i]) {
+ fprintf(stderr, "qemu: could not open serial device '%s'\n",
+ serial_devices[i]);
+ exit(1);
+ }
+ if (!strcmp(serial_devices[i], "vc"))
+ qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
+ }
}
- 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)
@@ -3142,11 +3149,9 @@ int main(int argc, char **argv)
} else {
printf("Waiting gdb connection on port %d\n", gdbstub_port);
}
- term_init();
} else
#endif
{
- term_init();
/* XXX: simplify init */
read_passwords();
if (start_emulation) {
diff --git a/vl.h b/vl.h
index 485ccc020c..1f1e9e4242 100644
--- a/vl.h
+++ b/vl.h
@@ -200,8 +200,6 @@ void qemu_chr_add_read_handler(CharDriverState *s,
IOReadHandler *fd_read, void *opaque);
void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
-CharDriverState *serial_hd;
-
/* consoles */
typedef struct DisplayState DisplayState;
@@ -214,6 +212,12 @@ int is_active_console(TextConsole *s);
CharDriverState *text_console_init(DisplayState *ds);
void console_select(unsigned int index);
+/* serial ports */
+
+#define MAX_SERIAL_PORTS 4
+
+extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+
/* network redirectors support */
#define MAX_NICS 8