summaryrefslogtreecommitdiffstats
path: root/bsps/powerpc/shared/console/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/powerpc/shared/console/console.c')
-rw-r--r--bsps/powerpc/shared/console/console.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/bsps/powerpc/shared/console/console.c b/bsps/powerpc/shared/console/console.c
new file mode 100644
index 0000000000..f275683cc2
--- /dev/null
+++ b/bsps/powerpc/shared/console/console.c
@@ -0,0 +1,314 @@
+/*
+ * console.c -- console I/O package
+ *
+ * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * This code is based on the pc386 BSP console.c so the following
+ * copyright also applies :
+ *
+ * (C) Copyright 1997 -
+ * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+ *
+ * Till Straumann, <strauman@slac.stanford.edu>, 12/20/2001
+ * separate BSP specific stuff from generics...
+ *
+ * http://pandora.ist.utl.pt
+ *
+ * Instituto Superior Tecnico * Lisboa * PORTUGAL
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <rtems/libio.h>
+#include <rtems/console.h>
+#include <rtems/termiostypes.h>
+#include <termios.h>
+#include <bsp/uart.h>
+#include <rtems/bspIo.h> /* printk */
+
+/* Definitions for BSPConsolePort */
+/*
+ * Possible value for console input/output :
+ * BSP_CONSOLE_PORT_CONSOLE
+ * BSP_UART_COM1
+ * BSP_UART_COM2
+ */
+int BSPConsolePort = BSP_CONSOLE_PORT;
+
+int BSPBaseBaud = BSP_UART_BAUD_BASE;
+
+/*
+ * TERMIOS_OUTPUT_MODE should be a 'bspopts.h/configure'-able option;
+ * we could even make it a link-time option (but that would require
+ * small changes)...
+ */
+#if defined(USE_POLLED_IO)
+ #define TERMIOS_OUTPUT_MODE TERMIOS_POLLED
+#elif defined(USE_TASK_DRIVEN_IO)
+ #define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN
+#else
+ #define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN
+#endif
+
+/*-------------------------------------------------------------------------+
+| External Prototypes
++--------------------------------------------------------------------------*/
+
+static int conSetAttr(int minor, const struct termios *);
+
+typedef struct TtySTblRec_ {
+ char *name;
+ rtems_irq_hdl isr;
+} TtySTblRec, *TtySTbl;
+
+static TtySTblRec ttyS[]={
+ { "/dev/ttyS0",
+#ifdef BSP_UART_IOBASE_COM1
+ BSP_uart_termios_isr_com1
+#else
+ 0
+#endif
+ },
+ { "/dev/ttyS1",
+#ifdef BSP_UART_IOBASE_COM2
+ BSP_uart_termios_isr_com2
+#else
+ 0
+#endif
+ },
+};
+
+/*-------------------------------------------------------------------------+
+| Console device driver INITIALIZE entry point.
++--------------------------------------------------------------------------+
+| Initilizes the I/O console (keyboard + VGA display) driver.
++--------------------------------------------------------------------------*/
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * The video was initialized in the start.s code and does not need
+ * to be reinitialized.
+ */
+
+ /*
+ * Set up TERMIOS
+ */
+ rtems_termios_initialize();
+
+ /*
+ * Do device-specific initialization
+ */
+
+ /* RTEMS calls this routine once with 'minor'==0; loop through
+ * all known instances...
+ */
+
+ for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) {
+ char *nm;
+ /*
+ * Skip ports (possibly not supported by BSP...) we have no ISR for
+ */
+ if ( ! ttyS[minor].isr )
+ continue;
+ /*
+ * Register the device
+ */
+ status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor);
+ if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) {
+ printk("Registering /dev/console as minor %" PRIu32 " (==%s)\n",
+ minor,
+ ttyS[minor].name);
+ /* also register an alias */
+ status = rtems_io_register_name ( (nm="/dev/console"), major, minor);
+ }
+
+ if (status != RTEMS_SUCCESSFUL) {
+ printk("Error registering %s!\n",nm);
+ rtems_fatal_error_occurred (status);
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+} /* console_initialize */
+
+#if !defined(USE_POLLED_IO)
+static int console_first_open(int major, int minor, void *arg)
+{
+ rtems_status_code status;
+
+ /* must not open a minor device we have no ISR for */
+ assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr );
+
+ /* 9600-8-N-1 */
+ BSP_uart_init(minor, 9600, 0);
+ status = BSP_uart_install_isr(minor, ttyS[minor].isr);
+ if (!status) {
+ printk("Error installing serial console interrupt handler for '%s'!\n",
+ ttyS[minor].name);
+ rtems_fatal_error_occurred(status);
+ }
+
+ /*
+ * Pass data area info down to driver
+ */
+ BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1);
+
+ /* Enable interrupts on channel */
+ BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS);
+
+ return 0;
+}
+#endif
+
+#if !defined(USE_POLLED_IO)
+static int console_last_close(int major, int minor, void *arg)
+{
+ BSP_uart_remove_isr(minor, ttyS[minor].isr);
+ return 0;
+}
+#endif
+
+/*-------------------------------------------------------------------------+
+| Console device driver OPEN entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver console_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_status_code status;
+ static rtems_termios_callbacks cb =
+#if defined(USE_POLLED_IO)
+ {
+ NULL, /* firstOpen */
+ NULL, /* lastClose */
+ NULL, /* pollRead */
+ BSP_uart_termios_write_polled, /* write */
+ conSetAttr, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ TERMIOS_POLLED /* outputUsesInterrupts */
+ };
+#else
+ {
+ console_first_open, /* firstOpen */
+ console_last_close, /* lastClose */
+#ifdef USE_TASK_DRIVEN_IO
+ BSP_uart_termios_read_com, /* pollRead */
+#else
+ NULL, /* pollRead */
+#endif
+ BSP_uart_termios_write_com, /* write */
+ conSetAttr, /* setAttributes */
+ NULL, /* stopRemoteTx */
+ NULL, /* startRemoteTx */
+ TERMIOS_OUTPUT_MODE /* outputUsesInterrupts */
+ };
+#endif
+
+ status = rtems_termios_open (major, minor, arg, &cb);
+
+ if (status != RTEMS_SUCCESSFUL) {
+ printk("Error opening console device\n");
+ return status;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*-------------------------------------------------------------------------+
+| Console device driver CLOSE entry point
++--------------------------------------------------------------------------*/
+rtems_device_driver
+console_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_device_driver res = RTEMS_SUCCESSFUL;
+
+ res = rtems_termios_close (arg);
+
+ return res;
+} /* console_close */
+
+/*-------------------------------------------------------------------------+
+| Console device driver READ entry point.
++--------------------------------------------------------------------------+
+| Read characters from the I/O console. We only have stdin.
++--------------------------------------------------------------------------*/
+rtems_device_driver console_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_read (arg);
+} /* console_read */
+
+/*-------------------------------------------------------------------------+
+| Console device driver WRITE entry point.
++--------------------------------------------------------------------------+
+| Write characters to the I/O console. Stderr and stdout are the same.
++--------------------------------------------------------------------------*/
+rtems_device_driver console_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ return rtems_termios_write (arg);
+} /* console_write */
+
+/*
+ * Handle ioctl request.
+ */
+rtems_device_driver console_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+/* does the BSP support break callbacks ? */
+#if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB)
+ rtems_libio_ioctl_args_t *ioa=arg;
+ switch (ioa->command) {
+ case BIOCSETBREAKCB: return BSP_uart_set_break_cb(minor, ioa);
+ case BIOCGETBREAKCB: return BSP_uart_get_break_cb(minor, ioa);
+ default: break;
+ }
+#endif
+ return rtems_termios_ioctl (arg);
+}
+
+static int conSetAttr(
+ int minor,
+ const struct termios *t
+)
+{
+ rtems_termios_baud_t baud;
+
+ baud = rtems_termios_baud_to_number(t->c_ospeed);
+ if ( baud > 115200 )
+ rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
+
+ BSP_uart_set_baud(minor, baud);
+
+ return 0;
+}