summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/score603e/console/console.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/powerpc/score603e/console/console.c497
1 files changed, 497 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/score603e/console/console.c b/c/src/lib/libbsp/powerpc/score603e/console/console.c
new file mode 100644
index 0000000000..a3836bd6a8
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/score603e/console/console.c
@@ -0,0 +1,497 @@
+/*
+ * This file contains the TTY driver for the serial ports on the SCORE603e.
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * Currently only polled mode is supported.
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "consolebsp.h"
+
+#if (1)
+/*
+ * The Port Used for the Console interface is based upon which
+ * debugger is being used. The SDS debugger uses a binary
+ * interface on port 0 as part of the debugger. Thus port 0 can
+ * not be used as the console port for the SDS debugger.
+ */
+
+#if (SCORE603E_USE_SDS)
+#define USE_FOR_CONSOLE_DEF 1
+
+#elif (SCORE603E_USE_OPEN_FIRMWARE)
+#define USE_FOR_CONSOLE_DEF 0
+
+#elif (SCORE603E_USE_NONE)
+#define USE_FOR_CONSOLE_DEF 0
+
+#elif (SCORE603E_USE_DINK)
+#define USE_FOR_CONSOLE_DEF 0
+
+#else
+#error "SCORE603E CONSOLE.C -- what ROM monitor are you using"
+#endif
+
+#endif
+
+#if (0)
+extern int USE_FOR_CONSOLE;
+#endif
+
+int USE_FOR_CONSOLE = USE_FOR_CONSOLE_DEF;
+
+/*
+ *
+ * Console Device Driver Entry Points
+ */
+
+/* PAGE
+ *
+ * DEBUG_puts
+ *
+ * This should be safe in the event of an error. It attempts to insure
+ * that no TX empty interrupts occur while it is doing polled IO. Then
+ * it restores the state of that external interrupt.
+ *
+ * Input parameters:
+ * string - pointer to debug output string
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void DEBUG_puts(
+ char *string
+)
+{
+ char *s;
+ int console;
+ volatile rtems_unsigned8 *csr;
+
+ console = USE_FOR_CONSOLE;
+
+ csr = Ports_85C30[ console ].ctrl;
+
+ /* should disable interrupts here */
+
+ for ( s = string ; *s ; s++ )
+ outbyte_polled_85c30( csr, *s );
+
+ outbyte_polled_85c30( csr, '\r' );
+ outbyte_polled_85c30( csr, '\n' );
+
+ /* should enable interrupts here */
+}
+
+/* PAGE
+ *
+ * console_inbyte_nonblocking
+ *
+ * Console Termios polling input entry point.
+ */
+
+int console_inbyte_nonblocking(
+ int minor
+)
+{
+ int port = minor;
+
+ /*
+ * verify port Number
+ */
+ assert ( port < NUM_Z85C30_PORTS );
+
+ /*
+ * return a character from the 85c30 port.
+ */
+ return inbyte_nonblocking_85c30( &Ports_85C30[ port ] );
+}
+
+
+void console_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources( configuration, NUM_Z85C30_PORTS );
+}
+
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_close (arg);
+}
+
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_ioctl (arg);
+}
+
+
+
+/*
+ * Interrupt driven console IO
+ */
+
+#if CONSOLE_USE_INTERRUPTS
+
+rtems_isr console_isr(
+ rtems_vector_number vector
+)
+{
+ int i;
+
+ for (i=0; i < NUM_Z85C30_PORTS; i++){
+ ISR_85c30_Async( &Ports_85C30[i] );
+
+#if (0) /* XXX - TO TEST LOOP BACKS comment this out. */
+ if ( Ports_85C30[i].Chip->vector == vector ) {
+ ISR_85c30_Async( &Ports_85C30[i] );
+ }
+#endif
+ }
+}
+
+void console_exit()
+{
+ int i;
+ volatile Ring_buffer_t *buffer;
+ rtems_unsigned32 ch;
+
+ for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
+
+ buffer = &( Ports_85C30[i].Protocol->TX_Buffer);
+
+ while ( !Ring_buffer_Is_empty( buffer ) ) {
+ Ring_buffer_Remove_character( buffer, ch );
+ outbyte_polled_85c30( Ports_85C30[i].ctrl, ch );
+ }
+ }
+}
+
+void console_initialize_interrupts( void )
+{
+ volatile Ring_buffer_t *buffer;
+ Console_Protocol *protocol;
+ int i;
+
+ for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
+ protocol = Ports_85C30[i].Protocol;
+
+ /*
+ * Initialize the ring buffer and set to not transmitting.
+ */
+ buffer = &protocol->TX_Buffer;
+ Ring_buffer_Initialize( buffer );
+ protocol->Is_TX_active = FALSE;
+ }
+
+ /*
+ * Connect each vector to the interupt service routine.
+ */
+ for (i=0; i < NUM_Z85C30_CHIPS; i++)
+ set_vector( console_isr, Chips_85C30[i].vector, 1 );
+
+
+ atexit( console_exit );
+
+}
+void console_outbyte_interrupts(
+ const Port_85C30_info *Port,
+ char ch
+);
+
+/* XXXXXX */
+#endif
+
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * Routine called to initialize the console device driver.
+ */
+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;
+ int port, chip, p0,p1;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+ /*
+ * Register Device Names
+ */
+ console = USE_FOR_CONSOLE;
+ status = rtems_io_register_name( "/dev/console", major, console );
+ if (status != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred(status);
+
+ /*
+ * Initialize Hardware
+ */
+
+
+/*
+ * INITIALIZE_COM_PORTS is defined in the linker script. If it is
+ * true all serial chips on the board are to be reset at startup
+ * otherwise the reset is assumed to occur elsewhere (ie. in the
+ * debugger...)
+ */
+#if ( INITIALIZE_COM_PORTS )
+
+ /*
+ * Force to perform a hardware reset w/o
+ * Master interrupt enable via register 9
+ */
+
+ for (port=0; port<NUM_Z85C30_PORTS; port++){
+ p0 = port;
+ port++;
+ p1 = port;
+ Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
+ }
+#else
+ /* TEMP - To see if this makes a diff with the new ports.
+ * Never reset chip 1 when using the chip as a monitor
+ */
+ for (port=2; port<NUM_Z85C30_PORTS; port++){
+ p0 = port;
+ port++;
+ p1 = port;
+ Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
+ }
+#endif
+
+ /*
+ * Initialize each port.
+ * Note: the ports are numbered such that 0,1 are on the first chip
+ * 2,3 are on the second ....
+ */
+
+ for (port=0; port<NUM_Z85C30_PORTS; port++) {
+ chip = port >> 1;
+ initialize_85c30_port( &Ports_85C30[port] );
+ }
+
+#if CONSOLE_USE_INTERRUPTS
+ console_initialize_interrupts();
+#endif
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * console_write_support
+ *
+ * Console Termios output entry point.
+ *
+ */
+int console_write_support(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int nwrite = 0;
+ volatile rtems_unsigned8 *csr;
+ int port = minor;
+
+ /*
+ * verify port Number
+ */
+ assert ( port < NUM_Z85C30_PORTS );
+
+ /*
+ * Set the csr based upon the port number.
+ */
+ csr = Ports_85C30[ port ].ctrl;
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len) {
+#if (CONSOLE_USE_INTERRUPTS)
+ console_outbyte_interrupts( &Ports_85C30[ port ], *buf++ );
+#else
+ outbyte_polled_85c30( csr, *buf++ );
+#endif
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+/* PAGE
+ *
+ * console_open
+ *
+ * open a port as a termios console.
+ *
+ */
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code sc;
+ int port = minor;
+#if (CONSOLE_USE_INTERRUPTS)
+ rtems_libio_open_close_args_t *args = arg;
+ static const rtems_termios_callbacks intrCallbacks = {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ NULL, /* pollRead */
+ console_write_support, /* write */
+ NULL, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 1 /* outputUsesInterrupts */
+ };
+#else
+ static const rtems_termios_callbacks pollCallbacks = {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ console_inbyte_nonblocking, /* pollRead */
+ console_write_support, /* write */
+ NULL, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ 0 /* outputUsesInterrupts */
+ };
+#endif
+
+
+ /*
+ * Verify the minor number is valid.
+ */
+ if (minor < 0)
+ return RTEMS_INVALID_NUMBER;
+
+ if ( port > NUM_Z85C30_PORTS )
+ return RTEMS_INVALID_NUMBER;
+
+ /*
+ * open the port as a termios console driver.
+ */
+
+#if (CONSOLE_USE_INTERRUPTS)
+ sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
+
+ Ports_85C30[ minor ].Protocol->console_termios_data = args->iop->data1;
+#else
+ sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
+#endif
+
+ return sc;
+}
+
+
+#if (CONSOLE_USE_INTERRUPTS)
+
+/*
+ * console_outbyte_interrupts
+ *
+ * This routine transmits a character out.
+ *
+ * Input parameters:
+ * port - port to transmit character to
+ * ch - character to be transmitted
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+void console_outbyte_interrupts(
+ const Port_85C30_info *Port,
+ char ch
+)
+{
+ Console_Protocol *protocol;
+ rtems_unsigned32 isrlevel;
+
+ protocol = Port->Protocol;
+
+ /*
+ * If this is the first character then we need to prime the pump
+ */
+
+ if ( protocol->Is_TX_active == FALSE ) {
+
+ rtems_interrupt_disable( isrlevel );
+ protocol->Is_TX_active = TRUE;
+ outbyte_polled_85c30( Port->ctrl, ch );
+ rtems_interrupt_enable( isrlevel );
+
+ return;
+ }
+
+ while ( Ring_buffer_Is_full( &protocol->TX_Buffer ) );
+
+ Ring_buffer_Add_character( &protocol->TX_Buffer, ch );
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+