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 | 314 | |
315 | 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 | 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 | 323 | /* PC hardware initialisation */ |
321 | 324 | void pc_init(int ram_size, int vga_ram_size, int boot_device, |
322 | 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 | 474 | pic_init(); |
472 | 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 | 483 | if (pci_enabled) { |
477 | 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 | 200 | pic_init(); |
201 | 201 | |
202 | 202 | /* XXX: use Mac Serial port */ |
203 | - serial_init(0x3f8, 4, serial_hd); | |
203 | + serial_init(0x3f8, 4, serial_hds[0]); | |
204 | 204 | |
205 | 205 | for(i = 0; i < nb_nics; i++) { |
206 | 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 | 492 | pic_init(); |
493 | 493 | // pit = pit_init(0x40, 0); |
494 | 494 | |
495 | - serial_init(0x3f8, 4, serial_hd); | |
495 | + serial_init(0x3f8, 4, serial_hds[0]); | |
496 | 496 | nb_nics1 = nb_nics; |
497 | 497 | if (nb_nics1 > NE2000_NB_MAX) |
498 | 498 | nb_nics1 = NE2000_NB_MAX; | ... | ... |
vl.c
... | ... | @@ -128,6 +128,7 @@ int graphic_width = 800; |
128 | 128 | int graphic_height = 600; |
129 | 129 | int graphic_depth = 15; |
130 | 130 | TextConsole *vga_console; |
131 | +CharDriverState *serial_hds[MAX_SERIAL_PORTS]; | |
131 | 132 | |
132 | 133 | /***********************************************************/ |
133 | 134 | /* x86 ISA bus support */ |
... | ... | @@ -1166,6 +1167,43 @@ static void stdio_read(void *opaque, const uint8_t *buf, int size) |
1166 | 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 | 1207 | CharDriverState *qemu_chr_open_stdio(void) |
1170 | 1208 | { |
1171 | 1209 | CharDriverState *chr; |
... | ... | @@ -1183,6 +1221,10 @@ CharDriverState *qemu_chr_open_stdio(void) |
1183 | 1221 | chr = qemu_chr_open_fd(0, 1); |
1184 | 1222 | } |
1185 | 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 | 1228 | return chr; |
1187 | 1229 | } |
1188 | 1230 | |
... | ... | @@ -1449,57 +1491,6 @@ static int net_fd_init(NetDriverState *nd, int fd) |
1449 | 1491 | /***********************************************************/ |
1450 | 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 | 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 | 1522 | { |
1532 | 1523 | if (cpu_signal_handler(host_signum, info, puc)) |
1533 | 1524 | return; |
1534 | - term_exit(); | |
1525 | + if (stdio_nb_clients > 0) | |
1526 | + term_exit(); | |
1535 | 1527 | abort(); |
1536 | 1528 | } |
1537 | 1529 | #endif |
... | ... | @@ -2568,8 +2560,9 @@ int main(int argc, char **argv) |
2568 | 2560 | const char *r, *optarg; |
2569 | 2561 | CharDriverState *monitor_hd; |
2570 | 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 | 2566 | #if !defined(CONFIG_SOFTMMU) |
2574 | 2567 | /* we never want that malloc() uses mmap() */ |
2575 | 2568 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
... | ... | @@ -2594,8 +2587,12 @@ int main(int argc, char **argv) |
2594 | 2587 | has_cdrom = 1; |
2595 | 2588 | cyls = heads = secs = 0; |
2596 | 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 | 2596 | nb_tun_fds = 0; |
2600 | 2597 | net_if_type = -1; |
2601 | 2598 | nb_nics = 1; |
... | ... | @@ -2674,7 +2671,7 @@ int main(int argc, char **argv) |
2674 | 2671 | break; |
2675 | 2672 | case QEMU_OPTION_nographic: |
2676 | 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 | 2675 | nographic = 1; |
2679 | 2676 | break; |
2680 | 2677 | case QEMU_OPTION_kernel: |
... | ... | @@ -2865,7 +2862,13 @@ int main(int argc, char **argv) |
2865 | 2862 | pstrcpy(monitor_device, sizeof(monitor_device), optarg); |
2866 | 2863 | break; |
2867 | 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 | 2872 | break; |
2870 | 2873 | } |
2871 | 2874 | } |
... | ... | @@ -3066,14 +3069,18 @@ int main(int argc, char **argv) |
3066 | 3069 | } |
3067 | 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 | 3085 | /* setup cpu signal handlers for MMU / self modifying code handling */ |
3079 | 3086 | #if !defined(CONFIG_SOFTMMU) |
... | ... | @@ -3142,11 +3149,9 @@ int main(int argc, char **argv) |
3142 | 3149 | } else { |
3143 | 3150 | printf("Waiting gdb connection on port %d\n", gdbstub_port); |
3144 | 3151 | } |
3145 | - term_init(); | |
3146 | 3152 | } else |
3147 | 3153 | #endif |
3148 | 3154 | { |
3149 | - term_init(); | |
3150 | 3155 | /* XXX: simplify init */ |
3151 | 3156 | read_passwords(); |
3152 | 3157 | if (start_emulation) { | ... | ... |
vl.h
... | ... | @@ -200,8 +200,6 @@ void qemu_chr_add_read_handler(CharDriverState *s, |
200 | 200 | IOReadHandler *fd_read, void *opaque); |
201 | 201 | void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event); |
202 | 202 | |
203 | -CharDriverState *serial_hd; | |
204 | - | |
205 | 203 | /* consoles */ |
206 | 204 | |
207 | 205 | typedef struct DisplayState DisplayState; |
... | ... | @@ -214,6 +212,12 @@ int is_active_console(TextConsole *s); |
214 | 212 | CharDriverState *text_console_init(DisplayState *ds); |
215 | 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 | 221 | /* network redirectors support */ |
218 | 222 | |
219 | 223 | #define MAX_NICS 8 | ... | ... |