diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-19 06:28:01 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 13:08:32 +0200 |
commit | d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch) | |
tree | caa54b4229e86a68c84ab5961af34e087dce5302 /c/src/lib/libbsp/m68k/mvme167 | |
parent | bsps/powerpc: Move shared btimer support (diff) | |
download | rtems-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.am | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/m68k/mvme167/console/console-recording.h | 572 | ||||
-rw-r--r-- | c/src/lib/libbsp/m68k/mvme167/console/console.c | 1676 |
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 -} |