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 | ... | ... |