From 37b1f11fa6988348aca65d30624b29567a955deb Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sat, 23 Feb 2013 15:15:59 +0000 Subject: [PATCH] cleaned up serial mode handling and some other minor changes --- bochs/.bochsrc | 13 +++---- bochs/doc/docbook/user/user.dbk | 6 +-- bochs/doc/man/bochsrc.5 | 4 +- bochs/iodev/serial.cc | 68 +++++++++++++++++---------------- bochs/iodev/serial.h | 18 +++++---- bochs/iodev/serial_raw.cc | 36 ++++++++--------- bochs/iodev/serial_raw.h | 8 ++-- 7 files changed, 78 insertions(+), 75 deletions(-) diff --git a/bochs/.bochsrc b/bochs/.bochsrc index f0a48f6f5..84d30a765 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -663,10 +663,10 @@ debugger_log: - #======================================================================= # COM1, COM2, COM3, COM4: -# This defines a serial port (UART type 16550A). In the 'term' you can specify -# a device to use as com1. This can be a real serial line, or a pty. To use -# a pty (under X/Unix), create two windows (xterms, usually). One of them will -# run bochs, and the other will act as com1. Find out the tty the com1 +# This defines a serial port (UART type 16550A). In the 'term' mode you can +# specify a device to use as com1. This can be a real serial line, or a pty. +# To use a pty (under X/Unix), create two windows (xterms, usually). One of +# them will run bochs, and the other will act as com1. Find out the tty the com1 # window using the `tty' command, and use that as the `dev' parameter. # Then do `sleep 1000000' in the com1 window to keep the shell from # messing with things, and run bochs in the other window. Serial I/O to @@ -677,9 +677,8 @@ debugger_log: - # opens socket/named pipe and waits until a client application connects to it # before starting simulation. This mode is useful for remote debugging (e.g. # with gdb's "target remote host:port" command or windbg's command line option -# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for -# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP -# communication, pipe modes use duplex byte mode pipes. +# -k com:pipe,port=\\.\pipe\pipename). Socket modes use simple TCP communication, +# pipe modes use duplex byte mode pipes. # Other serial modes are 'null' (no input/output), 'file' (output to a file # specified as the 'dev' parameter), 'raw' (use the real serial port - under # construction for win32), 'mouse' (standard serial mouse - requires diff --git a/bochs/doc/docbook/user/user.dbk b/bochs/doc/docbook/user/user.dbk index 2bd24c7d1..2fc36bf3d 100644 --- a/bochs/doc/docbook/user/user.dbk +++ b/bochs/doc/docbook/user/user.dbk @@ -3861,10 +3861,8 @@ Examples: In server mode it opens socket/named pipe and waits until a client application connects to it before starting simulation. This mode is useful for remote debugging (e.g. with gdb's "target remote host:port" command or windbg's command - line option -k com:pipe,port=\\.\pipe\pipename). - - Note: 'socket' is a shorthand for 'socket-client', 'pipe' for 'pipe-client'. - Socket modes use simple TCP communication, pipe modes use duplex byte mode pipes. + line option -k com:pipe,port=\\.\pipe\pipename). Socket modes use simple TCP + communication, pipe modes use duplex byte mode pipes. Other serial modes are 'null' (no input/output), 'file' (output to a file diff --git a/bochs/doc/man/bochsrc.5 b/bochs/doc/man/bochsrc.5 index f251ff1cd..e39968b88 100644 --- a/bochs/doc/man/bochsrc.5 +++ b/bochs/doc/man/bochsrc.5 @@ -1,5 +1,5 @@ .\"Document Author: Timothy R. Butler - tbutler@uninetsolutions.com" -.TH bochsrc 5 "27 Jan 2013" "bochsrc" "The Bochs Project" +.TH bochsrc 5 "23 Feb 2013" "bochsrc" "The Bochs Project" .\"SKIP_SECTION" .SH NAME bochsrc \- Configuration file for Bochs. @@ -561,7 +561,7 @@ Examples: .TP .I "com1: \fP, \fIcom2: \fP, \fIcom3: \fPor \fIcom4:" -This defines a serial port (UART type 16550A). In the 'term' you can specify +This defines a serial port (UART type 16550A). In the 'term' mode you can specify a device to use as com1. This can be a real serial line, or a pty. To use a pty (under X/Unix), create two windows (xterms, usually). One of them will run bochs, and the other will act as com1. Find out the tty the com1 window diff --git a/bochs/iodev/serial.cc b/bochs/iodev/serial.cc index ecdc96697..dccd12934 100644 --- a/bochs/iodev/serial.cc +++ b/bochs/iodev/serial.cc @@ -61,15 +61,13 @@ void serial_init_options(void) static const char *serial_mode_list[] = { "null", "file", - "pipe", - "pipe-client", - "pipe-server", "term", "raw", "mouse", - "socket", "socket-client", "socket-server", + "pipe-client", + "pipe-server", NULL }; @@ -87,8 +85,8 @@ void serial_init_options(void) (i==0)?1 : 0); // only enable the first by default sprintf(label, "I/O mode of the serial device for COM%d", i+1); bx_param_enum_c *mode = new bx_param_enum_c(menu, "mode", label, - "The mode can be one these: 'null', 'file', 'pipe', 'term', 'raw', 'mouse', 'socket'", - serial_mode_list, 0, 0); + "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket*', 'pipe*'", + serial_mode_list, BX_SER_MODE_NULL, BX_SER_MODE_NULL); mode->set_ask_format("Choose I/O mode of the serial device [%s] "); sprintf(label, "Pathname of the serial device for COM%d", i+1); bx_param_filename_c *path = new bx_param_filename_c(menu, "dev", label, @@ -212,10 +210,12 @@ bx_serial_c::~bx_serial_c(void) delete [] BX_SER_THIS s[i].raw; #endif break; - case BX_SER_MODE_SOCKET: + case BX_SER_MODE_SOCKET_CLIENT: + case BX_SER_MODE_SOCKET_SERVER: if (BX_SER_THIS s[i].socket_id >= 0) closesocket(BX_SER_THIS s[i].socket_id); break; - case BX_SER_MODE_PIPE: + case BX_SER_MODE_PIPE_CLIENT: + case BX_SER_MODE_PIPE_SERVER: #ifdef WIN32 if (BX_SER_THIS s[i].pipe) CloseHandle(BX_SER_THIS s[i].pipe); @@ -353,15 +353,15 @@ bx_serial_c::init(void) } BX_SER_THIS s[i].io_mode = BX_SER_MODE_NULL; - const char *mode = SIM->get_param_enum("mode", base)->get_selected(); + Bit8u mode = SIM->get_param_enum("mode", base)->get(); const char *dev = SIM->get_param_string("dev", base)->getptr(); - if (!strcmp(mode, "file")) { + if (mode == BX_SER_MODE_FILE) { if (strlen(dev) > 0) { BX_SER_THIS s[i].output = fopen(dev, "wb"); if (BX_SER_THIS s[i].output) BX_SER_THIS s[i].io_mode = BX_SER_MODE_FILE; } - } else if (!strcmp(mode, "term")) { + } else if (mode == BX_SER_MODE_TERM) { #if defined(SERIAL_ENABLE) && !defined(WIN32) if (strlen(dev) > 0) { BX_SER_THIS s[i].tty_id = open(dev, O_RDWR|O_NONBLOCK,600); @@ -400,25 +400,26 @@ bx_serial_c::init(void) #else BX_PANIC(("serial terminal support not available")); #endif /* def SERIAL_ENABLE */ - } else if (!strcmp(mode, "raw")) { + } else if (mode == BX_SER_MODE_RAW) { #if USE_RAW_SERIAL BX_SER_THIS s[i].raw = new serial_raw(dev); BX_SER_THIS s[i].io_mode = BX_SER_MODE_RAW; #else BX_PANIC(("raw serial support not present")); #endif - } else if (!strcmp(mode, "mouse")) { + } else if (mode == BX_SER_MODE_MOUSE) { BX_SER_THIS s[i].io_mode = BX_SER_MODE_MOUSE; BX_SER_THIS mouse_port = i; BX_SER_THIS mouse_type = SIM->get_param_enum(BXPN_MOUSE_TYPE)->get(); - } else if (!strncmp(mode, "socket", 6)) { - BX_SER_THIS s[i].io_mode = BX_SER_MODE_SOCKET; + } else if ((mode == BX_SER_MODE_SOCKET_CLIENT) || + (mode == BX_SER_MODE_SOCKET_SERVER)) { + BX_SER_THIS s[i].io_mode = mode; struct sockaddr_in sin; struct hostent *hp; char host[BX_PATHNAME_LEN]; int port; SOCKET socket; - bx_bool server = !strcmp(mode, "socket-server"); + bx_bool server = (mode == BX_SER_MODE_SOCKET_SERVER); #if defined(WIN32) static bx_bool winsock_init = false; @@ -487,13 +488,14 @@ bx_serial_c::init(void) if (socket > 0) BX_INFO(("com%d - inet %s - socket_id: %d, ip:%s, port:%d", i+1, server ? "server" : "client", socket, host, port)); - } else if (!strncmp(mode, "pipe", 4)) { + } else if ((mode == BX_SER_MODE_PIPE_CLIENT) || + (mode == BX_SER_MODE_PIPE_SERVER)) { if (strlen(dev) > 0) { + bx_bool server = (mode == BX_SER_MODE_PIPE_SERVER); #ifdef WIN32 - bx_bool server = !strcmp(mode, "pipe-server"); HANDLE pipe; - BX_SER_THIS s[i].io_mode = BX_SER_MODE_PIPE; + BX_SER_THIS s[i].io_mode = mode; // server mode if (server) { @@ -526,11 +528,11 @@ bx_serial_c::init(void) if (pipe != INVALID_HANDLE_VALUE) BX_SER_THIS s[i].pipe = pipe; #else - BX_PANIC(("support for serial mode '%s' not available", mode)); + BX_PANIC(("support for serial mode 'pipe-%s' not available", server?"server":"client")); #endif } - } else if (strcmp(mode, "null")) { - BX_PANIC(("unknown serial i/o mode '%s'", mode)); + } else if (mode != BX_SER_MODE_NULL) { + BX_PANIC(("unknown serial i/o mode %d", mode)); } // simulate device connected if (BX_SER_THIS s[i].io_mode != BX_SER_MODE_RAW) { @@ -1201,8 +1203,7 @@ void bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len) BX_SER_THIS s[port].line_status.framing_error = 1; rx_fifo_enq(port, 0x00); } - } - else { + } else { /* transition to normal mode */ #if USE_RAW_SERIAL if (BX_SER_THIS s[port].io_mode == BX_SER_MODE_RAW) { @@ -1269,9 +1270,7 @@ void bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len) BX_SER_THIS s[port].raw->set_modem_control(value & 0x03); } #endif - } - else - { + } else { /* simulate device connected */ BX_SER_THIS s[port].modem_status.cts = 1; BX_SER_THIS s[port].modem_status.dsr = 1; @@ -1397,7 +1396,8 @@ void bx_serial_c::tx_timer(void) case BX_SER_MODE_MOUSE: BX_INFO(("com%d: write to mouse ignored: 0x%02x", port+1, BX_SER_THIS s[port].tsrbuffer)); break; - case BX_SER_MODE_SOCKET: + case BX_SER_MODE_SOCKET_CLIENT: + case BX_SER_MODE_SOCKET_SERVER: if (BX_SER_THIS s[port].socket_id >= 0) { #ifdef WIN32 BX_INFO(("attempting to write win32 : %c", BX_SER_THIS s[port].tsrbuffer)); @@ -1407,8 +1407,10 @@ void bx_serial_c::tx_timer(void) ::write(BX_SER_THIS s[port].socket_id, (bx_ptr_t) & BX_SER_THIS s[port].tsrbuffer, 1); #endif - } - case BX_SER_MODE_PIPE: + } + break; + case BX_SER_MODE_PIPE_CLIENT: + case BX_SER_MODE_PIPE_SERVER: #ifdef WIN32 if (BX_SER_THIS s[port].pipe) { DWORD written; @@ -1490,7 +1492,8 @@ void bx_serial_c::rx_timer(void) if ((BX_SER_THIS s[port].line_status.rxdata_ready == 0) || (BX_SER_THIS s[port].fifo_cntl.enable)) { switch (BX_SER_THIS s[port].io_mode) { - case BX_SER_MODE_SOCKET: + case BX_SER_MODE_SOCKET_CLIENT: + case BX_SER_MODE_SOCKET_SERVER: #if BX_HAVE_SELECT && defined(SERIAL_ENABLE) if (BX_SER_THIS s[port].line_status.rxdata_ready == 0) { tval.tv_sec = 0; @@ -1573,7 +1576,8 @@ void bx_serial_c::rx_timer(void) data_ready = 1; } break; - case BX_SER_MODE_PIPE: + case BX_SER_MODE_PIPE_CLIENT: + case BX_SER_MODE_PIPE_SERVER: #ifdef WIN32 DWORD avail = 0; if (BX_SER_THIS s[port].pipe && diff --git a/bochs/iodev/serial.h b/bochs/iodev/serial.h index 012e8f2bd..54e9dfde9 100644 --- a/bochs/iodev/serial.h +++ b/bochs/iodev/serial.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2004-2009 The Bochs Project +// Copyright (C) 2004-2013 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -63,13 +63,15 @@ extern "C" { #define BX_SER_MSR 6 #define BX_SER_SCR 7 -#define BX_SER_MODE_NULL 0 -#define BX_SER_MODE_FILE 1 -#define BX_SER_MODE_TERM 2 -#define BX_SER_MODE_RAW 3 -#define BX_SER_MODE_MOUSE 4 -#define BX_SER_MODE_SOCKET 5 -#define BX_SER_MODE_PIPE 6 +#define BX_SER_MODE_NULL 0 +#define BX_SER_MODE_FILE 1 +#define BX_SER_MODE_TERM 2 +#define BX_SER_MODE_RAW 3 +#define BX_SER_MODE_MOUSE 4 +#define BX_SER_MODE_SOCKET_CLIENT 5 +#define BX_SER_MODE_SOCKET_SERVER 6 +#define BX_SER_MODE_PIPE_CLIENT 7 +#define BX_SER_MODE_PIPE_SERVER 8 enum { BX_SER_INT_IER, diff --git a/bochs/iodev/serial_raw.cc b/bochs/iodev/serial_raw.cc index da495c943..9aac10192 100644 --- a/bochs/iodev/serial_raw.cc +++ b/bochs/iodev/serial_raw.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2004 The Bochs Project +// Copyright (C) 2004-2013 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -107,7 +107,7 @@ serial_raw::~serial_raw(void) void serial_raw::set_baudrate(int rate) { - BX_DEBUG (("set_baudrate %d", rate)); + BX_DEBUG(("set_baudrate %d", rate)); #ifdef WIN32 switch (rate) { case 110: dcb.BaudRate = CBR_110; break; @@ -129,7 +129,7 @@ void serial_raw::set_baudrate(int rate) void serial_raw::set_data_bits(int val) { - BX_DEBUG (("set data bits (%d)", val)); + BX_DEBUG(("set data bits (%d)", val)); #ifdef WIN32 dcb.ByteSize = val; DCBchanged = TRUE; @@ -138,7 +138,7 @@ void serial_raw::set_data_bits(int val) void serial_raw::set_stop_bits(int val) { - BX_DEBUG (("set stop bits (%d)", val)); + BX_DEBUG(("set stop bits (%d)", val)); #ifdef WIN32 if (val == 1) { dcb.StopBits = ONESTOPBIT; @@ -153,26 +153,26 @@ void serial_raw::set_stop_bits(int val) void serial_raw::set_parity_mode(int mode) { - BX_DEBUG (("set parity mode %d", mode)); + BX_DEBUG(("set parity mode %d", mode)); #ifdef WIN32 switch (mode) { - case 0: + case P_NONE: dcb.fParity = FALSE; dcb.Parity = NOPARITY; break; - case 1: + case P_ODD: dcb.fParity = TRUE; dcb.Parity = ODDPARITY; break; - case 2: + case P_EVEN: dcb.fParity = TRUE; dcb.Parity = EVENPARITY; break; - case 3: + case P_HIGH: dcb.fParity = TRUE; dcb.Parity = MARKPARITY; break; - case 4: + case P_LOW: dcb.fParity = TRUE; dcb.Parity = SPACEPARITY; break; @@ -183,7 +183,7 @@ void serial_raw::set_parity_mode(int mode) void serial_raw::set_break(int mode) { - BX_DEBUG (("set break %s", mode?"on":"off")); + BX_DEBUG(("set break %s", mode?"on":"off")); #ifdef WIN32 if (mode) { SetCommBreak(hCOM); @@ -195,7 +195,7 @@ void serial_raw::set_break(int mode) void serial_raw::set_modem_control(int ctrl) { - BX_DEBUG (("set modem control 0x%02x", ctrl)); + BX_DEBUG(("set modem control 0x%02x", ctrl)); #ifdef WIN32 EscapeCommFunction(hCOM, (ctrl & 0x01)?SETDTR:CLRDTR); EscapeCommFunction(hCOM, (ctrl & 0x02)?SETRTS:CLRRTS); @@ -209,7 +209,7 @@ int serial_raw::get_modem_status() #ifdef WIN32 status = MSR_value; #endif - BX_DEBUG (("get modem status returns 0x%02x", status)); + BX_DEBUG(("get modem status returns 0x%02x", status)); return status; } @@ -239,7 +239,7 @@ void serial_raw::transmit(Bit8u byte) OVERLAPPED tx_ovl; #endif - BX_DEBUG (("transmit %d", byte)); + BX_DEBUG(("transmit %d", byte)); if (present) { #ifdef WIN32 if (DCBchanged) { @@ -265,7 +265,7 @@ void serial_raw::transmit(Bit8u byte) bx_bool serial_raw::ready_transmit() { - BX_DEBUG (("ready_transmit returning %d", present)); + BX_DEBUG(("ready_transmit returning %d", present)); return present; } @@ -277,7 +277,7 @@ bx_bool serial_raw::ready_receive() SetEvent(rx_ovl.hEvent); } #endif - BX_DEBUG (("ready_receive returning %d", (rxdata_count > 0))); + BX_DEBUG(("ready_receive returning %d", (rxdata_count > 0))); return (rxdata_count > 0); } @@ -327,11 +327,11 @@ int serial_raw::receive() } return data; #else - BX_DEBUG (("receive returning 'A'")); + BX_DEBUG(("receive returning 'A'")); return (int)'A'; #endif } else { - BX_DEBUG (("receive returning 'A'")); + BX_DEBUG(("receive returning 'A'")); return (int)'A'; } } diff --git a/bochs/iodev/serial_raw.h b/bochs/iodev/serial_raw.h index 32c155a47..d044a5820 100644 --- a/bochs/iodev/serial_raw.h +++ b/bochs/iodev/serial_raw.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2004 The Bochs Project +// Copyright (C) 2004-2013 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -56,8 +56,8 @@ public: serial_raw(const char *devname); virtual ~serial_raw(); void set_baudrate(int rate); - void set_data_bits(int); - void set_stop_bits(int); + void set_data_bits(int val); + void set_stop_bits(int val); void set_parity_mode(int mode); void set_break(int mode); void set_modem_control(int ctrl); @@ -65,7 +65,7 @@ public: void transmit(Bit8u byte); bx_bool ready_transmit(); bx_bool ready_receive(); - int receive (); + int receive(); #ifdef WIN32_RECEIVE_RAW void serial_thread(); #endif