Commit 8d11df9e5aa58497e27e3481cca119809c76afc6
1 parent
05d5818c
multiple serial port support - terminal init fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1048 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
88 additions
and
72 deletions
hw/pc.c
@@ -314,9 +314,12 @@ static const int ide_irq[2] = { 14, 15 }; | @@ -314,9 +314,12 @@ static const int ide_irq[2] = { 14, 15 }; | ||
314 | 314 | ||
315 | #define NE2000_NB_MAX 6 | 315 | #define NE2000_NB_MAX 6 |
316 | 316 | ||
317 | -static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; | 317 | +static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; |
318 | static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; | 318 | static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; |
319 | 319 | ||
320 | +static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; | ||
321 | +static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; | ||
322 | + | ||
320 | /* PC hardware initialisation */ | 323 | /* PC hardware initialisation */ |
321 | void pc_init(int ram_size, int vga_ram_size, int boot_device, | 324 | void pc_init(int ram_size, int vga_ram_size, int boot_device, |
322 | DisplayState *ds, const char **fd_filename, int snapshot, | 325 | 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, | @@ -471,7 +474,11 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, | ||
471 | pic_init(); | 474 | pic_init(); |
472 | pit = pit_init(0x40, 0); | 475 | pit = pit_init(0x40, 0); |
473 | 476 | ||
474 | - serial_init(0x3f8, 4, serial_hd); | 477 | + for(i = 0; i < MAX_SERIAL_PORTS; i++) { |
478 | + if (serial_hds[i]) { | ||
479 | + serial_init(serial_io[i], serial_irq[i], serial_hds[i]); | ||
480 | + } | ||
481 | + } | ||
475 | 482 | ||
476 | if (pci_enabled) { | 483 | if (pci_enabled) { |
477 | for(i = 0; i < nb_nics; i++) { | 484 | for(i = 0; i < nb_nics; i++) { |
hw/ppc_chrp.c
@@ -200,7 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | @@ -200,7 +200,7 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | ||
200 | pic_init(); | 200 | pic_init(); |
201 | 201 | ||
202 | /* XXX: use Mac Serial port */ | 202 | /* XXX: use Mac Serial port */ |
203 | - serial_init(0x3f8, 4, serial_hd); | 203 | + serial_init(0x3f8, 4, serial_hds[0]); |
204 | 204 | ||
205 | for(i = 0; i < nb_nics; i++) { | 205 | for(i = 0; i < nb_nics; i++) { |
206 | pci_ne2000_init(pci_bus, &nd_table[i]); | 206 | pci_ne2000_init(pci_bus, &nd_table[i]); |
hw/ppc_prep.c
@@ -492,7 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | @@ -492,7 +492,7 @@ void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | ||
492 | pic_init(); | 492 | pic_init(); |
493 | // pit = pit_init(0x40, 0); | 493 | // pit = pit_init(0x40, 0); |
494 | 494 | ||
495 | - serial_init(0x3f8, 4, serial_hd); | 495 | + serial_init(0x3f8, 4, serial_hds[0]); |
496 | nb_nics1 = nb_nics; | 496 | nb_nics1 = nb_nics; |
497 | if (nb_nics1 > NE2000_NB_MAX) | 497 | if (nb_nics1 > NE2000_NB_MAX) |
498 | nb_nics1 = NE2000_NB_MAX; | 498 | nb_nics1 = NE2000_NB_MAX; |
vl.c
@@ -128,6 +128,7 @@ int graphic_width = 800; | @@ -128,6 +128,7 @@ int graphic_width = 800; | ||
128 | int graphic_height = 600; | 128 | int graphic_height = 600; |
129 | int graphic_depth = 15; | 129 | int graphic_depth = 15; |
130 | TextConsole *vga_console; | 130 | TextConsole *vga_console; |
131 | +CharDriverState *serial_hds[MAX_SERIAL_PORTS]; | ||
131 | 132 | ||
132 | /***********************************************************/ | 133 | /***********************************************************/ |
133 | /* x86 ISA bus support */ | 134 | /* x86 ISA bus support */ |
@@ -1166,6 +1167,43 @@ static void stdio_read(void *opaque, const uint8_t *buf, int size) | @@ -1166,6 +1167,43 @@ static void stdio_read(void *opaque, const uint8_t *buf, int size) | ||
1166 | stdio_received_byte(buf[i]); | 1167 | stdio_received_byte(buf[i]); |
1167 | } | 1168 | } |
1168 | 1169 | ||
1170 | +/* init terminal so that we can grab keys */ | ||
1171 | +static struct termios oldtty; | ||
1172 | +static int old_fd0_flags; | ||
1173 | + | ||
1174 | +static void term_exit(void) | ||
1175 | +{ | ||
1176 | + tcsetattr (0, TCSANOW, &oldtty); | ||
1177 | + fcntl(0, F_SETFL, old_fd0_flags); | ||
1178 | +} | ||
1179 | + | ||
1180 | +static void term_init(void) | ||
1181 | +{ | ||
1182 | + struct termios tty; | ||
1183 | + | ||
1184 | + tcgetattr (0, &tty); | ||
1185 | + oldtty = tty; | ||
1186 | + old_fd0_flags = fcntl(0, F_GETFL); | ||
1187 | + | ||
1188 | + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP | ||
1189 | + |INLCR|IGNCR|ICRNL|IXON); | ||
1190 | + tty.c_oflag |= OPOST; | ||
1191 | + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); | ||
1192 | + /* if graphical mode, we allow Ctrl-C handling */ | ||
1193 | + if (nographic) | ||
1194 | + tty.c_lflag &= ~ISIG; | ||
1195 | + tty.c_cflag &= ~(CSIZE|PARENB); | ||
1196 | + tty.c_cflag |= CS8; | ||
1197 | + tty.c_cc[VMIN] = 1; | ||
1198 | + tty.c_cc[VTIME] = 0; | ||
1199 | + | ||
1200 | + tcsetattr (0, TCSANOW, &tty); | ||
1201 | + | ||
1202 | + atexit(term_exit); | ||
1203 | + | ||
1204 | + fcntl(0, F_SETFL, O_NONBLOCK); | ||
1205 | +} | ||
1206 | + | ||
1169 | CharDriverState *qemu_chr_open_stdio(void) | 1207 | CharDriverState *qemu_chr_open_stdio(void) |
1170 | { | 1208 | { |
1171 | CharDriverState *chr; | 1209 | CharDriverState *chr; |
@@ -1183,6 +1221,10 @@ CharDriverState *qemu_chr_open_stdio(void) | @@ -1183,6 +1221,10 @@ CharDriverState *qemu_chr_open_stdio(void) | ||
1183 | chr = qemu_chr_open_fd(0, 1); | 1221 | chr = qemu_chr_open_fd(0, 1); |
1184 | } | 1222 | } |
1185 | stdio_clients[stdio_nb_clients++] = chr; | 1223 | stdio_clients[stdio_nb_clients++] = chr; |
1224 | + if (stdio_nb_clients == 1) { | ||
1225 | + /* set the terminal in raw mode */ | ||
1226 | + term_init(); | ||
1227 | + } | ||
1186 | return chr; | 1228 | return chr; |
1187 | } | 1229 | } |
1188 | 1230 | ||
@@ -1449,57 +1491,6 @@ static int net_fd_init(NetDriverState *nd, int fd) | @@ -1449,57 +1491,6 @@ static int net_fd_init(NetDriverState *nd, int fd) | ||
1449 | /***********************************************************/ | 1491 | /***********************************************************/ |
1450 | /* dumb display */ | 1492 | /* dumb display */ |
1451 | 1493 | ||
1452 | -#ifdef _WIN32 | ||
1453 | - | ||
1454 | -static void term_exit(void) | ||
1455 | -{ | ||
1456 | -} | ||
1457 | - | ||
1458 | -static void term_init(void) | ||
1459 | -{ | ||
1460 | -} | ||
1461 | - | ||
1462 | -#else | ||
1463 | - | ||
1464 | -/* init terminal so that we can grab keys */ | ||
1465 | -static struct termios oldtty; | ||
1466 | -static int old_fd0_flags; | ||
1467 | - | ||
1468 | -static void term_exit(void) | ||
1469 | -{ | ||
1470 | - tcsetattr (0, TCSANOW, &oldtty); | ||
1471 | - fcntl(0, F_SETFL, old_fd0_flags); | ||
1472 | -} | ||
1473 | - | ||
1474 | -static void term_init(void) | ||
1475 | -{ | ||
1476 | - struct termios tty; | ||
1477 | - | ||
1478 | - tcgetattr (0, &tty); | ||
1479 | - oldtty = tty; | ||
1480 | - old_fd0_flags = fcntl(0, F_GETFL); | ||
1481 | - | ||
1482 | - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP | ||
1483 | - |INLCR|IGNCR|ICRNL|IXON); | ||
1484 | - tty.c_oflag |= OPOST; | ||
1485 | - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); | ||
1486 | - /* if graphical mode, we allow Ctrl-C handling */ | ||
1487 | - if (nographic) | ||
1488 | - tty.c_lflag &= ~ISIG; | ||
1489 | - tty.c_cflag &= ~(CSIZE|PARENB); | ||
1490 | - tty.c_cflag |= CS8; | ||
1491 | - tty.c_cc[VMIN] = 1; | ||
1492 | - tty.c_cc[VTIME] = 0; | ||
1493 | - | ||
1494 | - tcsetattr (0, TCSANOW, &tty); | ||
1495 | - | ||
1496 | - atexit(term_exit); | ||
1497 | - | ||
1498 | - fcntl(0, F_SETFL, O_NONBLOCK); | ||
1499 | -} | ||
1500 | - | ||
1501 | -#endif | ||
1502 | - | ||
1503 | static void dumb_update(DisplayState *ds, int x, int y, int w, int h) | 1494 | static void dumb_update(DisplayState *ds, int x, int y, int w, int h) |
1504 | { | 1495 | { |
1505 | } | 1496 | } |
@@ -1531,7 +1522,8 @@ static void host_segv_handler(int host_signum, siginfo_t *info, | @@ -1531,7 +1522,8 @@ static void host_segv_handler(int host_signum, siginfo_t *info, | ||
1531 | { | 1522 | { |
1532 | if (cpu_signal_handler(host_signum, info, puc)) | 1523 | if (cpu_signal_handler(host_signum, info, puc)) |
1533 | return; | 1524 | return; |
1534 | - term_exit(); | 1525 | + if (stdio_nb_clients > 0) |
1526 | + term_exit(); | ||
1535 | abort(); | 1527 | abort(); |
1536 | } | 1528 | } |
1537 | #endif | 1529 | #endif |
@@ -2568,8 +2560,9 @@ int main(int argc, char **argv) | @@ -2568,8 +2560,9 @@ int main(int argc, char **argv) | ||
2568 | const char *r, *optarg; | 2560 | const char *r, *optarg; |
2569 | CharDriverState *monitor_hd; | 2561 | CharDriverState *monitor_hd; |
2570 | char monitor_device[128]; | 2562 | char monitor_device[128]; |
2571 | - char serial_device[128]; | ||
2572 | - | 2563 | + char serial_devices[MAX_SERIAL_PORTS][128]; |
2564 | + int serial_device_index; | ||
2565 | + | ||
2573 | #if !defined(CONFIG_SOFTMMU) | 2566 | #if !defined(CONFIG_SOFTMMU) |
2574 | /* we never want that malloc() uses mmap() */ | 2567 | /* we never want that malloc() uses mmap() */ |
2575 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); | 2568 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
@@ -2594,8 +2587,12 @@ int main(int argc, char **argv) | @@ -2594,8 +2587,12 @@ int main(int argc, char **argv) | ||
2594 | has_cdrom = 1; | 2587 | has_cdrom = 1; |
2595 | cyls = heads = secs = 0; | 2588 | cyls = heads = secs = 0; |
2596 | pstrcpy(monitor_device, sizeof(monitor_device), "vc"); | 2589 | pstrcpy(monitor_device, sizeof(monitor_device), "vc"); |
2597 | - pstrcpy(serial_device, sizeof(serial_device), "vc"); | ||
2598 | 2590 | ||
2591 | + pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc"); | ||
2592 | + for(i = 1; i < MAX_SERIAL_PORTS; i++) | ||
2593 | + serial_devices[i][0] = '\0'; | ||
2594 | + serial_device_index = 0; | ||
2595 | + | ||
2599 | nb_tun_fds = 0; | 2596 | nb_tun_fds = 0; |
2600 | net_if_type = -1; | 2597 | net_if_type = -1; |
2601 | nb_nics = 1; | 2598 | nb_nics = 1; |
@@ -2674,7 +2671,7 @@ int main(int argc, char **argv) | @@ -2674,7 +2671,7 @@ int main(int argc, char **argv) | ||
2674 | break; | 2671 | break; |
2675 | case QEMU_OPTION_nographic: | 2672 | case QEMU_OPTION_nographic: |
2676 | pstrcpy(monitor_device, sizeof(monitor_device), "stdio"); | 2673 | pstrcpy(monitor_device, sizeof(monitor_device), "stdio"); |
2677 | - pstrcpy(serial_device, sizeof(serial_device), "stdio"); | 2674 | + pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio"); |
2678 | nographic = 1; | 2675 | nographic = 1; |
2679 | break; | 2676 | break; |
2680 | case QEMU_OPTION_kernel: | 2677 | case QEMU_OPTION_kernel: |
@@ -2865,7 +2862,13 @@ int main(int argc, char **argv) | @@ -2865,7 +2862,13 @@ int main(int argc, char **argv) | ||
2865 | pstrcpy(monitor_device, sizeof(monitor_device), optarg); | 2862 | pstrcpy(monitor_device, sizeof(monitor_device), optarg); |
2866 | break; | 2863 | break; |
2867 | case QEMU_OPTION_serial: | 2864 | case QEMU_OPTION_serial: |
2868 | - pstrcpy(serial_device, sizeof(serial_device), optarg); | 2865 | + if (serial_device_index >= MAX_SERIAL_PORTS) { |
2866 | + fprintf(stderr, "qemu: too many serial ports\n"); | ||
2867 | + exit(1); | ||
2868 | + } | ||
2869 | + pstrcpy(serial_devices[serial_device_index], | ||
2870 | + sizeof(serial_devices[0]), optarg); | ||
2871 | + serial_device_index++; | ||
2869 | break; | 2872 | break; |
2870 | } | 2873 | } |
2871 | } | 2874 | } |
@@ -3066,14 +3069,18 @@ int main(int argc, char **argv) | @@ -3066,14 +3069,18 @@ int main(int argc, char **argv) | ||
3066 | } | 3069 | } |
3067 | monitor_init(monitor_hd, !nographic); | 3070 | monitor_init(monitor_hd, !nographic); |
3068 | 3071 | ||
3069 | - serial_hd = qemu_chr_open(serial_device); | ||
3070 | - if (!serial_hd) { | ||
3071 | - fprintf(stderr, "qemu: could not open serial device '%s'\n", serial_device); | ||
3072 | - exit(1); | 3072 | + for(i = 0; i < MAX_SERIAL_PORTS; i++) { |
3073 | + if (serial_devices[i][0] != '\0') { | ||
3074 | + serial_hds[i] = qemu_chr_open(serial_devices[i]); | ||
3075 | + if (!serial_hds[i]) { | ||
3076 | + fprintf(stderr, "qemu: could not open serial device '%s'\n", | ||
3077 | + serial_devices[i]); | ||
3078 | + exit(1); | ||
3079 | + } | ||
3080 | + if (!strcmp(serial_devices[i], "vc")) | ||
3081 | + qemu_chr_printf(serial_hds[i], "serial%d console\n", i); | ||
3082 | + } | ||
3073 | } | 3083 | } |
3074 | - if (!strcmp(serial_device, "vc")) | ||
3075 | - qemu_chr_printf(serial_hd, "serial0 console\n"); | ||
3076 | - | ||
3077 | 3084 | ||
3078 | /* setup cpu signal handlers for MMU / self modifying code handling */ | 3085 | /* setup cpu signal handlers for MMU / self modifying code handling */ |
3079 | #if !defined(CONFIG_SOFTMMU) | 3086 | #if !defined(CONFIG_SOFTMMU) |
@@ -3142,11 +3149,9 @@ int main(int argc, char **argv) | @@ -3142,11 +3149,9 @@ int main(int argc, char **argv) | ||
3142 | } else { | 3149 | } else { |
3143 | printf("Waiting gdb connection on port %d\n", gdbstub_port); | 3150 | printf("Waiting gdb connection on port %d\n", gdbstub_port); |
3144 | } | 3151 | } |
3145 | - term_init(); | ||
3146 | } else | 3152 | } else |
3147 | #endif | 3153 | #endif |
3148 | { | 3154 | { |
3149 | - term_init(); | ||
3150 | /* XXX: simplify init */ | 3155 | /* XXX: simplify init */ |
3151 | read_passwords(); | 3156 | read_passwords(); |
3152 | if (start_emulation) { | 3157 | if (start_emulation) { |
vl.h
@@ -200,8 +200,6 @@ void qemu_chr_add_read_handler(CharDriverState *s, | @@ -200,8 +200,6 @@ void qemu_chr_add_read_handler(CharDriverState *s, | ||
200 | IOReadHandler *fd_read, void *opaque); | 200 | IOReadHandler *fd_read, void *opaque); |
201 | void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event); | 201 | void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event); |
202 | 202 | ||
203 | -CharDriverState *serial_hd; | ||
204 | - | ||
205 | /* consoles */ | 203 | /* consoles */ |
206 | 204 | ||
207 | typedef struct DisplayState DisplayState; | 205 | typedef struct DisplayState DisplayState; |
@@ -214,6 +212,12 @@ int is_active_console(TextConsole *s); | @@ -214,6 +212,12 @@ int is_active_console(TextConsole *s); | ||
214 | CharDriverState *text_console_init(DisplayState *ds); | 212 | CharDriverState *text_console_init(DisplayState *ds); |
215 | void console_select(unsigned int index); | 213 | void console_select(unsigned int index); |
216 | 214 | ||
215 | +/* serial ports */ | ||
216 | + | ||
217 | +#define MAX_SERIAL_PORTS 4 | ||
218 | + | ||
219 | +extern CharDriverState *serial_hds[MAX_SERIAL_PORTS]; | ||
220 | + | ||
217 | /* network redirectors support */ | 221 | /* network redirectors support */ |
218 | 222 | ||
219 | #define MAX_NICS 8 | 223 | #define MAX_NICS 8 |