summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mvme167
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-19 06:28:01 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:32 +0200
commitd7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch)
treecaa54b4229e86a68c84ab5961af34e087dce5302 /c/src/lib/libbsp/m68k/mvme167
parentbsps/powerpc: Move shared btimer support (diff)
downloadrtems-d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc.tar.bz2
bsps: Move console drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/m68k/mvme167')
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/console/console-recording.h572
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/console/console.c1676
3 files changed, 1 insertions, 2249 deletions
diff --git a/c/src/lib/libbsp/m68k/mvme167/Makefile.am b/c/src/lib/libbsp/m68k/mvme167/Makefile.am
index 1632a35b8b..ac80bf6014 100644
--- a/c/src/lib/libbsp/m68k/mvme167/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mvme167/Makefile.am
@@ -29,7 +29,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspreset-empty.c
# clock
librtemsbsp_a_SOURCES +=../../../../../../bsps/m68k/mvme167/clock/ckinit.c
# console
-librtemsbsp_a_SOURCES += console/console.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/console/console.c
# timer
librtemsbsp_a_SOURCES += timer/timer.c
librtemsbsp_a_SOURCES += timer/timerisr.S
diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h b/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h
deleted file mode 100644
index 4d8d3fc66c..0000000000
--- a/c/src/lib/libbsp/m68k/mvme167/console/console-recording.h
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (c) 2000, National Research Council of Canada
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-/* CD2401 CONSOLE DRIVER DEBUG INFO RECORDING */
-
-#ifdef CD2401_RECORD_DEBUG_INFO
-
-/* Control individual recording here. That way, we don't clutter console.c */
-#define CD2401_RECORD_WRITE
-#define CD2401_RECORD_TX_ISR
-#define CD2401_RECORD_RX_ISR
-#define CD2401_RECORD_RE_ISR
-#define CD2401_RECORD_MODEM_ISR
-#define CD2401_RECORD_SET_ATTRIBUTE
-#define CD2401_RECORD_FIRST_OPEN
-#define CD2401_RECORD_LAST_CLOSE
-#define CD2401_RECORD_START_REMOTE_TX
-#define CD2401_RECORD_STOP_REMOTE_TX
-#define CD2401_RECORD_DRAIN_OUTPUT
-#define CD2401_RECORD_DELAY
-
-/* Call the data recording functions */
-#ifdef CD2401_RECORD_WRITE
-#define CD2401_RECORD_WRITE_INFO( args ) cd2401_record_write_info args
-#else
-#define CD2401_RECORD_WRITE_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_TX_ISR
-#define CD2401_RECORD_TX_ISR_INFO( args ) cd2401_record_tx_isr_info args
-#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args ) cd2401_record_tx_isr_spurious_info args
-#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args ) cd2401_record_tx_isr_buserr_info args
-#else
-#define CD2401_RECORD_TX_ISR_INFO( args )
-#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args )
-#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_RX_ISR
-#define CD2401_RECORD_RX_ISR_INFO( args ) cd2401_record_rx_isr_info args
-#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args ) cd2401_record_rx_isr_spurious_info args
-#else
-#define CD2401_RECORD_RX_ISR_INFO( args )
-#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_RE_ISR
-#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args ) cd2401_record_re_isr_spurious_info args
-#else
-#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_MODEM_ISR
-#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args ) cd2401_record_modem_isr_spurious_info args
-#else
-#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_SET_ATTRIBUTES
-#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args ) cd2401_record_set_attributes_info args
-#else
-#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_FIRST_OPEN
-#define CD2401_RECORD_FIRST_OPEN_INFO( args ) cd2401_record_first_open_info args
-#else
-#define CD2401_RECORD_FIRST_OPEN_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_LAST_CLOSE
-#define CD2401_RECORD_LAST_CLOSE_INFO( args ) cd2401_record_last_close_info args
-#else
-#define CD2401_RECORD_LAST_CLOSE_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_START_REMOTE_TX
-#define CD2401_RECORD_START_REMOTE_TX_INFO( args ) cd2401_record_start_remote_tx_info args
-#else
-#define CD2401_RECORD_START_REMOTE_TX_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_STOP_REMOTE_TX
-#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args ) cd2401_record_stop_remote_tx_info args
-#else
-#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_DRAIN_OUTPUT
-#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args ) cd2401_record_drain_output_info args
-#else
-#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args )
-#endif
-
-#ifdef CD2401_RECORD_DELAY
-#define CD2401_RECORD_DELAY_INFO( args ) cd2401_record_delay_info args
-#else
-#define CD2401_RECORD_DELAY_INFO( args )
-#endif
-
-/* Define the data and the recording functions */
-#define CD2401_DEBUG_BUFFER_SIZE 256
-#define CD2401_DEBUG_CHAR_BUFSIZE 64
-#define CD2401_WRITE_INFO 1
-#define CD2401_TX_ISR_INFO 2
-#define CD2401_TX_ISR_SPURIOUS_INFO 3
-#define CD2401_TX_ISR_BUSERR_INFO 4
-#define CD2401_RX_ISR_INFO 5
-#define CD2401_RX_ISR_SPURIOUS_INFO 6
-#define CD2401_RE_ISR_SPURIOUS_INFO 7
-#define CD2401_MODEM_ISR_SPURIOUS_INFO 8
-#define CD2401_FIRST_OPEN_INFO 9
-#define CD2401_LAST_CLOSE_INFO 10
-#define CD2401_START_REMOTE_TX_INFO 11
-#define CD2401_STOP_REMOTE_TX_INFO 12
-#define CD2401_SET_ATTRIBUTE_INFO 13
-#define CD2401_DRAIN_OUTPUT_INFO 14
-#define CD2401_DELAY_INFO 15
-
-struct cd2401_debug_info {
- short discriminant;
- short record_size;
- union {
- struct cd2401_write_info {
- int length;
- char buffer[CD2401_DEBUG_CHAR_BUFSIZE];
- char dmabuf;
- } write_info;
- struct cd2401_tx_isr_info {
- unsigned char channel;
- unsigned char status;
- unsigned char initial_ier;
- unsigned char final_ier;
- uint8_t txEmpty;
- } tx_isr_info;
- struct cd2401_tx_isr_spurious_info {
- unsigned char channel;
- unsigned char status;
- unsigned char initial_ier;
- unsigned char final_ier;
- unsigned long spurdev;
- unsigned long spurcount;
- } tx_isr_spurious_info;
- struct cd2401_tx_isr_buserr_info {
- unsigned char channel;
- unsigned char status;
- unsigned char initial_ier;
- unsigned char buserr;
- unsigned long type;
- unsigned long addr;
- } tx_isr_buserr_info;
- struct cd2401_rx_isr_info {
- unsigned char channel;
- int length;
- char buffer[CD2401_DEBUG_CHAR_BUFSIZE];
- } rx_isr_info;
- struct cd2401_rx_isr_spurious_info {
- unsigned char channel;
- unsigned char status;
- unsigned long spurdev;
- unsigned long spurcount;
- } rx_isr_spurious_info;
- struct cd2401_re_isr_spurious_info {
- unsigned char channel;
- unsigned long spurdev;
- unsigned long spurcount;
- } re_isr_spurious_info;
- struct cd2401_modem_isr_spurious_info {
- unsigned char channel;
- unsigned long spurdev;
- unsigned long spurcount;
- } modem_isr_spurious_info;
- struct cd2401_first_open_info {
- unsigned char channel;
- uint8_t init_count;
- } first_open_info;
- struct cd2401_last_close_info {
- unsigned char channel;
- uint8_t init_count;
- } last_close_info;
- struct cd2401_start_remote_tx_info {
- unsigned char channel;
- } start_remote_tx_info;
- struct cd2401_stop_remote_tx_info {
- unsigned char channel;
- } stop_remote_tx_info;
- struct cd2401_set_attribute_info {
- int minor;
- uint8_t need_reinit;
- uint8_t txEmpty;
- uint8_t csize;
- uint8_t cstopb;
- uint8_t parodd;
- uint8_t parenb;
- uint8_t ignpar;
- uint8_t inpck;
- uint8_t hw_flow_ctl;
- uint8_t sw_flow_ctl;
- uint8_t extra_flow_ctl;
- uint8_t icrnl;
- uint8_t igncr;
- uint8_t inlcr;
- uint8_t brkint;
- uint8_t ignbrk;
- uint8_t parmrk;
- uint8_t istrip;
- uint16_t tx_period;
- uint16_t rx_period;
- uint32_t out_baud;
- uint32_t in_baud;
- } set_attribute_info;
- struct cd2401_drain_output_info {
- uint8_t txEmpty;
- uint8_t own_buf_A;
- uint8_t own_buf_B;
- } drain_output_info;
- struct cd2401_delay_info {
- rtems_interval start;
- rtems_interval end;
- rtems_interval current;
- unsigned long loop_count;
- } delay_info;
- } u;
-};
-
-struct cd2401_debug_info cd2401_debug_buffer[CD2401_DEBUG_BUFFER_SIZE];
-int cd2401_debug_index = 0;
-
-#include <string.h>
-
-int cd2401_get_record_size(
- int size
-)
-{
- /* Not the best way to do this */
- return size + 4;
-}
-
-void cd2401_record_write_info(
- int len,
- const char * buf,
- char dmabuf
-)
-{
- int max_length;
-
- max_length = (len < CD2401_DEBUG_CHAR_BUFSIZE ) ? len : CD2401_DEBUG_CHAR_BUFSIZE;
-
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_WRITE_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_write_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.write_info.length = len;
- memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.write_info.buffer), buf, max_length );
- cd2401_debug_buffer[cd2401_debug_index].u.write_info.dmabuf = dmabuf;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_tx_isr_info(
- unsigned char ch,
- unsigned char status,
- unsigned char initial_ier,
- unsigned char final_ier,
- uint8_t txEmpty
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_tx_isr_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.status = status;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.initial_ier = initial_ier;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.final_ier = final_ier;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_info.txEmpty = txEmpty;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_tx_isr_spurious_info(
- unsigned char ch,
- unsigned char status,
- unsigned char initial_ier,
- unsigned char final_ier,
- unsigned char spur_dev,
- unsigned char spur_cnt
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_SPURIOUS_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_tx_isr_spurious_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.status = status;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.initial_ier = initial_ier;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.final_ier = final_ier;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurdev = spur_dev;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_spurious_info.spurcount = spur_cnt;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_tx_isr_buserr_info(
- unsigned char ch,
- unsigned char status,
- unsigned char initial_ier,
- unsigned char buserr,
- unsigned long buserr_type,
- unsigned long buserr_addr
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_TX_ISR_BUSERR_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_tx_isr_buserr_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.status = status;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.initial_ier = initial_ier;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.buserr = buserr;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.type = buserr_type;
- cd2401_debug_buffer[cd2401_debug_index].u.tx_isr_buserr_info.addr = buserr_addr;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_rx_isr_info(
- unsigned char ch,
- unsigned char total,
- char * buffer
-)
-{
- int max_length;
-
- max_length = (total < CD2401_DEBUG_CHAR_BUFSIZE ) ? total : CD2401_DEBUG_CHAR_BUFSIZE;
-
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_rx_isr_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.length = max_length;
- memcpy ( &(cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_info.buffer), buffer, max_length );
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_rx_isr_spurious_info(
- unsigned char ch,
- unsigned char status,
- uint32_t spur_dev,
- uint32_t spur_cnt
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RX_ISR_SPURIOUS_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_rx_isr_spurious_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.status = status;
- cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurdev = spur_dev;
- cd2401_debug_buffer[cd2401_debug_index].u.rx_isr_spurious_info.spurcount = spur_cnt;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_re_isr_spurious_info(
- unsigned char ch,
- uint32_t spur_dev,
- uint32_t spur_cnt
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_RE_ISR_SPURIOUS_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_re_isr_spurious_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurdev = spur_dev;
- cd2401_debug_buffer[cd2401_debug_index].u.re_isr_spurious_info.spurcount = spur_cnt;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_modem_isr_spurious_info(
- unsigned char ch,
- uint32_t spur_dev,
- uint32_t spur_cnt
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_MODEM_ISR_SPURIOUS_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_modem_isr_spurious_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurdev = spur_dev;
- cd2401_debug_buffer[cd2401_debug_index].u.modem_isr_spurious_info.spurcount = spur_cnt;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_first_open_info(
- unsigned char ch,
- uint8_t init_count
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_FIRST_OPEN_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_first_open_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.first_open_info.init_count = init_count;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_last_close_info(
- unsigned char ch,
- uint8_t init_count
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_LAST_CLOSE_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_last_close_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.channel = ch;
- cd2401_debug_buffer[cd2401_debug_index].u.last_close_info.init_count = init_count;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_start_remote_tx_info(
- unsigned char ch
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_START_REMOTE_TX_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_start_remote_tx_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.start_remote_tx_info.channel = ch;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_stop_remote_tx_info(
- unsigned char ch
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_STOP_REMOTE_TX_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_stop_remote_tx_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.stop_remote_tx_info.channel = ch;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_set_attributes_info(
- int minor,
- uint8_t need_reinit,
- uint8_t csize,
- uint8_t cstopb,
- uint8_t parodd,
- uint8_t parenb,
- uint8_t ignpar,
- uint8_t inpck,
- uint8_t hw_flow_ctl,
- uint8_t sw_flow_ctl,
- uint8_t extra_flow_ctl,
- uint8_t icrnl,
- uint8_t igncr,
- uint8_t inlcr,
- uint8_t brkint,
- uint8_t ignbrk,
- uint8_t parmrk,
- uint8_t istrip,
- uint16_t tx_period,
- uint16_t rx_period,
- uint32_t out_baud,
- uint32_t in_baud
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_SET_ATTRIBUTE_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_set_attribute_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.minor = minor;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.need_reinit = need_reinit;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.txEmpty = CD2401_Channel_Info[minor].txEmpty;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.csize = csize;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.cstopb = cstopb;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parodd = parodd;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parenb = parenb;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignpar = ignpar;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inpck = inpck;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.hw_flow_ctl = hw_flow_ctl;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.sw_flow_ctl = sw_flow_ctl;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.extra_flow_ctl = extra_flow_ctl;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.icrnl = icrnl;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.igncr = igncr;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.inlcr = inlcr;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.brkint = brkint;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.ignbrk = ignbrk;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.parmrk = parmrk;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.istrip = istrip;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.tx_period = tx_period;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.rx_period = rx_period;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.out_baud = out_baud;
- cd2401_debug_buffer[cd2401_debug_index].u.set_attribute_info.in_baud = in_baud;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_drain_output_info(
- uint8_t txEmpty,
- uint8_t own_buf_A,
- uint8_t own_buf_B
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DRAIN_OUTPUT_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_drain_output_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.txEmpty = txEmpty;
- cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_A = own_buf_A;
- cd2401_debug_buffer[cd2401_debug_index].u.drain_output_info.own_buf_B = own_buf_B;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-void cd2401_record_delay_info(
- rtems_interval start,
- rtems_interval end,
- rtems_interval current,
- unsigned long loop_count
-)
-{
- memset( &(cd2401_debug_buffer[cd2401_debug_index]), '\0', sizeof( struct cd2401_debug_info ) );
- cd2401_debug_buffer[cd2401_debug_index].discriminant = CD2401_DELAY_INFO;
- cd2401_debug_buffer[cd2401_debug_index].record_size =
- cd2401_get_record_size( sizeof( struct cd2401_delay_info ) );
- cd2401_debug_buffer[cd2401_debug_index].u.delay_info.start = start;
- cd2401_debug_buffer[cd2401_debug_index].u.delay_info.end = end;
- cd2401_debug_buffer[cd2401_debug_index].u.delay_info.current = current;
- cd2401_debug_buffer[cd2401_debug_index].u.delay_info.loop_count = loop_count;
-
- cd2401_debug_index = (cd2401_debug_index + 1 ) % CD2401_DEBUG_BUFFER_SIZE;
-}
-
-#else
-
-/* Do not call the data recording functions */
-#define CD2401_RECORD_WRITE_INFO( args )
-#define CD2401_RECORD_TX_ISR_INFO( args )
-#define CD2401_RECORD_TX_ISR_SPURIOUS_INFO( args )
-#define CD2401_RECORD_TX_ISR_BUSERR_INFO( args )
-#define CD2401_RECORD_RX_ISR_INFO( args )
-#define CD2401_RECORD_RX_ISR_SPURIOUS_INFO( args )
-#define CD2401_RECORD_RE_ISR_SPURIOUS_INFO( args )
-#define CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO( args )
-#define CD2401_RECORD_FIRST_OPEN_INFO( args )
-#define CD2401_RECORD_LAST_CLOSE_INFO( args )
-#define CD2401_RECORD_START_REMOTE_TX_INFO( args )
-#define CD2401_RECORD_STOP_REMOTE_TX_INFO( args )
-#define CD2401_RECORD_SET_ATTRIBUTES_INFO( args )
-#define CD2401_RECORD_DRAIN_OUTPUT_INFO( args )
-#define CD2401_RECORD_DELAY_INFO( args )
-
-#endif
diff --git a/c/src/lib/libbsp/m68k/mvme167/console/console.c b/c/src/lib/libbsp/m68k/mvme167/console/console.c
deleted file mode 100644
index 0499ac46b3..0000000000
--- a/c/src/lib/libbsp/m68k/mvme167/console/console.c
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- * This file contains the MVME167 termios console package. Only asynchronous
- * I/O is supported.
- *
- * /dev/tty0 is channel 0, Serial Port 1/Console on the MVME712M.
- * /dev/tty1 is channel 1, Serial Port 2/TTY01 on the MVME712M.
- * /dev/tty2 is channel 2, Serial Port 3 on the MVME712M.
- * /dev/tty3 is channel 3, Serial Port 4 on the MVME712M.
- *
- * Normal I/O uses DMA for output, interrupts for input. /dev/console is
- * fixed to be /dev/tty01, Serial Port 2. Very limited support is provided
- * for polled I/O. Polled I/O is intended only for running the RTEMS test
- * suites. In all cases, Serial Port 1/Console is allocated to 167Bug and
- * is the dedicated debugger port. We configure GDB to use 167Bug for
- * debugging. When debugging with GDB or 167Bug, do not open /dev/tty00.
- *
- * Modern I/O chips often contain a number of I/O devices that can operate
- * almost independently of each other. Typically, in RTEMS, all devices in
- * an I/O chip are handled by a single device driver, but that need not be
- * always the case. Each device driver must supply six entry points in the
- * Device Driver Table: a device initialization function, as well as an open,
- * close, read, write and a control function. RTEMS assigns a device major
- * number to each device driver. This major device number is the index of the
- * device driver entries in the Device Driver Table, and it used to identify
- * a particular device driver. To distinguish multiple I/O sub-devices within
- * an I/O chip, RTEMS supports device minor numbers. When a I/O device is
- * initialized, the major number is supplied to the initialization function.
- * That function must register each sub-device with a separate name and minor
- * number (as well as the supplied major number). When an application opens a
- * device by name, the corresponding major and minor numbers are returned to
- * the caller to be used in subsequent I/O operations (although these details
- * are typically hidden within the library functions).
- *
- * Such a scheme recognizes that the initialization of the individual
- * sub-devices is generally not completely independent. For example, the
- * four serial ports of the CD2401 can be configured almost independently
- * from each other. One port could be configured to operate in asynchronous
- * mode with interrupt-driven I/O, while another port could be configured to
- * operate in HDLC mode with DMA I/O. However, a device reset command will
- * reset all four channels, and the width of DMA transfers and the number of
- * retries following bus errors selected applies to all four channels.
- * Consequently, when initializing one channel, one must be careful not to
- * destroy the configuration of other channels that are already configured.
- *
- * One problem with the RTEMS I/O initialization model is that no information
- * other than a device major number is passed to the initialization function.
- * Consequently, the sub-devices must be initialized with some pre-determined
- * configuration. To change the configuration of a sub-device, it is
- * necessary to either rewrite the initialization function, or to make a
- * series of rtems_io_control() calls after initialization. The first
- * approach is not very elegant. The second approach is acceptable if an
- * application is simply changing baud rates, parity or other such
- * asynchronous parameters (as supplied by the termios package). But what if
- * an application requires one channel to run in HDLC or Bisync mode and
- * another in async mode? With a single driver per I/O chip approach, the
- * device driver must support multiple protocols. This is feasible, but it
- * often means that an application that only does asynchronous I/O now links
- * in code for other unused protocols, thus wasting precious ROM space.
- * Worse, it requires that the sub-devices be initialized in some
- * configuration, and that configuration then changed through a series of
- * device driver control calls. There is no standard API in RTEMS to switch
- * a serial line to some synchronous protocol.
- *
- * A better approach is to treat each channel as a separate device, each with
- * its own device device driver. The application then supplies its own device
- * driver table with only the required protocols (drivers) on each line. The
- * problem with this approach is that the device drivers are not really
- * independent, given that the I/O sub-devices within a common chip are not
- * independent themselves. Consequently, the related device drivers must
- * share some information. In RTEMS, there is no standard location in which
- * to share information.
- *
- * This driver handles all four channels, i.e. it distinguishes the
- * sub-devices using minor device numbers. Only asynchronous I/O is
- * supported. The console is currently fixed to be channel 1 on the CD2401,
- * which corresponds to the TTY01 port (Serial Port 2) on the MVME712M
- * Transition Module.
- *
- * The CD2401 does either interrupt-driven or DMA I/O; it does not support
- * polling. In interrupt-driven or DMA I/O modes, interrupts from the CD2401
- * are routed to the MC68040, and the processor generates an interrupt
- * acknowledge cycle directly to the CD2401 to obtain an interrupt vector.
- * The PCCchip2 supports a pseudo-polling mode in which interrupts from the
- * CD2401 are not routed to the MC68040, but can be detected by the processor
- * by reading the appropriate CD2401 registers. In this mode, interrupt
- * acknowledge cycles must be generated to the CD2401 by reading the
- * appropriate PCCchip2 registers.
- *
- * Interrupts from the four channels cannot be routed independently; either
- * all channels are used in the pseudo-polling mode, or all channels are used
- * in interrupt-driven/DMA mode. There is no advantage in using the speudo-
- * polling mode. Consenquently, this driver performs DMA input and output.
- * Output is performed directly from the termios raw output buffer, while
- * input is accumulated into a separate buffer.
- *
- * THIS MODULE IS NOT RE-ENTRANT! Simultaneous access to a device from
- * multiple tasks is likely to cause significant problems! Concurrency
- * control is implemented in the termios package.
- *
- * THE INTERRUPT LEVEL IS SET TO 1 FOR ALL CHANNELS.
- * If the CD2401 is to be used for high speed synchronous serial I/O, the
- * interrupt priority might need to be increased.
- *
- * ALL INTERRUPT HANDLERS ARE SHARED.
- * When adding extra device drivers, either rewrite the interrupt handlers
- * to demultiplex the interrupts, or install separate vectors. Common vectors
- * are currently used to catch spurious interrupts. We could already have
- * installed separate vectors for each channel and used the spurious
- * interrupt handler defined in some other BSPs, but handling spurious
- * interrupts from the CD2401 in this device driver allows us to record more
- * information on the source of the interrupts. Furthermore, we have observed
- * the occasional spurious interrupt from channel 0. We definitely do not
- * to call a debugger for those.
- *
- * All page references are to the MVME166/MVME167/MVME187 Single Board
- * Computer Programmer's Reference Guide (MVME187PG/D2) with the April
- * 1993 supplements/addenda (MVME187PG/D2A1).
- */
-
-/*
- * Copyright (c) 1998, National Research Council of Canada
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#define M167_INIT
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include <rtems/console.h>
-#include <rtems/libio.h>
-#include <rtems/termiostypes.h>
-#include <bsp.h> /* Must be before libio.h */
-
-/* Utility functions */
-void cd2401_udelay( unsigned long delay );
-void cd2401_chan_cmd( uint8_t channel, uint8_t cmd, uint8_t wait );
-uint16_t cd2401_bitrate_divisor( uint32_t clkrate, uint32_t * bitrate );
-void cd2401_initialize( void );
-void cd2401_interrupts_initialize( bool enable );
-
-/* ISRs */
-rtems_isr cd2401_modem_isr( rtems_vector_number vector );
-rtems_isr cd2401_re_isr( rtems_vector_number vector );
-rtems_isr cd2401_rx_isr( rtems_vector_number vector );
-rtems_isr cd2401_tx_isr( rtems_vector_number vector );
-
-/* Termios callbacks */
-int cd2401_firstOpen( int major, int minor, void *arg );
-int cd2401_lastClose( int major, int minor, void *arg );
-int cd2401_setAttributes( int minor, const struct termios *t );
-int cd2401_startRemoteTx( int minor );
-int cd2401_stopRemoteTx( int minor );
-ssize_t cd2401_write( int minor, const char *buf, size_t len );
-int cd2401_drainOutput( int minor );
-int _167Bug_pollRead( int minor );
-ssize_t _167Bug_pollWrite( int minor, const char *buf, size_t len );
-
-/* Printk function */
-static void _BSP_output_char( char c );
-BSP_output_char_function_type BSP_output_char = _BSP_output_char;
-BSP_polling_getchar_function_type BSP_poll_char = NULL;
-
-/* '\r' character in memory. This used to live on
- * the stack but storing the '\r' character is
- * optimized away by gcc-4.3.2 (since it seems to
- * be unused [only referenced from inline assembly
- * code in _167Bug_pollWrite()]).
- * Hence we make it a global constant.
- */
-static const char cr_char = '\r';
-
-/* Channel info */
-/* static */ volatile struct {
- void *tty; /* Really a struct rtems_termios_tty * */
- int len; /* Record nb of chars being TX'ed */
- const char *buf; /* Record where DMA is coming from */
- uint32_t spur_cnt; /* Nb of spurious ints so far */
- uint32_t spur_dev; /* Indo on last spurious int */
- uint32_t buserr_addr; /* Faulting address */
- uint32_t buserr_type; /* Reason of bus error during DMA */
- uint8_t own_buf_A; /* If true, buffer A belongs to the driver */
- uint8_t own_buf_B; /* If true, buffer B belongs to the driver */
- uint8_t txEmpty; /* If true, the output FIFO should be empty */
-} CD2401_Channel_Info[4];
-
-/*
- * The number of channels already opened. If zero, enable the interrupts. The
- * initial value must be 0. If initialized explicitly, the variable ends up
- * in the .data section. Its value is not re-initialized on system restart.
- * Furthermore, because the variable is changed, the .data section would not
- * be ROMable. We thus leave the variable uninitialized, which causes it to
- * be allocated in the .bss section, and rely on RTEMS to zero the .bss
- * section on every startup.
- */
-uint8_t Init_count;
-
-/* Record previous handlers */
-rtems_isr_entry Prev_re_isr; /* Previous rx exception isr */
-rtems_isr_entry Prev_rx_isr; /* Previous rx isr */
-rtems_isr_entry Prev_tx_isr; /* Previous tx isr */
-rtems_isr_entry Prev_modem_isr; /* Previous modem/timer isr */
-
-/* Define the following symbol to trace the calls to this driver */
-/* #define CD2401_RECORD_DEBUG_INFO */
-#include "console-recording.h"
-
-/*
- * Utility functions.
- */
-
-/*
- * Assumes that clock ticks 1 million times per second.
- *
- * MAXIMUM DELAY IS ABOUT 20 ms
- *
- * Input parameters:
- * delay: Number of microseconds to delay.
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
- void cd2401_udelay
-(
- unsigned long delay
-)
-{
- unsigned long i = 20000; /* In case clock is off */
- rtems_interval start_ticks, end_ticks, current_ticks;
-
- start_ticks = rtems_clock_get_ticks_since_boot();
- end_ticks = start_ticks + delay;
-
- do {
- current_ticks = rtems_clock_get_ticks_since_boot();
- } while ( --i && (current_ticks <= end_ticks) );
-
- CD2401_RECORD_DELAY_INFO(( start_ticks, end_ticks, current_ticks, i ));
-}
-
-/*
- * cd2401_chan_cmd
- *
- * Sends a CCR command to the specified channel. Waits for any unfinished
- * previous command to complete, then sends the specified command. Optionally
- * wait for the current command to finish before returning.
- *
- * Input parameters:
- * channel - CD2401 channel number
- * cmd - command byte
- * wait - if non-zero, wait for specified command to complete before
- * returning.
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-void cd2401_chan_cmd(
- uint8_t channel,
- uint8_t cmd,
- uint8_t wait
-)
-{
- if ( channel < 4 ) {
- cd2401->car = channel; /* Select channel */
-
- while ( cd2401->ccr != 0 ); /* Wait for completion of previous command */
- cd2401->ccr = cmd; /* Send command */
- if ( wait )
- while( cd2401->ccr != 0 );/* Wait for completion */
- }
- else {
- /* This may not be the best error message */
- rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
- }
-}
-
-/*
- * cd2401_bitrate_divisor
- *
- * Compute the divisor and clock source to use to obtain the desired bitrate.
- *
- * Input parameters:
- * clkrate - system clock rate (CLK input frequency)
- * bitrate - the desired bitrate
- *
- * Output parameters:
- * bitrate - The actual bitrate achievable, to the nearest bps.
- *
- * Return values:
- * Returns divisor in lower byte and clock source in upper byte for the
- * specified bitrate.
- */
-uint16_t cd2401_bitrate_divisor(
- uint32_t clkrate,
- uint32_t * bitrate
-)
-{
- uint32_t divisor;
- uint16_t clksource;
-
- divisor = *bitrate << 3; /* temporary; multiply by 8 for CLK/8 */
- divisor = (clkrate + (divisor>>1)) / divisor; /* divisor for clk0 (CLK/8) */
-
- /* Use highest speed clock source for best precision - try clk0 to clk4 */
- for( clksource = 0; clksource < 0x0400 && divisor > 0x100; clksource += 0x0100 )
- divisor >>= 2;
- divisor--; /* adjustment, see specs */
- if( divisor < 1 )
- divisor = 1;
- else if( divisor > 0xFF )
- divisor = 0xFF;
- *bitrate = clkrate / (1 << ((clksource >> 7)+3)) / (divisor+1);
- return( clksource | divisor );
-}
-
-/*
- * cd2401_initialize
- *
- * Initializes the CD2401 device. Individual channels on the chip are left in
- * their default reset state, and should be subsequently configured.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-void cd2401_initialize( void )
-{
- int i;
-
- for ( i = 3; i >= 0; i-- ) {
- CD2401_Channel_Info[i].tty = NULL;
- CD2401_Channel_Info[i].len = 0;
- CD2401_Channel_Info[i].buf = NULL;
- CD2401_Channel_Info[i].spur_cnt = 0;
- CD2401_Channel_Info[i].spur_dev = 0;
- CD2401_Channel_Info[i].buserr_type = 0;
- CD2401_Channel_Info[i].buserr_addr = 0;
- CD2401_Channel_Info[i].own_buf_A = TRUE;
- CD2401_Channel_Info[i].own_buf_B = TRUE;
- CD2401_Channel_Info[i].txEmpty = TRUE;
- }
-
- /*
- * Normally, do a device reset here. If we do it, we will most likely clober
- * the port settings for 167Bug on channel 0. So we just shut up all the
- * ports by disabling their interrupts.
- */
-#if 0
- cd2401->gfrcr = 0; /* So we can detect that device init is done */
- cd2401_chan_cmd( 0x10, 0); /* Reset all */
- while(cd2401->gfrcr == 0); /* Wait for reset all */
-#endif
-
- /*
- * The CL-CD2400/2401 manual (part no 542400-003) states on page 87 that
- * the LICR "contains the number of the interrupting channel being served.
- * The channel number is always that of the current acknowledged interrupt."
- * THE USER MUST PROGRAM CHANNEL NUMBER IN LICR! It is not set automatically
- * by the hardware, as suggested by the manual.
- *
- * The updated manual (part no 542400-007) has the story straight. The
- * CD2401 automatically initializes the LICR to contain the channel number
- * in bits 2 and 3. However, these bits are not preserved when the user
- * defined bits are written.
- *
- * The same vector number is used for all four channels. Different vector
- * numbers could be programmed for each channel, thus avoiding the need to
- * demultiplex the interrupts in the ISR.
- */
- for ( i = 0; i < 4; i++ ) {
- cd2401->car = i; /* Select channel */
- cd2401->livr = 0x5C; /* Motorola suggested value p. 3-15 */
- cd2401->licr = i << 2; /* Don't rely on reset value */
- cd2401->ier = 0; /* Disable all interrupts */
- }
-
- /*
- * The content of the CD2401 xpilr registers must match the A7-A0 addresses
- * generated by the PCCchip2 during interrupt acknowledge cycles in order
- * for the CD2401 to recognize the IACK cycle and clear its interrupt
- * request.
- */
- cd2401->mpilr = 0x01; /* Match pccchip2->modem_piack p. 3-27 */
- cd2401->tpilr = 0x02; /* Match pccchip2->tx_piack p. 3-28 */
- cd2401->rpilr = 0x03; /* Match pccchip2->rx_piack p. 3-29 */
-
- /* Global CD2401 registers */
- cd2401->dmr = 0; /* 16-bit DMA transfers when possible */
- cd2401->bercnt = 0; /* Do not retry DMA upon bus errors */
-
- /*
- * Setup timer prescaler period, which clocks timers 1 and 2 (or rx timeout
- * and tx delay). The prescaler is clocked by the system clock) / 2048. The
- * register must be in the range 0x0A..0xFF, ie. a rescaler period range of
- * about 1ms..26ms for a nominal system clock rate of 20MHz.
- */
- cd2401->tpr = 0x0A; /* Same value as 167Bug */
-}
-
-/*
- * cd2401_interrupts_initialize
- *
- * This routine enables or disables the CD2401 interrupts to the MC68040.
- * Interrupts cannot be enabled/disabled on a per-channel basis.
- *
- * Input parameters:
- * enable - if true, enable the interrupts, else disable them.
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- *
- * THE FIRST CD2401 CHANNEL OPENED SHOULD ENABLE INTERRUPTS.
- * THE LAST CD2401 CHANNEL CLOSED SHOULD DISABLE INTERRUPTS.
- */
-void cd2401_interrupts_initialize(
- bool enable
-)
-{
- if ( enable ) {
- /*
- * Enable interrupts from the CD2401 in the PCCchip2.
- * During DMA transfers, the MC68040 supplies dirty data during read cycles
- * from the CD2401 and leaves the data dirty in its data cache if there is
- * a cache hit. The MC68040 updates the data cache during write cycles from
- * the CD2401 if there is a cache hit.
- */
- pccchip2->SCC_error = 0x01;
- pccchip2->SCC_modem_int_ctl = 0x10 | CD2401_INT_LEVEL;
- pccchip2->SCC_tx_int_ctl = 0x10 | CD2401_INT_LEVEL;
- pccchip2->SCC_rx_int_ctl = 0x50 | CD2401_INT_LEVEL;
-
- pccchip2->gen_control |= 0x02; /* Enable pccchip2 interrupts */
- }
- else {
- /* Disable interrupts */
- pccchip2->SCC_modem_int_ctl &= 0xEF;
- pccchip2->SCC_tx_int_ctl &= 0xEF;
- pccchip2->SCC_rx_int_ctl &= 0xEF;
- }
-}
-
-/* ISRs */
-
-/*
- * cd2401_modem_isr
- *
- * Modem/timer interrupt (group 1) from CD2401. These are not used, and not
- * expected. Record as spurious and clear.
- *
- * Input parameters:
- * vector - vector number
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-rtems_isr cd2401_modem_isr(
- rtems_vector_number vector
-)
-{
- uint8_t ch;
-
- /* Get interrupting channel ID */
- ch = cd2401->licr >> 2;
-
- /* Record interrupt info for debugging */
- CD2401_Channel_Info[ch].spur_dev =
- (vector << 24) | (cd2401->stk << 16) | (cd2401->mir << 8) | cd2401->misr;
- CD2401_Channel_Info[ch].spur_cnt++;
-
- cd2401->meoir = 0; /* EOI */
- CD2401_RECORD_MODEM_ISR_SPURIOUS_INFO(( ch,
- CD2401_Channel_Info[ch].spur_dev,
- CD2401_Channel_Info[ch].spur_cnt ));
-}
-
-/*
- * cd2401_re_isr
- *
- * RX exception interrupt (group 3, receiver exception) from CD2401. These are
- * not used, and not expected. Record as spurious and clear.
- *
- * FIX THIS ISR TO DETECT BREAK CONDITIONS AND RAISE SIGINT
- *
- * Input parameters:
- * vector - vector number
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-rtems_isr cd2401_re_isr(
- rtems_vector_number vector
-)
-{
- uint8_t ch;
-
- /* Get interrupting channel ID */
- ch = cd2401->licr >> 2;
-
- /* Record interrupt info for debugging */
- CD2401_Channel_Info[ch].spur_dev =
- (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl;
- CD2401_Channel_Info[ch].spur_cnt++;
-
- if ( cd2401->u5.b.risrl & 0x80 ) /* Timeout interrupt? */
- cd2401->ier &= 0xDF; /* Disable rx timeout interrupt */
- cd2401->reoir = 0x08; /* EOI; exception char not read */
- CD2401_RECORD_RE_ISR_SPURIOUS_INFO(( ch,
- CD2401_Channel_Info[ch].spur_dev,
- CD2401_Channel_Info[ch].spur_cnt ));
-}
-
-/*
- * cd2401_rx_isr
- *
- * RX interrupt (group 3, receiver data) from CD2401.
- *
- * Input parameters:
- * vector - vector number
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-rtems_isr cd2401_rx_isr(
- rtems_vector_number vector
-)
-{
- char c;
- uint8_t ch, status, nchars, total;
- #ifdef CD2401_RECORD_DEBUG_INFO
- uint8_t i = 0;
- char buffer[256];
- #endif
-
- (void) total; /* avoid set but not used warnings when not recording info */
-
- status = cd2401->u5.b.risrl;
- ch = cd2401->licr >> 2;
-
- /* Has this channel been initialized or is it a condition we ignore? */
- if ( CD2401_Channel_Info[ch].tty && !status ) {
- /* Normal Rx Int, read chars, enqueue them, and issue EOI */
- total = nchars = cd2401->rfoc; /* Nb of chars to retrieve from rx FIFO */
- while ( nchars-- > 0 ) {
- c = (char)cd2401->dr; /* Next char in rx FIFO */
- rtems_termios_enqueue_raw_characters( CD2401_Channel_Info[ch].tty ,&c, 1 );
- #ifdef CD2401_RECORD_DEBUG_INFO
- buffer[i++] = c;
- #endif
- }
- cd2401->reoir = 0; /* EOI */
- CD2401_RECORD_RX_ISR_INFO(( ch, total, buffer ));
- } else {
- /* No, record as spurious interrupt */
- CD2401_Channel_Info[ch].spur_dev =
- (vector << 24) | (cd2401->stk << 16) | (cd2401->rir << 8) | cd2401->u5.b.risrl;
- CD2401_Channel_Info[ch].spur_cnt++;
- cd2401->reoir = 0x04; /* EOI - character not read */
- CD2401_RECORD_RX_ISR_SPURIOUS_INFO(( ch, status,
- CD2401_Channel_Info[ch].spur_dev,
- CD2401_Channel_Info[ch].spur_cnt ));
- }
-}
-
-/*
- * cd2401_tx_isr
- *
- * TX interrupt (group 2) from CD2401.
- *
- * Input parameters:
- * vector - vector number
- *
- * Output parameters: NONE
- *
- * Return values: NONE
- */
-rtems_isr cd2401_tx_isr(
- rtems_vector_number vector
-)
-{
- uint8_t ch, status, buserr, initial_ier, final_ier;
-
- status = cd2401->tisr;
- ch = cd2401->licr >> 2;
- initial_ier = cd2401->ier;
-
- #ifndef CD2401_RECORD_DEBUG_INFO
- /*
- * When the debug is disabled, these variables are really not read.
- * But when debug is enabled, they are.
- */
- (void) initial_ier; /* avoid set but not used warning */
- (void) final_ier; /* avoid set but not used warning */
- #endif
-
- /* Has this channel been initialized? */
- if ( !CD2401_Channel_Info[ch].tty ) {
- /* No, record as spurious interrupt */
- CD2401_Channel_Info[ch].spur_dev =
- (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr;
- CD2401_Channel_Info[ch].spur_cnt++;
- final_ier = cd2401->ier &= 0xFC;/* Shut up, whoever you are */
-
- cd2401->teoir = 0x88; /* EOI - Terminate buffer and no transfer */
- CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, final_ier,
- CD2401_Channel_Info[ch].spur_dev,
- CD2401_Channel_Info[ch].spur_cnt ));
- return;
- }
-
- if ( status & 0x80 ) {
- /*
- * Bus error occurred during DMA transfer. For now, just record.
- * Get reason for DMA bus error and clear the report for the next
- * occurrence
- */
- buserr = pccchip2->SCC_error;
- pccchip2->SCC_error = 0x01;
- CD2401_Channel_Info[ch].buserr_type =
- (vector << 24) | (buserr << 16) | (cd2401->tir << 8) | cd2401->tisr;
- CD2401_Channel_Info[ch].buserr_addr =
- (((uint32_t)cd2401->tcbadru) << 16) | cd2401->tcbadrl;
-
- cd2401->teoir = 0x80; /* EOI - terminate bad buffer */
- CD2401_RECORD_TX_ISR_BUSERR_INFO(( ch, status, initial_ier, buserr,
- CD2401_Channel_Info[ch].buserr_type,
- CD2401_Channel_Info[ch].buserr_addr ));
- return;
- }
-
- if ( status & 0x20 ) {
- /* DMA done -- Turn off TxD int, turn on TxMpty */
- final_ier = cd2401->ier = (cd2401->ier & 0xFE) | 0x02;
- if( status & 0x08 ) {
- /* Transmit buffer B was released */
- CD2401_Channel_Info[ch].own_buf_B = TRUE;
- }
- else {
- /* Transmit buffer A was released */
- CD2401_Channel_Info[ch].own_buf_A = TRUE;
- }
- CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier,
- CD2401_Channel_Info[ch].txEmpty ));
-
- /* This call can result in a call to cd2401_write() */
- rtems_termios_dequeue_characters (
- CD2401_Channel_Info[ch].tty,
- CD2401_Channel_Info[ch].len );
- cd2401->teoir = 0x08; /* EOI - no data transfered */
- }
- else if ( status & 0x02 ) {
- /* TxEmpty */
- CD2401_Channel_Info[ch].txEmpty = TRUE;
- final_ier = cd2401->ier &= 0xFD;/* Shut up the interrupts */
- cd2401->teoir = 0x08; /* EOI - no data transfered */
- CD2401_RECORD_TX_ISR_INFO(( ch, status, initial_ier, final_ier,
- CD2401_Channel_Info[ch].txEmpty ));
- }
- else {
- /* Why did we get a Tx interrupt? */
- CD2401_Channel_Info[ch].spur_dev =
- (vector << 24) | (cd2401->stk << 16) | (cd2401->tir << 8) | cd2401->tisr;
- CD2401_Channel_Info[ch].spur_cnt++;
- cd2401->teoir = 0x08; /* EOI - no data transfered */
- CD2401_RECORD_TX_ISR_SPURIOUS_INFO(( ch, status, initial_ier, 0xFF,
- CD2401_Channel_Info[ch].spur_dev,
- CD2401_Channel_Info[ch].spur_cnt ));
- }
-}
-
-/*
- * termios callbacks
- */
-
-/*
- * cd2401_firstOpen
- *
- * This is the first time that this minor device (channel) is opened.
- * Complete the asynchronous initialization.
- *
- * Input parameters:
- * major - device major number
- * minor - channel number
- * arg - pointer to a struct rtems_libio_open_close_args_t
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- */
-int cd2401_firstOpen(
- int major,
- int minor,
- void *arg
-)
-{
- rtems_libio_open_close_args_t *args = arg;
- rtems_libio_ioctl_args_t newarg;
- struct termios termios;
- rtems_status_code sc;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable (level);
-
- /*
- * Set up the line with the specified parameters. The difficulty is that
- * the line parameters are stored in the struct termios field of a
- * struct rtems_termios_tty that is not defined in a public header file.
- * Therefore, we do not have direct access to the termios passed in with
- * arg. So we make a rtems_termios_ioctl() call to get a pointer to the
- * termios structure.
- *
- * THIS KLUDGE MAY BREAK IN THE FUTURE!
- *
- * We could have made a tcgetattr() call if we had our fd.
- */
- newarg.iop = args->iop;
- newarg.command = TIOCGETA;
- newarg.buffer = &termios;
- sc = rtems_termios_ioctl (&newarg);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (sc);
-
- /*
- * Turn off hardware flow control. It is a pain with 3-wire cables.
- * The rtems_termios_ioctl() call below results in a call to
- * cd2401_setAttributes to initialize the line. The caller will "wait"
- * on the ttyMutex that it already owns; this is safe in RTEMS.
- */
- termios.c_cflag |= CLOCAL; /* Ignore modem status lines */
- newarg.command = TIOCGETA;
- sc = rtems_termios_ioctl (&newarg);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (sc);
-
- /* Mark that the channel as initialized */
- CD2401_Channel_Info[minor].tty = args->iop->data1;
-
- /* If the first of the four channels to open, set up the interrupts */
- if ( !Init_count++ ) {
- /* Install the interrupt handlers */
- Prev_re_isr = (rtems_isr_entry) set_vector( cd2401_re_isr, 0x5C, 1 );
- Prev_modem_isr = (rtems_isr_entry) set_vector( cd2401_modem_isr, 0x5D, 1 );
- Prev_tx_isr = (rtems_isr_entry) set_vector( cd2401_tx_isr, 0x5E, 1 );
- Prev_rx_isr = (rtems_isr_entry) set_vector( cd2401_rx_isr, 0x5F, 1 );
-
- cd2401_interrupts_initialize( TRUE );
- }
-
- CD2401_RECORD_FIRST_OPEN_INFO(( minor, Init_count ));
-
- rtems_interrupt_enable (level);
-
- /* Return something */
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * cd2401_lastClose
- *
- * There are no more opened file descriptors to this device. Close it down.
- *
- * Input parameters:
- * major - device major number
- * minor - channel number
- * arg - pointer to a struct rtems_libio_open_close_args_t
- */
-int cd2401_lastClose(
- int major,
- int minor,
- void *arg
-)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable (level);
-
- /* Mark that the channel is no longer is use */
- CD2401_Channel_Info[minor].tty = NULL;
-
- /* If the last of the four channels to close, disable the interrupts */
- if ( !--Init_count ) {
- cd2401_interrupts_initialize( FALSE );
-
- /* De-install the interrupt handlers */
- set_vector( Prev_re_isr, 0x5C, 1 );
- set_vector( Prev_modem_isr, 0x5D, 1 );
- set_vector( Prev_tx_isr, 0x5E, 1 );
- set_vector( Prev_rx_isr, 0x5F, 1 );
- }
-
- CD2401_RECORD_LAST_CLOSE_INFO(( minor, Init_count ));
-
- rtems_interrupt_enable (level);
-
- /* return something */
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * cd2401_setAttributes
- *
- * Set up the selected channel of the CD2401 chip for doing asynchronous
- * I/O with DMA.
- *
- * The chip must already have been initialized by cd2401_initialize().
- *
- * This code was written for clarity. The code space it occupies could be
- * reduced. The code could also be compiled with aggressive optimization
- * turned on.
- *
- * Input parameters:
- * minor - the selected channel
- * t - the termios parameters
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- */
-int cd2401_setAttributes(
- int minor,
- const struct termios *t
-)
-{
- uint8_t csize, cstopb, parodd, parenb, ignpar, inpck;
- uint8_t hw_flow_ctl, sw_flow_ctl, extra_flow_ctl;
- uint8_t icrnl, igncr, inlcr, brkint, ignbrk, parmrk, istrip;
- uint8_t need_reinitialization = FALSE;
- uint8_t read_enabled;
- uint16_t tx_period, rx_period;
- uint32_t out_baud, in_baud;
- rtems_interrupt_level level;
-
- /* Determine what the line parameters should be */
-
- /* baud rates */
- out_baud = rtems_termios_baud_to_number(t->c_ospeed);
- in_baud = rtems_termios_baud_to_number(t->c_ispeed);
-
- /* Number of bits per char */
- csize = 0x07; /* to avoid a warning */
- switch ( t->c_cflag & CSIZE ) {
- case CS5: csize = 0x04; break;
- case CS6: csize = 0x05; break;
- case CS7: csize = 0x06; break;
- case CS8: csize = 0x07; break;
- }
-
- /* Parity */
- if ( t->c_cflag & PARODD )
- parodd = 0x80; /* Odd parity */
- else
- parodd = 0;
-
- if ( t->c_cflag & PARENB )
- parenb = 0x40; /* Parity enabled on Tx and Rx */
- else
- parenb = 0x00; /* No parity on Tx and Rx */
-
- /* CD2401 IGNPAR and INPCK bits are inverted wrt POSIX standard? */
- if ( t->c_iflag & INPCK )
- ignpar = 0; /* Check parity on input */
- else
- ignpar = 0x10; /* Do not check parity on input */
- if ( t->c_iflag & IGNPAR ) {
- inpck = 0x03; /* Discard error character */
- parmrk = 0;
- } else {
- if ( t->c_iflag & PARMRK ) {
- inpck = 0x01; /* Translate to 0xFF 0x00 <char> */
- parmrk = 0x04;
- } else {
- inpck = 0x01; /* Translate to 0x00 */
- parmrk = 0;
- }
- }
-
- /* Stop bits */
- if ( t->c_cflag & CSTOPB )
- cstopb = 0x04; /* Two stop bits */
- else
- cstopb = 0x02; /* One stop bit */
-
- /* Modem flow control */
- if ( t->c_cflag & CLOCAL )
- hw_flow_ctl = 0x04; /* Always assert RTS before Tx */
- else
- hw_flow_ctl = 0x07; /* Always assert RTS before Tx,
- wait for CTS and DSR */
-
- /* XON/XOFF Tx flow control */
- if ( t->c_iflag & IXON ) {
- sw_flow_ctl = 0x40; /* Tx in-band flow ctl enabled, wait for XON */
- extra_flow_ctl = 0x30; /* Eat XON/XOFF, XON/XOFF in SCHR1, SCHR2 */
- }
- else {
- sw_flow_ctl = 0; /* Tx in-band flow ctl disabled */
- extra_flow_ctl = 0; /* Pass on XON/XOFF */
- }
-
- /* CL/LF translation */
- if ( t->c_iflag & ICRNL )
- icrnl = 0x40; /* Map CR to NL on input */
- else
- icrnl = 0; /* Pass on CR */
- if ( t->c_iflag & INLCR )
- inlcr = 0x20; /* Map NL to CR on input */
- else
- inlcr = 0; /* Pass on NL */
- if ( t->c_iflag & IGNCR )
- igncr = 0x80; /* CR discarded on input */
- else
- igncr = 0;
-
- /* Break handling */
- if ( t->c_iflag & IGNBRK ) {
- ignbrk = 0x10; /* Ignore break on input */
- brkint = 0x08;
- } else {
- if ( t->c_iflag & BRKINT ) {
- ignbrk = 0; /* Generate SIGINT (interrupt ) */
- brkint = 0;
- } else {
- ignbrk = 0; /* Convert to 0x00 */
- brkint = 0x08;
- }
- }
-
- /* Stripping */
- if ( t->c_iflag & ISTRIP )
- istrip = 0x80; /* Strip to 7 bits */
- else
- istrip = 0; /* Leave as 8 bits */
-
- rx_period = cd2401_bitrate_divisor( 20000000Ul, &in_baud );
- tx_period = cd2401_bitrate_divisor( 20000000Ul, &out_baud );
-
- /*
- * If this is the first time that the line characteristics are set up, then
- * the device must be re-initialized.
- * Also check if we need to change anything. It is preferable to not touch
- * the device if nothing changes. As soon as we touch it, it tends to
- * glitch. If anything changes, we reprogram all registers. This is
- * harmless.
- */
- if ( ( CD2401_Channel_Info[minor].tty == 0 ) ||
- ( cd2401->cor1 != (parodd | parenb | ignpar | csize) ) ||
- ( cd2401->cor2 != (sw_flow_ctl | hw_flow_ctl) ) ||
- ( cd2401->cor3 != (extra_flow_ctl | cstopb) ) ||
- ( cd2401->cor6 != (igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck) ) ||
- ( cd2401->cor7 != istrip ) ||
- ( cd2401->u1.async.schr1 != t->c_cc[VSTART] ) ||
- ( cd2401->u1.async.schr2 != t->c_cc[VSTOP] ) ||
- ( cd2401->rbpr != (unsigned char)rx_period ) ||
- ( cd2401->rcor != (unsigned char)(rx_period >> 8) ) ||
- ( cd2401->tbpr != (unsigned char)tx_period ) ||
- ( cd2401->tcor != ( (tx_period >> 3) & 0xE0 ) ) )
- need_reinitialization = TRUE;
-
- /* Write to the ports */
- rtems_interrupt_disable (level);
-
- cd2401->car = minor; /* Select channel */
- read_enabled = cd2401->csr & 0x80 ? TRUE : FALSE;
-
- if ( (t->c_cflag & CREAD ? TRUE : FALSE ) != read_enabled ) {
- /* Read enable status is changing */
- need_reinitialization = TRUE;
- }
-
- if ( need_reinitialization ) {
- /*
- * Could not find a way to test whether the CD2401 was done transmitting.
- * The TxEmpty interrupt does not seem to indicate that the FIFO is empty
- * in DMA mode. So, just wait a while for output to drain. May not be
- * enough, but it will have to do (should be long enough for 1 char at
- * 9600 bsp)...
- */
- cd2401_udelay( 2000L );
-
- /* Clear channel */
- cd2401_chan_cmd (minor, 0x40, 1);
-
- cd2401->car = minor; /* Select channel */
- cd2401->cmr = 0x42; /* Interrupt Rx, DMA Tx, async mode */
- cd2401->cor1 = parodd | parenb | ignpar | csize;
- cd2401->cor2 = sw_flow_ctl | hw_flow_ctl;
- cd2401->cor3 = extra_flow_ctl | cstopb;
- cd2401->cor4 = 0x0A; /* No DSR/DCD/CTS detect; FIFO threshold of 10 */
- cd2401->cor5 = 0x0A; /* No DSR/DCD/CTS detect; DTR threshold of 10 */
- cd2401->cor6 = igncr | icrnl | inlcr | ignbrk | brkint | parmrk | inpck;
- cd2401->cor7 = istrip; /* No LNext; ignore XON/XOFF if frame error; no tx translations */
- /* Special char 1: XON character */
- cd2401->u1.async.schr1 = t->c_cc[VSTART];
- /* special char 2: XOFF character */
- cd2401->u1.async.schr2 = t->c_cc[VSTOP];
-
- /*
- * Special chars 3 and 4, char range, LNext, RFAR[1..4] and CRC
- * are unused, left as is.
- */
-
- /* Set baudrates for receiver and transmitter */
- cd2401->rbpr = (unsigned char)rx_period;
- cd2401->rcor = (unsigned char)(rx_period >> 8); /* no DPLL */
- cd2401->tbpr = (unsigned char)tx_period;
- cd2401->tcor = (tx_period >> 3) & 0xE0; /* no x1 ext clk, no loopback */
-
- /* Timeout for 4 chars at 9600, 8 bits per char, 1 stop bit */
- cd2401->u2.w.rtpr = 0x04; /* NEED TO LOOK AT THIS LINE! */
-
- if ( t->c_cflag & CREAD ) {
- /* Re-initialize channel, enable rx and tx */
- cd2401_chan_cmd (minor, 0x2A, 1);
- /* Enable rx data ints */
- cd2401->ier = 0x08;
- } else {
- /* Re-initialize channel, enable tx, disable rx */
- cd2401_chan_cmd (minor, 0x29, 1);
- }
- }
-
- CD2401_RECORD_SET_ATTRIBUTES_INFO(( minor, need_reinitialization, csize,
- cstopb, parodd, parenb, ignpar, inpck,
- hw_flow_ctl, sw_flow_ctl, extra_flow_ctl,
- icrnl, igncr, inlcr, brkint, ignbrk,
- parmrk, istrip, tx_period, rx_period,
- out_baud, in_baud ));
-
- rtems_interrupt_enable (level);
-
- /*
- * Looks like the CD2401 needs time to settle after initialization. Give it
- * 10 ms. I don't really believe it, but if output resumes to quickly after
- * this call, the first few characters are not right.
- */
- if ( need_reinitialization )
- cd2401_udelay( 10000L );
-
- /* Return something */
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * cd2401_startRemoreTx
- *
- * Defined as a callback, but it would appear that it is never called. The
- * POSIX standard states that when the tcflow() function is called with the
- * TCION action, the system wall transmit a START character. Presumably,
- * tcflow() is called internally when IXOFF is set in the termios c_iflag
- * field when the input buffer can accomodate enough characters. It should
- * probably be called from fillBufferQueue(). Clearly, the function is also
- * explicitly callable by user code. The action is clearly to send the START
- * character, regardless of whether START/STOP flow control is in effect.
- *
- * Input parameters:
- * minor - selected channel
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- *
- * PROPER START CHARACTER MUST BE PROGRAMMED IN SCHR1.
- */
-int cd2401_startRemoteTx(
- int minor
-)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable (level);
-
- cd2401->car = minor; /* Select channel */
- cd2401->stcr = 0x01; /* Send SCHR1 ahead of chars in FIFO */
-
- CD2401_RECORD_START_REMOTE_TX_INFO(( minor ));
-
- rtems_interrupt_enable (level);
-
- /* Return something */
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * cd2401_stopRemoteTx
- *
- * Defined as a callback, but it would appear that it is never called. The
- * POSIX standard states that when the tcflow() function is called with the
- * TCIOFF function, the system wall transmit a STOP character. Presumably,
- * tcflow() is called internally when IXOFF is set in the termios c_iflag
- * field as the input buffer is about to overflow. It should probably be
- * called from rtems_termios_enqueue_raw_characters(). Clearly, the function
- * is also explicitly callable by user code. The action is clearly to send
- * the STOP character, regardless of whether START/STOP flow control is in
- * effect.
- *
- * Input parameters:
- * minor - selected channel
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- *
- * PROPER STOP CHARACTER MUST BE PROGRAMMED IN SCHR2.
- */
-int cd2401_stopRemoteTx(
- int minor
-)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable (level);
-
- cd2401->car = minor; /* Select channel */
- cd2401->stcr = 0x02; /* Send SCHR2 ahead of chars in FIFO */
-
- CD2401_RECORD_STOP_REMOTE_TX_INFO(( minor ));
-
- rtems_interrupt_enable (level);
-
- /* Return something */
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * cd2401_write
- *
- * Initiate DMA output. Termios guarantees that the buffer does not wrap
- * around, so we can do DMA strait from the supplied buffer.
- *
- * Input parameters:
- * minor - selected channel
- * buf - output buffer
- * len - number of chars to output
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- *
- * MUST BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED!
- * The processor is placed at interrupt level CD2401_INT_LEVEL explicitly in
- * console_write(). The processor is necessarily at interrupt level 1 in
- * cd2401_tx_isr().
- */
-ssize_t cd2401_write(
- int minor,
- const char *buf,
- size_t len
-)
-{
- if (len > 0) {
- cd2401->car = minor; /* Select channel */
-
- if ( (cd2401->dmabsts & 0x08) == 0 ) {
- /* Next buffer is A. Wait for it to be ours. */
- while ( cd2401->atbsts & 0x01 );
-
- CD2401_Channel_Info[minor].own_buf_A = FALSE;
- CD2401_Channel_Info[minor].len = len;
- CD2401_Channel_Info[minor].buf = buf;
- cd2401->atbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 );
- cd2401->atbadrl = (uint16_t)( (uint32_t) buf );
- cd2401->atbcnt = len;
- CD2401_RECORD_WRITE_INFO(( len, buf, 'A' ));
- cd2401->atbsts = 0x03; /* CD2401 owns buffer, int when empty */
- }
- else {
- /* Next buffer is B. Wait for it to be ours. */
- while ( cd2401->btbsts & 0x01 );
-
- CD2401_Channel_Info[minor].own_buf_B = FALSE;
- CD2401_Channel_Info[minor].len = len;
- CD2401_Channel_Info[minor].buf = buf;
- cd2401->btbadru = (uint16_t)( ( (uint32_t) buf ) >> 16 );
- cd2401->btbadrl = (uint16_t)( (uint32_t) buf );
- cd2401->btbcnt = len;
- CD2401_RECORD_WRITE_INFO(( len, buf, 'B' ));
- cd2401->btbsts = 0x03; /* CD2401 owns buffer, int when empty */
- }
- /* Nuts -- Need TxD ints */
- CD2401_Channel_Info[minor].txEmpty = FALSE;
- cd2401->ier |= 0x01;
- }
-
- /* Return something */
- return len;
-}
-
-#if 0
-/*
- * cd2401_drainOutput
- *
- * Wait for the txEmpty indication on the specified channel.
- *
- * Input parameters:
- * minor - selected channel
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- *
- * MUST NOT BE EXECUTED WITH THE CD2401 INTERRUPTS DISABLED!
- * The txEmpty flag is set by the tx ISR.
- *
- * DOES NOT WORK! DO NOT ENABLE THIS CODE. THE CD2401 DOES NOT COOPERATE!
- * The code is here to document that the output FIFO is NOT empty when
- * the CD2401 reports that the Tx buffer is empty.
- */
-int cd2401_drainOutput(
- int minor
-)
-{
- CD2401_RECORD_DRAIN_OUTPUT_INFO(( CD2401_Channel_Info[minor].txEmpty,
- CD2401_Channel_Info[minor].own_buf_A,
- CD2401_Channel_Info[minor].own_buf_B ));
-
- while( ! (CD2401_Channel_Info[minor].txEmpty &&
- CD2401_Channel_Info[minor].own_buf_A &&
- CD2401_Channel_Info[minor].own_buf_B) );
-
- /* Return something */
- return RTEMS_SUCCESSFUL;
-}
-#endif
-
-/*
- * _167Bug_pollRead
- *
- * Read a character from the 167Bug console, and return it. Return -1
- * if there is no character in the input FIFO.
- *
- * Input parameters:
- * minor - selected channel
- *
- * Output parameters: NONE
- *
- * Return value: char returned as positive signed int
- * -1 if no character is present in the input FIFO.
- *
- * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
- */
-int _167Bug_pollRead(
- int minor
-)
-{
- int char_not_available;
- unsigned char c;
- rtems_interrupt_level previous_level;
-
- /*
- * Redirection of .INSTAT does not work: 167-Bug crashes.
- * Switch the input stream to the specified port.
- * Make sure this is atomic code.
- */
- rtems_interrupt_disable( previous_level );
-
- __asm__ volatile( "movew %1, -(%%sp)\n\t"/* Channel */
- "trap #15\n\t" /* Trap to 167Bug */
- ".short 0x61\n\t" /* Code for .REDIR_I */
- "trap #15\n\t" /* Trap to 167Bug */
- ".short 0x01\n\t" /* Code for .INSTAT */
- "move %%cc, %0\n\t" /* Get condition codes */
- "andil #4, %0" /* Keep the Zero bit */
- : "=d" (char_not_available) : "d" (minor): "%%cc" );
-
- if (char_not_available) {
- rtems_interrupt_enable( previous_level );
- return -1;
- }
-
- /* Read the char and return it */
- __asm__ volatile( "subq.l #2,%%a7\n\t" /* Space for result */
- "trap #15\n\t" /* Trap to 167 Bug */
- ".short 0x00\n\t" /* Code for .INCHR */
- "moveb (%%a7)+, %0" /* Pop char into c */
- : "=d" (c) : );
-
- rtems_interrupt_enable( previous_level );
-
- return (int)c;
-}
-
-/*
- * _167Bug_pollWrite
- *
- * Output buffer through 167Bug. Returns only once every character has been
- * sent (polled output).
- *
- * Input parameters:
- * minor - selected channel
- * buf - output buffer
- * len - number of chars to output
- *
- * Output parameters: NONE
- *
- * Return value: IGNORED
- *
- * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
- */
-ssize_t _167Bug_pollWrite(
- int minor,
- const char *buf,
- size_t len
-)
-{
- const char *endbuf = buf + len;
-
- __asm__ volatile( "pea (%0)\n\t" /* endbuf */
- "pea (%1)\n\t" /* buf */
- "movew #0x21, -(%%sp)\n\t" /* Code for .OUTSTR */
- "movew %2, -(%%sp)\n\t" /* Channel */
- "trap #15\n\t" /* Trap to 167Bug */
- ".short 0x60" /* Code for .REDIR */
- :: "a" (endbuf), "a" (buf), "d" (minor) );
-
- /* Return something */
- return len;
-}
-
-/*
- * do_poll_read
- *
- * Input characters through 167Bug. Returns has soon as a character has been
- * received. Otherwise, if we wait for the number of requested characters, we
- * could be here forever!
- *
- * CR is converted to LF on input. The terminal should not send a CR/LF pair
- * when the return or enter key is pressed.
- *
- * Input parameters:
- * major - ignored. Should be the major number for this driver.
- * minor - selected channel.
- * arg->buffer - where to put the received characters.
- * arg->count - number of characters to receive before returning--Ignored.
- *
- * Output parameters:
- * arg->bytes_moved - the number of characters read. Always 1.
- *
- * Return value: RTEMS_SUCCESSFUL
- *
- * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
- */
-static rtems_status_code do_poll_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- rtems_libio_rw_args_t *rw_args = arg;
- int c;
-
- while( (c = _167Bug_pollRead (minor)) == -1 );
- rw_args->buffer[0] = (uint8_t)c;
- if( rw_args->buffer[0] == '\r' )
- rw_args->buffer[0] = '\n';
- rw_args->bytes_moved = 1;
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * do_poll_write
- *
- * Output characters through 167Bug. Returns only once every character has
- * been sent.
- *
- * CR is transmitted AFTER a LF on output.
- *
- * Input parameters:
- * major - ignored. Should be the major number for this driver.
- * minor - selected channel
- * arg->buffer - where to get the characters to transmit.
- * arg->count - the number of characters to transmit before returning.
- *
- * Output parameters:
- * arg->bytes_moved - the number of characters read
- *
- * Return value: RTEMS_SUCCESSFUL
- *
- * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
- */
-static rtems_status_code do_poll_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- rtems_libio_rw_args_t *rw_args = arg;
- uint32_t i;
-
- for( i = 0; i < rw_args->count; i++ ) {
- _167Bug_pollWrite(minor, &(rw_args->buffer[i]), 1);
- if ( rw_args->buffer[i] == '\n' )
- _167Bug_pollWrite(minor, &cr_char, 1);
- }
- rw_args->bytes_moved = i;
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * _BSP_output_char
- *
- * printk() function prototyped in bspIo.h. Does not use termios.
- */
-void _BSP_output_char(char c)
-{
- rtems_device_minor_number printk_minor;
-
- /*
- * Can't rely on console_initialize having been called before this function
- * is used.
- */
- if ( NVRAM_CONFIGURE )
- /* J1-4 is on, use NVRAM info for configuration */
- printk_minor = (nvram->console_printk_port & 0x30) >> 4;
- else
- printk_minor = PRINTK_MINOR;
-
- _167Bug_pollWrite(printk_minor, &c, 1);
-}
-
-/*
- ***************
- * BOILERPLATE *
- ***************
- *
- * All these functions are prototyped in rtems/c/src/lib/include/console.h.
- */
-
-/*
- * Initialize and register the device
- */
-rtems_device_driver console_initialize(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code status;
- rtems_device_minor_number console_minor;
-
- /*
- * Set up TERMIOS if needed
- */
- if ( NVRAM_CONFIGURE ) {
- /* J1-4 is on, use NVRAM info for configuration */
- console_minor = nvram->console_printk_port & 0x03;
-
- if ( nvram->console_mode & 0x01 )
- /* termios */
- rtems_termios_initialize ();
- }
- else {
- console_minor = CONSOLE_MINOR;
-#if CD2401_USE_TERMIOS == 1
- rtems_termios_initialize ();
-#endif
- }
-
- /*
- * Do device-specific initialization
- * Does not affect 167-Bug.
- */
- cd2401_initialize ();
-
- /*
- * Register the devices
- */
- status = rtems_io_register_name ("/dev/tty0", major, 0);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- status = rtems_io_register_name ("/dev/tty1", major, 1);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- status = rtems_io_register_name ("/dev/console", major, console_minor);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- status = rtems_io_register_name ("/dev/tty2", major, 2);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- status = rtems_io_register_name ("/dev/tty3", major, 3);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Open the device
- */
-rtems_device_driver console_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- static const rtems_termios_callbacks pollCallbacks = {
- NULL, /* firstOpen */
- NULL, /* lastClose */
- _167Bug_pollRead, /* pollRead */
- _167Bug_pollWrite, /* write */
- NULL, /* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- 0 /* outputUsesInterrupts */
- };
-
- static const rtems_termios_callbacks intrCallbacks = {
- cd2401_firstOpen, /* firstOpen */
- cd2401_lastClose, /* lastClose */
- NULL, /* pollRead */
- cd2401_write, /* write */
- cd2401_setAttributes, /* setAttributes */
- cd2401_stopRemoteTx, /* stopRemoteTx */
- cd2401_startRemoteTx, /* startRemoteTx */
- 1 /* outputUsesInterrupts */
- };
-
- if ( NVRAM_CONFIGURE )
- /* J1-4 is on, use NVRAM info for configuration */
- if ( nvram->console_mode & 0x01 )
- /* termios */
- if ( nvram->console_mode & 0x02 )
- /* interrupt-driven I/O */
- return rtems_termios_open (major, minor, arg, &intrCallbacks);
- else
- /* polled I/O */
- return rtems_termios_open (major, minor, arg, &pollCallbacks);
- else
- /* no termios -- default to polled I/O */
- return RTEMS_SUCCESSFUL;
-#if CD2401_USE_TERMIOS == 1
-#if CD2401_IO_MODE != 1
- else
- /* termios & polled I/O*/
- return rtems_termios_open (major, minor, arg, &pollCallbacks);
-#else
- else
- /* termios & interrupt-driven I/O*/
- return rtems_termios_open (major, minor, arg, &intrCallbacks);
-#endif
-#else
- else
- /* no termios -- default to polled I/O */
- return RTEMS_SUCCESSFUL;
-#endif
-}
-
-/*
- * Close the device
- */
-rtems_device_driver console_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- if ( NVRAM_CONFIGURE ) {
- /* J1-4 is on, use NVRAM info for configuration */
- if ( nvram->console_mode & 0x01 )
- /* termios */
- return rtems_termios_close (arg);
- else
- /* no termios */
- return RTEMS_SUCCESSFUL;
- }
-#if CD2401_USE_TERMIOS == 1
- else
- /* termios */
- return rtems_termios_close (arg);
-#else
- else
- /* no termios */
- return RTEMS_SUCCESSFUL;
-#endif
-}
-
-/*
- * Read from the device
- */
-rtems_device_driver console_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- if ( NVRAM_CONFIGURE ) {
- /* J1-4 is on, use NVRAM info for configuration */
- if ( nvram->console_mode & 0x01 )
- /* termios */
- return rtems_termios_read (arg);
- else
- /* no termios -- default to polled */
- return do_poll_read (major, minor, arg);
- }
-#if CD2401_USE_TERMIOS == 1
- else
- /* termios */
- return rtems_termios_read (arg);
-#else
- else
- /* no termios -- default to polled */
- return do_poll_read (major, minor, arg);
-#endif
-}
-
-/*
- * Write to the device
- */
-rtems_device_driver console_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- if ( NVRAM_CONFIGURE ) {
- /* J1-4 is on, use NVRAM info for configuration */
- if ( nvram->console_mode & 0x01 )
- /* termios */
- return rtems_termios_write (arg);
- else
- /* no termios -- default to polled */
- return do_poll_write (major, minor, arg);
- }
-#if CD2401_USE_TERMIOS == 1
- else
- /* termios */
- return rtems_termios_write (arg);
-#else
- else
- /* no termios -- default to polled */
- return do_poll_write (major, minor, arg);
-#endif
-}
-
-/*
- * Handle ioctl request.
- */
-rtems_device_driver console_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
-)
-{
- if ( NVRAM_CONFIGURE ) {
- /* J1-4 is on, use NVRAM info for configuration */
- if ( nvram->console_mode & 0x01 )
- /* termios */
- return rtems_termios_ioctl (arg);
- else
- /* no termios -- default to polled */
- return RTEMS_SUCCESSFUL;
- }
-#if CD2401_USE_TERMIOS == 1
- else
- /* termios */
- return rtems_termios_ioctl (arg);
-#else
- else
- /* no termios -- default to polled */
- return RTEMS_SUCCESSFUL;
-#endif
-}