summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/dmv177/console/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/dmv177/console/console.c')
-rw-r--r--c/src/lib/libbsp/powerpc/dmv177/console/console.c479
1 files changed, 479 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/dmv177/console/console.c b/c/src/lib/libbsp/powerpc/dmv177/console/console.c
new file mode 100644
index 0000000000..b1fc6f19e9
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/dmv177/console/console.c
@@ -0,0 +1,479 @@
+/*
+ * console.c
+ *
+ * This driver uses the termios pseudo driver.
+ *
+ * Currently only polled mode is supported.
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * 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: console.c
+ */
+
+#include <stdlib.h>
+#include <motorola/mc68681.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <assert.h>
+
+#define COM1 0
+#define COM2 1
+#define NUM_PORTS 2
+#define USE_FOR_CONSOLE COM1
+
+/*
+ * Define RDB_BREAK_IN if you need to be able to break in to the
+ * program with a ctrl-c during remote target debugging. If so,
+ * UART B will not be accessible from rtems during remote debugging
+ * if interrupt driven console is used. Does not affect UART A, polled
+ * mode or when the program runs without remote debugging.
+ */
+#define RDB_BREAK_IN
+
+/* Proto-types for Duart.C */
+void console_initialize_interrupts( void );
+char console_inbyte_polled( int port );
+void console_outbyte_polled(int port, char ch);
+rtems_isr console_isr (rtems_vector_number vector);
+volatile void init_mc88681();
+
+/* PAGE
+ *
+ * console_initialize
+ *
+ * This routine initializes the console IO driver.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+ int console;
+
+ /*
+ * 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
+ */
+
+ init_mc88681 ();
+
+#if CONSOLE_USE_INTERRUPTS
+ console_initialize_interrupts();
+#endif
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/* PAGE
+ *
+ * console_write_support
+ *
+ * This routine is Console Termios output entry point.
+ *
+ * Input parameters:
+ * minor - console device minor number
+ * buf - buffer of data to be written
+ * len - length of data to be written
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * int number of bytes written
+ */
+
+int console_write_support(
+ int minor,
+ const char *buf,
+ int len)
+{
+ int nwrite = 0;
+ int port = minor;
+
+ /*
+ * verify port Number
+ */
+ assert ( port < NUM_PORTS );
+
+ /*
+ * poll each byte in the string out of the port.
+ */
+ while (nwrite < len) {
+#if defined(CONSOLE_USE_INTERRUPTS)
+#else
+ console_outbyte_polled(port, *buf++);
+#endif
+ nwrite++;
+ }
+
+ /*
+ * return the number of bytes written.
+ */
+ return nwrite;
+}
+
+
+/* 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;
+ rtems_unsigned32 isrlevel;
+
+ rtems_interrupt_disable( isrlevel );
+ for ( s = string ; *s ; s++ )
+ console_outbyte_polled( 0, *s );
+
+ console_outbyte_polled( 0, '\r' );
+ console_outbyte_polled( 0, '\n' );
+ rtems_interrupt_enable( isrlevel );
+}
+
+
+/* PAGE
+ *
+ * console_open
+ *
+ * This routine is the console device driver open entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+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 defined(CONSOLE_USE_INTERRUPTS)
+ rtems_libio_open_close_args_t *args = arg;
+#endif
+
+ /*
+ * Verify the minor number is valid.
+ */
+ if (minor < 0)
+ return RTEMS_INVALID_NUMBER;
+
+ if ( port > NUM_PORTS )
+ return RTEMS_INVALID_NUMBER;
+
+ /*
+ * open the port as a termios console driver.
+ */
+#if defined(CONSOLE_USE_INTERRUPTS)
+ sc = rtems_termios_open (major, minor, arg,
+ NULL, NULL, NULL,
+ console_write_support, 0);
+#else
+ sc = rtems_termios_open (major, minor, arg, NULL, NULL,
+ console_inbyte_nonblocking,
+ console_write_support,
+ 0);
+#endif
+
+ return sc;
+}
+
+
+
+/* PAGE
+ *
+ * console_reserve_resources
+ *
+ * This routine reserves resources for each port which may be
+ * used as a console.
+ *
+ * Input parameters:
+ * configuration - rtems configuration table.
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources( configuration, NUM_PORTS );
+}
+
+/* PAGE
+ *
+ * console_close
+ *
+ * This routine is the console device driver close entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ */
+
+rtems_device_driver console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_close (arg);
+}
+
+/* PAGE
+ *
+ * console_read
+ *
+ * This routine is the console device driver read entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+ rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_read (arg);
+}
+
+/* PAGE
+ *
+ * console_write
+ *
+ * This routine is the console device driver write entry point.
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ return rtems_termios_write (arg);
+}
+
+/* PAGE
+ *
+ * console_control
+ *
+ * This routine is console device driver control entry point
+ *
+ * Input parameters:
+ * major - console device major number
+ * minor - console device minor number
+ * arg - pointer to optional device driver arguments
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * rtems_device_driver status code
+ *
+ */
+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
+
+/*
+ * Buffers between task and ISRs
+ */
+
+#include <ringbuf.h>
+extern Ring_buffer_t TX_Buffer[2];
+extern Ring_buffer_t RX_Buffer[2];
+
+/*
+ * console_inbyte_interrupts
+ *
+ * This routine reads a character from the UART.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values:
+ * character read from UART
+ */
+
+char console_inbyte_interrupts( int port )
+{
+ char ch;
+
+ while ( Ring_buffer_Is_empty( &RX_Buffer[ port ] ) );
+
+ Ring_buffer_Remove_character( &RX_Buffer[ port ], ch );
+ return ch;
+}
+
+/*
+ * 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(
+ int port,
+ char ch
+)
+{
+ /*
+ * If this is the first character then we need to prime the pump
+ */
+
+ if ( Is_TX_active[ port ] == FALSE ) {
+ Is_TX_active[ port ] = TRUE;
+ console_outbyte_polled( port, ch );
+ return;
+ }
+
+ while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) );
+
+ Ring_buffer_Add_character( &TX_Buffer[ port ], ch );
+}
+
+/*
+ * console_exit
+ *
+ * This routine allows the console to exit by masking its associated interrupt
+ * vectors.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * Return values: NONE
+ */
+
+void console_exit()
+{
+ volatile unsigned char *_addr;
+ int port;
+
+ /*
+ * Although the interrupts for the UART are unmasked, the PIL is set to
+ * disable all external interrupts. So we might as well do this first.
+ */
+
+ /* ??? Mask All UART Interrupts */
+
+ for (port = MC68681_PORT_A; port <= MC68681_PORT_B; port++) {
+ while (!Ring_buffer_Is_empty (&TX_Buffer[port])) {
+ Ring_buffer_Remove_character (&TX_Buffer[port],ch);
+ console_outbyte_polled (port,ch);
+ }
+ }
+
+ /*
+ * Now wait for all the data to actually get out ... the send register
+ * should be empty.
+ */
+ _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);
+ while (!(*_addr & MC68681_TX_EMPTY));
+
+ _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);
+ while (!(*_addr & MC68681_TX_EMPTY));
+}
+#endif /* CONSOLE_USE_INTERRUPTS */
+
+
+