summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mvme162/consolex
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-08-01 18:12:11 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-08-01 18:12:11 +0000
commit9deb5b8b2822eb49c7a31d35d37d9b59dcd6555c (patch)
tree2797615f5f5eab05772d2bb807ba95e0d632481b /c/src/lib/libbsp/m68k/mvme162/consolex
parentMerged very large and much appreciated patch from Chris Johns (diff)
downloadrtems-9deb5b8b2822eb49c7a31d35d37d9b59dcd6555c.tar.bz2
Katsutoshi Shibuya (shibuya@mxb.meshnet.or.jp)of BU-Denken Co., Ltd.
(Sapporo, Japan) submitted the extended console driver for the MVME162LX BSP and the POSIX tcsetattr() and tcgetattr() routines. This device driver supports four serial ports, cooked IO, and provides a portable base for Zilog 8530 based console drivers.
Diffstat (limited to 'c/src/lib/libbsp/m68k/mvme162/consolex')
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in54
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/README97
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c75
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c786
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h93
5 files changed, 1105 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in b/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in
new file mode 100644
index 0000000000..0c45147de4
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/Makefile.in
@@ -0,0 +1,54 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH=@srcdir@
+
+PGM=${ARCH}/consolex.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=consolex
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=consolex
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
+ $(INSTALL) -m 444 $(H_FILES) ${PROJECT_RELEASE}/include
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/README b/c/src/lib/libbsp/m68k/mvme162/consolex/README
new file mode 100644
index 0000000000..719ed245eb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/README
@@ -0,0 +1,97 @@
+#
+# $Id$
+#
+
+This driver was submitted by Katsutoshi Shibuya <shibuya@mxb.meshnet.or.jp>.
+
+Configuration
+-------------
+The application can choose this driver by using "CONSOLEX_DRIVER_TABLE_ENTRY"
+in the driver table definition, in place of "CONSOLE_DRIVER_TABLE_ENTRY".
+See consolex/cTest.c for an example and consolex/README for more information.
+
+Programmatic Usage
+------------------
+
+- You can open 9 devices; console tty00, tty01, tty02, tty03,
+ rtty00, rtty01, rtty02, rtty03
+ tty00, rtty00 and console correspond to port#1 of MVME162LX,
+ tty01 and rtty01 correspond to port#2, and so on.
+- tty0x are "cooked" devices. They support following flags on termios
+ definition;
+ ISTRIP, INLCR, IGNCR, ICRNL, IUCLC, OLCUC, ONLCR, OCRNL, ICANON, ECHO,
+ CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
+- rtty0x are "raw" devices. They support following flags on termios
+ definition;
+ CBAUD, B38400, B19200, B9600, CSIZE, CS8, CS7, PARENB, PARODD, CSTOPB,
+- The default parameter is;
+ B38400, CS8, ICRNL, ONLCR, ICANON, ECHO
+ (but all flags except B38400 and CS8 will be ignored on raw device.)
+- All devices support O_NDELAY (non blocking read/write) mode operation.
+ (Non-blocking cooked mode output is valid, but will not work fine.)
+ (Non-blocking cooked mode input with ECHO flag may be blocked while sending
+ echoed character.)
+- All devices support hardware flow control by CTS/RTS.
+ (There is no way to disable it. There are no supports for soft flow control.)
+- The application can use tcgetattr or ioctl to obtain the parameters of the
+ device into struct termios.
+- The application can use tcsetattr or ioctl to set the parameters of the
+ device within the struct temios. The action argument (2nd arg) of the
+ tcsetattr must be TCSANOW.
+- On opening the device, the driver activate DTR line. On closing the device,
+ the driver deactivate DTR line.
+ If 2 or more device opening occures at the same time on the same port, only
+ the first open procedure activates DTR line, and only the last close
+ procedure deactivate it.
+- There are no device locking mechanisms. Application can open same device
+ several times.
+ But 2 simultanious reading operation on the same port will cause unexpected
+ result.
+
+Porting Notes
+-------------
+- This code can be used for any Zilog SCC based board.
+ Change the time constant parameters and SCC register base addresses.
+
+- This code is well separated into "device depended part" and "device
+ independed part".
+ They can use device independed part for any other board. The device
+ independed part requires following functions;
+
+ void SCCInitialize();
+ Initialize hardware.
+ rtems_boolean SCCGetOne(int port, char *ch);
+ Get one character from port. If no character is in the receiver buffer,
+ this function returns FALSE, otherwise TRUE.
+ char SCCGetOneBlocked(int port);
+ Get one character from port. If no character is in the receiver buffer,
+ wait it passing the CPU to the other task.
+ rtems_boolean SCCSendOne(int port, char ch);
+ Send one character via port. If the transmitter is not ready, this function
+ returns FALSE, otherwise TRUE.
+ void SCCSendOneBlocked(int port, char ch);
+ Send one character via port. Wait until the transmitter is ready, passing
+ the CPU to the other task.
+ unsigned32 SCCSetAttributes(int port, struct termios *tm);
+ Set device attribute according to the information in the struct termios.
+ c_cflags parameter (baud, parity, stopbits and code size) will be checked.
+ On the successful completion, this function should return 0.
+ unsigned32 SCCGetAttributes(int port, struct termios *tm);
+ Get device attribute according into the struct termios.
+ c_cflags parameter (baud, parity, stopbits and code size) will be set.
+ On the successful completion, this function should return 0.
+ void SCCSetDTR(port);
+ Activate DTR line.
+ void SCCResetDTR(port);
+ Deactivate DTR line.
+ void SCCSetRTS(port);
+ Activate RTS line.
+ void SCCResetRTS(port);
+ Deactivate RTS line.
+ int SCCGetCTS(port);
+ Return non zero when CTS line is activated.
+
+- If you don't want console port, undefine "CONSOLEPORT".
+
+- This code does not use ESCC feature; i.e. does not read register #4/#5/#14
+
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c b/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c
new file mode 100644
index 0000000000..899703892d
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/cTest.c
@@ -0,0 +1,75 @@
+/*
+ * Test program for consolex.
+ *
+ * NOTE: This program must be put together as an executable. :)
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <consolex.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+
+#if ! defined(O_NDELAY)
+# if defined(solaris2)
+# define O_NDELAY O_NONBLOCK
+# elif defined(RTEMS_NEWLIB)
+# define O_NDELAY _FNBIO
+# endif
+#endif
+
+rtems_driver_address_table Device_drivers[] = {
+ CONSOLEX_DRIVER_TABLE_ENTRY
+};
+
+rtems_task Init(rtems_task_argument arg)
+{
+ char buf[128];
+ int fd;
+ struct termios t;
+
+ printf("Console test.\n");
+
+ if((fd = open("/dev/tty00",O_RDWR)) < 0){
+ printf("Can't open device.\n");
+ return;
+ }
+ tcgetattr(fd,&t);
+ t.c_cflag = B9600|CS8;
+ tcsetattr(fd,TCSANOW,&t);
+ printf("iflag=%07o, oflag=%07o, cflag=%07o, lflag=%07o\n",
+ t.c_iflag,t.c_oflag,t.c_cflag,t.c_lflag);
+
+ do{
+ write(fd,"Your name? ",11);
+ read(fd,buf,sizeof(buf));
+ write(fd,"Hi ",3);
+ write(fd,buf,strlen(buf));
+ }while(*buf != '!');
+
+ close(fd);
+
+ printf("Done.\n");
+
+ exit(0);
+}
+
+#define CONFIGURE_INIT
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
+#include <confdefs.h>
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c
new file mode 100644
index 0000000000..c868954d12
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.c
@@ -0,0 +1,786 @@
+/*
+ * This file contains the MVME162LX extended console IO package.
+ *
+ * This file was created originally by
+ * On-Line Applications Research Corporation (OAR)
+ * and modified by:
+ *
+ * Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
+ *
+ * featuring support of:
+ *
+ * - Multi-SCC chip handling
+ * - Non-blocking I/O (O_NDELAY flag in libc)
+ * - Raw mode device (no CR/LF detection)
+ * - RTS/CTS flow control
+ *
+ * REMARKS: This routine requires multiple interrupt vectors
+ * from SCC_VECTOR (normaly 0x40)
+ * to SCC_VECTOR+(number of SCC chips)
+ *
+ * The original copyright follows;
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
+ * EISCAT Scientific Association. M.Savitski
+ *
+ * This material is a part of the MVME162 Board Support Package
+ * for the RTEMS executive. Its licensing policies are those of the
+ * RTEMS above.
+ *
+ */
+
+#define M162_INIT
+
+#include "consolex.h"
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define NPORTS 4 /* Number of ports */
+#define DEVICEPREFIX "tty"
+#define RAWDEVICEPREFIX "rtty"
+#define CONSOLEPORT 0 /* port# of console:
+ undef this if you do not want /dev/console */
+#define READRETRY 1 /* Maximum retry count for read one char */
+#define WRITERETRY 8 /* Maximum retry count for write one char */
+
+#define PORTFROM 0 /* for debug */
+
+static unsigned char opencount[NPORTS];
+
+/***********************************************************************
+ Ring buffer for device
+ ***********************************************************************/
+
+#define QUEUE_LENGTH 128 /* Must be 2^n number */
+
+typedef struct {
+ char buffer[QUEUE_LENGTH];
+ volatile int head;
+ volatile int tail;
+} ReceiverBuffer;
+
+#define ReceiverBufferInitialize( _buffer ) \
+ do { \
+ (_buffer)->head = (_buffer)->tail = 0; \
+ } while ( 0 )
+
+#define ReceiverBufferIsEmpty( _buffer ) \
+ ( (_buffer)->tail == (_buffer)->head )
+
+#define ReceiverBufferIsNearEmpty( _buffer ) \
+ ( (_buffer)->tail == (((_buffer)->head + 3) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferIsFull( _buffer ) \
+ ( (_buffer)->head == (((_buffer)->tail + 1) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferIsNearFull( _buffer ) \
+ ( (_buffer)->head == (((_buffer)->tail + 3) & (QUEUE_LENGTH-1)) )
+
+#define ReceiverBufferAdd( _buffer, _ch ) \
+ do { \
+ rtems_unsigned32 isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->tail = ((_buffer)->tail+1) & (QUEUE_LENGTH-1); \
+ (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+#define ReceiverBufferRemove( _buffer, _ch ) \
+ do { \
+ rtems_unsigned32 isrlevel; \
+ \
+ rtems_interrupt_disable( isrlevel ); \
+ (_buffer)->head = ((_buffer)->head+1) & (QUEUE_LENGTH-1); \
+ (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
+ rtems_interrupt_enable( isrlevel ); \
+ } while ( 0 )
+
+
+/***********************************************************************
+ DEVICE DEPENDED PART
+ ***********************************************************************/
+
+
+/* Time constant parameters
+ CAUTION: These parameters are for MVME162LX-213 board.
+ */
+
+#define TC38400 0x0006
+#define TC19200 0x000e
+#define TC9600 0x001e
+
+/* Re-defining SCC register control macros
+ to support Multi SCC chips */
+
+#undef scc
+static scc_regs *scc[NPORTS] = {
+ ((scc_regs * const) 0xFFF45004),
+ ((scc_regs * const) 0xFFF45000),
+ ((scc_regs * const) 0xFFF45804),
+ ((scc_regs * const) 0xFFF45800)
+};
+
+#undef ZWRITE0
+#define ZWRITE0(port, v) (scc[port]->csr = (unsigned char)(v))
+#undef ZREAD0
+#define ZREAD0(port) (scc[port]->csr)
+
+#undef ZREAD
+#define ZREAD(port, n) (ZWRITE0(port, n), (scc[port]->csr))
+#undef ZREADD
+#define ZREADD(port) (scc[port]->csr=0x08, scc[port]->csr )
+
+#undef ZWRITE
+#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
+#undef ZWRITED
+#define ZWRITED(port, v) (scc[port]->csr = 0x08, \
+ scc[port]->csr = (unsigned char)(v))
+
+static ReceiverBuffer receiverBuffer[NPORTS];
+
+/*
+ * Control flags (DTR/DCD/RTS/CTS)
+ */
+
+static unsigned char wr4[NPORTS];
+static unsigned char wr5[NPORTS];
+#define SCCSetDTR(port) ZWRITE(port, 5, (wr5[port] |= 0x80))
+#define SCCResetDTR(port) ZWRITE(port, 5, (wr5[port] &= ~0x80))
+#define SCCSetRTS(port) ZWRITE(port, 5, (wr5[port] |= 0x02))
+#define SCCResetRTS(port) ZWRITE(port,5, (wr5[port] &= ~0x02))
+#define SCCGetDCD(port) (ZREAD0(port)&0x08)
+#define SCCGetCTS(port) (ZREAD0(port)&0x20)
+
+
+/*
+ * Interrupt handler for receiver interrupts
+ */
+
+static rtems_isr SCCReceiverISR(rtems_vector_number vector)
+{
+ register int ipend, port;
+
+ port = (vector-SCC_VECTOR)*2;
+ ZWRITE0(port, 0x38); /* reset highest IUS */
+
+ ipend = ZREAD(port, 3); /* read int pending from A side */
+
+ if(ipend == 0x04)
+ port++; /* channel B intr pending */
+ else if(ipend == 0x20)
+ ; /* channel A intr pending */
+ else
+ return;
+
+ ReceiverBufferAdd(&receiverBuffer[port], ZREADD(port));
+
+ if(ZREAD(port,1) & 0x70){ /* check error stat */
+ ZWRITE0(port, 0x30); /* reset error */
+ }
+
+ if(ReceiverBufferIsNearFull(&receiverBuffer[port]))
+ SCCResetRTS(port);
+}
+
+/*
+ * Initialize
+ */
+
+void SCCInitialize()
+{
+ int i;
+
+ for(i = PORTFROM; i < NPORTS; i+=2)
+ ZWRITE(i, 9,0xc0); /* Reset SCC Chip */
+
+ for(i = PORTFROM; i < NPORTS; i++){
+ ReceiverBufferInitialize(&(receiverBuffer[i]));
+ wr4[i] = 0x44;
+ ZWRITE(i, 4, wr4[i]); /* x16 clock, 1 stop, parity none */
+ ZWRITE(i, 1, 0); /* disable interrupts */
+ ZWRITE(i, 2, SCC_VECTOR+(i/2));
+ ZWRITE(i, 3, 0xc1); /* receiver enable, 8bits */
+ wr5[i] = 0x68;
+ ZWRITE(i, 5, wr5[i]); /* transmitter enable, 8bits, DTR&RTS off */
+ ZWRITE(i,14, 0); /* stop baudrate gen. */
+ ZWRITE(i,11,0x50); /* use baurate gen. */
+ ZWRITE(i,15, 1); /* Select WR7' */
+ ZWRITE(i, 7, 0); /* Disable all special interrupts */
+ ZWRITE(i,10, 0);
+ ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */
+ set_vector(SCCReceiverISR, SCC_VECTOR+(i/2), 1); /* install ISR */
+ ZWRITE(i, 9, 8); /* master interrupt enable */
+ ZWRITE(i,12,TC38400&0xff); /* set 38400 baud */
+ ZWRITE(i,13,TC38400>>8);
+ ZWRITE(i,14, 3); /* start baudrate gen. */
+ /* CAUTION: If your SCC use XTAL on RTxC,
+ write 1 */
+ }
+ mcchip->vector_base = 0;
+ mcchip->gen_control = 2; /* MIEN */
+ mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
+}
+
+/*
+ * Non-blocking char input
+ */
+
+rtems_boolean SCCGetOne(int port, char *ch)
+{
+ int retry = READRETRY;
+ while(ReceiverBufferIsEmpty(&receiverBuffer[port]))
+ if(--retry <= 0)
+ return FALSE;
+
+ ReceiverBufferRemove(&receiverBuffer[port],*ch);
+
+ if(ReceiverBufferIsNearEmpty(&receiverBuffer[port]))
+ SCCSetRTS(port);
+ return TRUE;
+}
+
+/*
+ * Blocking char input
+ */
+
+char SCCGetOneBlocked(int port)
+{
+ unsigned char tmp_char;
+
+ while (!SCCGetOne(port, &tmp_char))
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+ return tmp_char;
+}
+
+/*
+ * Non-blocking char input
+ * No longer supports XON/XOFF flow control.
+ */
+
+rtems_boolean SCCSendOne(int port, char ch)
+{
+ int retry = WRITERETRY;
+
+ if(!SCCGetCTS(port))
+ return FALSE;
+ while(!(ZREAD0(port) & TX_BUFFER_EMPTY))
+ if(--retry <= 0)
+ return FALSE;
+ ZWRITED(port, ch);
+ return TRUE;
+}
+
+
+/*
+ * Blocking char output
+ * No longer supports XON/XOFF flow control.
+ */
+
+void SCCSendOneBlocked(int port, char ch)
+{
+ while(!SCCSendOne(port, ch))
+ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+}
+
+/*
+ * Set parameters for transmission
+ */
+
+unsigned32 SCCSetAttributes(int port, struct termios *t)
+{
+ unsigned char wr3;
+
+ ZWRITE(port,1,0); /* Disable interrupt */
+ ZWRITE(port,3,0); /* Disable receiver */
+ /* Baud */
+ switch(t->c_cflag & CBAUD){
+ case B38400:
+ ZWRITE(port,12,TC38400&0xff);
+ ZWRITE(port,13,TC38400>>8);
+ break;
+ case B19200:
+ ZWRITE(port,12,TC19200&0xff);
+ ZWRITE(port,13,TC19200>>8);
+ break;
+ case B9600:
+ ZWRITE(port,12,TC9600&0xff);
+ ZWRITE(port,13,TC9600>>8);
+ break;
+ }
+
+ /* Code size */
+ wr5[port] &= 0x8f;
+ wr3 = 0; /* receiver control */
+ switch(t->c_cflag & CSIZE){
+ case CS8:
+ wr5[port] |= 0x60;
+ wr3 |= 0xc0;
+ break;
+ case CS7:
+ wr5[port] |= 0x20;
+ wr3 |= 0x40;
+ break;
+ }
+
+ /* Parity */
+ wr4[port] &= 0xf0;
+ if(t->c_cflag & PARENB)
+ wr4[port] |= 0x01;
+ if(!(t->c_cflag & PARODD))
+ wr4[port] |= 0x02;
+ /* ZWRITE(port,4,wr4[port]);*/
+
+ /* Stop bits */
+ /* wr4[port] = ZREAD(port,4) & 0xfc;*/
+ if(t->c_cflag & CSTOPB)
+ wr4[port] |= 0x0c;
+ else
+ wr4[port] |= 0x04;
+
+ ZWRITE(port,4,wr4[port]); /* TxRx parameters */
+ ZWRITE(port,5,wr5[port]); /* Transmission parameters */
+ ZWRITE(port,3,wr3|0x01); /* Enable receiver */
+ ZWRITE(port,1,0x10); /* Enable interrupt */
+
+ return 0;
+}
+
+/*
+ * Get parameters for transmission
+ */
+
+unsigned32 SCCGetAttributes(int port, struct termios *t)
+{
+ unsigned32 b;
+
+ t->c_cflag = 0;
+
+ /* Baud */
+ b = ZREAD(port,13);
+ b <<= 8;
+ b |= ZREAD(port,12);
+ switch(b){
+ case TC38400:
+ t->c_cflag |= B38400;
+ break;
+ case TC19200:
+ t->c_cflag |= B19200;
+ break;
+ case TC9600:
+ t->c_cflag |= B9600;
+ break;
+ }
+
+ /* Code size */
+ /* wr = ZREAD(port,5);*/
+ t->c_cflag &= ~CSIZE;
+ switch(wr5[port]&0x60){
+ case 0x60:
+ t->c_cflag |= CS8;
+ break;
+ case 0x20:
+ t->c_cflag |= CS7;
+ break;
+ }
+
+ /* Parity */
+ /* wr = ZREAD(port,4);*/
+ if(wr4[port] & 0x01)
+ t->c_cflag |= PARENB;
+ else
+ t->c_cflag &= ~PARENB;
+ if(wr4[port] & 0x02)
+ t->c_cflag &= ~PARODD;
+ else
+ t->c_cflag |= PARODD;
+
+ /* Stop bits */
+ /* wr = ZREAD(port,4);*/
+ if((wr4[port]&0xc0) == 0xc0)
+ t->c_cflag |= CSTOPB;
+ else
+ t->c_cflag &= ~CSTOPB;
+
+ return 0;
+}
+
+/***********************************************************************
+ DEVICE INDEPENDED PART
+ ***********************************************************************/
+
+#define LOCAL_ISTRIP 0x0001
+#define LOCAL_INLCR 0x0002
+#define LOCAL_IGNCR 0x0004
+#define LOCAL_ICRNL 0x0008
+#define LOCAL_IUCLC 0x0010
+#define LOCAL_OLCUC 0x0020
+#define LOCAL_ONLCR 0x0040
+#define LOCAL_OCRNL 0x0080
+#define LOCAL_ICANON 0x0100
+#define LOCAL_ECHO 0x0200
+
+/*
+ * Device initialize entry point
+ */
+
+rtems_device_driver consolex_initialize(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_status_code status;
+ char devname[16];
+ int i;
+
+ SCCInitialize();
+
+#ifdef CONSOLEPORT
+ status = rtems_io_register_name("/dev/console",major,
+ (rtems_device_minor_number) CONSOLEPORT);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+#endif
+
+ for(i = PORTFROM; i < NPORTS; i++){
+ /* Register cooked ttys */
+ sprintf(devname,"/dev/%s%02d",DEVICEPREFIX,i);
+ status = rtems_io_register_name(strdup(devname),major,
+ (rtems_device_minor_number) i);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ /* Register raw ttys */
+ sprintf(devname,"/dev/%s%02d",RAWDEVICEPREFIX,i);
+ status = rtems_io_register_name(strdup(devname),major,
+ (rtems_device_minor_number) i+NPORTS);
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+ }
+
+ for(i = 0; i < NPORTS; i++){
+ opencount[i] = 0;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Open entry point
+ */
+
+rtems_device_driver consolex_open(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_open_close_args_t *openargs = (rtems_libio_open_close_args_t *) arg;
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ if(opencount[minor]++ == 0){
+ /* first open */
+ SCCSetDTR(minor);
+ SCCSetRTS(minor);
+ }
+ openargs->iop->data0 = LOCAL_ICRNL|LOCAL_ONLCR|LOCAL_ICANON|LOCAL_ECHO;
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * Close entry point
+ */
+
+rtems_device_driver consolex_close(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ if(--(opencount[minor]) == 0){
+ /* closed all */
+ SCCResetRTS(minor);
+ SCCResetDTR(minor);
+ }
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
+ * read bytes from the serial port.
+ */
+
+rtems_device_driver consolex_read_raw(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking read */
+ while(count){
+ if(!SCCGetOne(minor,buffer))
+ break;
+ buffer++;
+ count--;
+ }
+ }else{
+ /* Blocking read */
+ while(count){
+ *buffer = SCCGetOneBlocked(minor);
+ buffer++;
+ count--;
+ }
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver consolex_read(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+ unsigned32 mode;
+
+ if(minor >= NPORTS)
+ return consolex_read_raw(major,minor-NPORTS,arg);
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+ mode = rw_args->iop->data0;
+
+ /* Cooked read */
+ while(count){
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking read */
+ if(!SCCGetOne(minor,buffer))
+ break;
+ }else{
+ /* Blocking read */
+ *buffer = SCCGetOneBlocked(minor);
+ }
+ if((mode&LOCAL_ICANON) && (*buffer == '\b')){
+ if(buffer > (char *)(rw_args->buffer)){
+ buffer--;
+ count++;
+ if(mode&LOCAL_ECHO){
+ SCCSendOneBlocked(minor,'\b');
+ SCCSendOneBlocked(minor,' ');
+ SCCSendOneBlocked(minor,'\b');
+ }
+ }
+ continue;
+ }
+ if((mode&LOCAL_IGNCR) && (*buffer == '\r'))
+ continue;
+ if((mode&LOCAL_INLCR) && (*buffer == '\n'))
+ *buffer = '\r';
+ if((mode&LOCAL_ICRNL) && (*buffer == '\r'))
+ *buffer = '\n';
+ if((mode&LOCAL_IUCLC) && isupper(*buffer))
+ *buffer = tolower(*buffer);
+ if(mode&LOCAL_ISTRIP)
+ *buffer &= 0x7f;
+ if(mode&LOCAL_ECHO){
+ /* Caution: Echo back is blocking output */
+ SCCSendOneBlocked(minor,*buffer);
+ }
+ if((mode&LOCAL_ICANON) && (*buffer == '\n')){
+ buffer++;
+ count--;
+ if(count)
+ *buffer = 0;
+ if((mode&LOCAL_ECHO)&&(mode&LOCAL_ONLCR))
+ SCCSendOneBlocked(minor,'\r');
+ break; /* finish reading */
+ }
+ buffer++;
+ count--;
+ }
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+/*
+ * write bytes to the serial port.
+ */
+
+rtems_device_driver consolex_write_raw(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ while(count){
+ if(!SCCSendOne(minor,*buffer))
+ break;
+ buffer++;
+ count--;
+ }
+ }else{
+ /* Blocking write */
+ while(count){
+ SCCSendOneBlocked(minor,*buffer);
+ buffer++;
+ count--;
+ }
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver consolex_write(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
+ char *buffer;
+ int count;
+ char ch;
+ unsigned32 mode;
+
+ if(minor >= NPORTS)
+ return consolex_write_raw(major,minor-NPORTS,arg);
+
+ buffer = rw_args->buffer;
+ count = rw_args->count;
+ mode = rw_args->iop->data0;
+
+ /* Cooked write */
+ while(count){
+ ch = *buffer;
+ if((mode&LOCAL_ONLCR) && (ch == '\n')){ /* Output CRLF */
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ if(!SCCSendOne(minor,'\r'))
+ break;
+ }else{
+ SCCSendOneBlocked(minor,'\r');
+ }
+ }
+ if((mode&LOCAL_OCRNL) && (ch == '\r'))
+ ch = '\n';
+ if((mode&OLCUC) && (islower(ch)))
+ ch = toupper(ch);
+ if(rw_args->flags & LIBIO_FLAGS_NO_DELAY){
+ /* Non blocking write */
+ if(!SCCSendOne(minor,ch))
+ break;
+ }else{
+ SCCSendOneBlocked(minor,ch);
+ }
+ buffer++;
+ count--;
+ }
+
+ rw_args->bytes_moved = rw_args->count-count;
+ return count ? RTEMS_UNSATISFIED : RTEMS_SUCCESSFUL;
+}
+
+/*
+ * IO Control entry point
+ */
+
+rtems_device_driver consolex_control(rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg)
+{
+ rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
+ struct termios *tm = ioarg->buffer;
+ unsigned32 *mode = &(ioarg->iop->data0);
+
+ if(minor >= NPORTS)
+ minor -= NPORTS;
+ if(minor >= NPORTS)
+ return RTEMS_INVALID_NUMBER;
+
+ switch(ioarg->command){
+ case RTEMS_IO_GET_ATTRIBUTES:
+ tm->c_iflag = tm->c_oflag = tm->c_cflag = tm->c_lflag = 0;
+ if(*mode & LOCAL_ISTRIP)
+ tm->c_iflag |= ISTRIP;
+ if(*mode & LOCAL_INLCR)
+ tm->c_iflag |= INLCR;
+ if(*mode & LOCAL_IGNCR)
+ tm->c_iflag |= IGNCR;
+ if(*mode & LOCAL_ICRNL)
+ tm->c_iflag |= ICRNL;
+ if(*mode & LOCAL_IUCLC)
+ tm->c_iflag |= IUCLC;
+ if(*mode & LOCAL_OLCUC)
+ tm->c_oflag |= OLCUC;
+ if(*mode & LOCAL_ONLCR)
+ tm->c_oflag |= ONLCR;
+ if(*mode & LOCAL_OCRNL)
+ tm->c_oflag |= OCRNL;
+ if(*mode & LOCAL_ICANON)
+ tm->c_lflag |= ICANON;
+ if(*mode & LOCAL_ECHO)
+ tm->c_lflag |= ECHO;
+ ioarg->ioctl_return = SCCGetAttributes(minor,tm);
+ break;
+ case RTEMS_IO_SET_ATTRIBUTES:
+ *mode = 0;
+ if(tm->c_iflag & ISTRIP)
+ *mode |= LOCAL_ISTRIP;
+ if(tm->c_iflag & INLCR)
+ *mode |= LOCAL_INLCR;
+ if(tm->c_iflag & IGNCR)
+ *mode |= LOCAL_IGNCR;
+ if(tm->c_iflag & ICRNL)
+ *mode |= LOCAL_ICRNL;
+ if(tm->c_iflag & IUCLC)
+ *mode |= LOCAL_IUCLC;
+ if(tm->c_oflag & OLCUC)
+ *mode |= LOCAL_OLCUC;
+ if(tm->c_oflag & ONLCR)
+ *mode |= LOCAL_ONLCR;
+ if(tm->c_oflag & OCRNL)
+ *mode |= LOCAL_OCRNL;
+ if(tm->c_lflag & ICANON)
+ *mode |= LOCAL_ICANON;
+ if(tm->c_lflag & ECHO)
+ *mode |= LOCAL_ECHO;
+ ioarg->ioctl_return = SCCSetAttributes(minor,tm);
+ break;
+ default:
+ return RTEMS_NOT_DEFINED;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h
new file mode 100644
index 0000000000..b7ccb2a464
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mvme162/consolex/consolex.h
@@ -0,0 +1,93 @@
+/* consolex.h
+ *
+ * This file describes the Extended Console Device Driver
+ * This driver provides support for the standard C Library.
+ *
+ * This file was created originally by
+ * On-Line Applications Research Corporation (OAR)
+ * and modified by:
+ *
+ * Katsutoshi Shibuya - BU-Denken Co.,Ltd. - Sapporo, JAPAN
+ *
+ * featuring support of:
+ *
+ * - Multi-SCC chip handling
+ * - Non-blocking I/O (O_NDELAY flag in libc)
+ * - Raw mode device (no CR/LF detection)
+ * - RTS/CTS flow control
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ */
+
+#ifndef _CONSOLEX_DRIVER_h
+#define _CONSOLEX_DRIVER_h
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CONSOLEX_DRIVER_TABLE_ENTRY \
+ { consolex_initialize, consolex_open, consolex_close, \
+ consolex_read, consolex_write, consolex_control }
+
+rtems_device_driver consolex_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver consolex_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+/* Low level IO functions */
+void SCCInitialize();
+rtems_boolean SCCGetOne(int port, char *ch);
+char SCCGetOneBlocked(int port);
+rtems_boolean SCCSendOne(int port, char ch);
+void SCCSendOneBlocked(int port, char ch);
+unsigned32 SCCSetAttributes(int port, struct termios *t);
+unsigned32 SCCGetAttributes(int port, struct termios *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */