diff options
Diffstat (limited to 'bsps/powerpc/shared/console/console.c')
-rw-r--r-- | bsps/powerpc/shared/console/console.c | 314 |
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; +} |