Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:58

0001 /*
0002  *  console.c  -- console I/O package
0003  *
0004  *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
0005  *
0006  * This code is based on the pc386 BSP console.c so the following
0007  * copyright also applies :
0008  *
0009  * (C) Copyright 1997 -
0010  * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
0011  *
0012  * Till Straumann, <strauman@slac.stanford.edu>, 12/20/2001
0013  * separate BSP specific stuff from generics...
0014  *
0015  * http://pandora.ist.utl.pt
0016  *
0017  * Instituto Superior Tecnico * Lisboa * PORTUGAL
0018  *  The license and distribution terms for this file may be
0019  *  found in the file LICENSE in this distribution or at
0020  *  http://www.rtems.org/license/LICENSE.
0021  */
0022 
0023 #include <stdlib.h>
0024 #include <assert.h>
0025 #include <inttypes.h>
0026 
0027 #include <bsp.h>
0028 #include <bsp/irq.h>
0029 #include <rtems/bspIo.h>
0030 #include <rtems/libio.h>
0031 #include <rtems/console.h>
0032 #include <rtems/termiostypes.h>
0033 #include <termios.h>
0034 #include <bsp/uart.h>
0035 #include <rtems/bspIo.h>  /* printk */
0036 
0037 /* Definitions for BSPConsolePort */
0038 /*
0039  * Possible value for console input/output :
0040  *    BSP_CONSOLE_PORT_CONSOLE
0041  *    BSP_UART_COM1
0042  *    BSP_UART_COM2
0043  */
0044 int BSPConsolePort = BSP_CONSOLE_PORT;
0045 
0046 int BSPBaseBaud    = BSP_UART_BAUD_BASE;
0047 
0048 /*
0049  * TERMIOS_OUTPUT_MODE should be a 'bspopts.h/configure'-able option;
0050  * we could even make it a link-time option (but that would require
0051  * small changes)...
0052  */
0053 #if defined(USE_POLLED_IO)
0054   #define TERMIOS_OUTPUT_MODE TERMIOS_POLLED
0055 #elif defined(USE_TASK_DRIVEN_IO)
0056   #define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN
0057 #else
0058   #define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN
0059 #endif
0060 
0061 /*-------------------------------------------------------------------------+
0062 | External Prototypes
0063 +--------------------------------------------------------------------------*/
0064 
0065 static int  conSetAttr(int minor, const struct termios *);
0066 
0067 typedef struct TtySTblRec_ {
0068   char          *name;
0069   rtems_irq_hdl  isr;
0070 } TtySTblRec, *TtySTbl;
0071 
0072 static TtySTblRec ttyS[]={
0073     { "/dev/ttyS0",
0074 #ifdef BSP_UART_IOBASE_COM1
0075       BSP_uart_termios_isr_com1
0076 #else
0077       0
0078 #endif
0079     },
0080     { "/dev/ttyS1",
0081 #ifdef BSP_UART_IOBASE_COM2
0082       BSP_uart_termios_isr_com2
0083 #else
0084       0
0085 #endif
0086     },
0087 };
0088 
0089 /*-------------------------------------------------------------------------+
0090 | Console device driver INITIALIZE entry point.
0091 +--------------------------------------------------------------------------+
0092 | Initilizes the I/O console (keyboard + VGA display) driver.
0093 +--------------------------------------------------------------------------*/
0094 rtems_device_driver console_initialize(
0095   rtems_device_major_number major,
0096   rtems_device_minor_number minor,
0097   void                      *arg
0098 )
0099 {
0100   rtems_status_code status;
0101 
0102   /*
0103    *  The video was initialized in the start.s code and does not need
0104    *  to be reinitialized.
0105    */
0106 
0107   /*
0108    * Set up TERMIOS
0109    */
0110   rtems_termios_initialize();
0111 
0112   /*
0113    * Do device-specific initialization
0114    */
0115 
0116   /* RTEMS calls this routine once with 'minor'==0; loop through
0117    * all known instances...
0118    */
0119 
0120   for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) {
0121     char *nm;
0122     /*
0123      * Skip ports (possibly not supported by BSP...) we have no ISR for
0124      */
0125     if ( ! ttyS[minor].isr )
0126       continue;
0127     /*
0128      * Register the device
0129      */
0130     status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor);
0131     if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor) {
0132       printk("Registering /dev/console as minor %" PRIu32 " (==%s)\n",
0133               minor,
0134               ttyS[minor].name);
0135       /* also register an alias */
0136       status = rtems_io_register_name ( (nm="/dev/console"), major, minor);
0137     }
0138 
0139     if (status != RTEMS_SUCCESSFUL) {
0140       printk("Error registering %s!\n",nm);
0141       rtems_fatal_error_occurred (status);
0142     }
0143   }
0144 
0145   return RTEMS_SUCCESSFUL;
0146 } /* console_initialize */
0147 
0148 #if !defined(USE_POLLED_IO)
0149 static int console_first_open(int major, int minor, void *arg)
0150 {
0151   rtems_status_code status;
0152 
0153   /* must not open a minor device we have no ISR for */
0154   assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr );
0155 
0156   /* BSP_CONSOLE_BAUD-8-N-1 */
0157   BSP_uart_init(minor, BSP_CONSOLE_BAUD, 0);
0158   status = BSP_uart_install_isr(minor, ttyS[minor].isr);
0159   if (!status) {
0160     printk("Error installing serial console interrupt handler for '%s'!\n",
0161       ttyS[minor].name);
0162     rtems_fatal_error_occurred(status);
0163   }
0164 
0165   /*
0166    * Pass data area info down to driver
0167    */
0168   BSP_uart_termios_set(minor, ((rtems_libio_open_close_args_t *)arg)->iop->data1);
0169 
0170   /* Enable interrupts  on channel */
0171   BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS);
0172 
0173   return 0;
0174 }
0175 #endif
0176 
0177 #if !defined(USE_POLLED_IO)
0178 static int console_last_close(int major, int minor, void *arg)
0179 {
0180   BSP_uart_remove_isr(minor, ttyS[minor].isr);
0181   return 0;
0182 }
0183 #endif
0184 
0185 /*-------------------------------------------------------------------------+
0186 | Console device driver OPEN entry point
0187 +--------------------------------------------------------------------------*/
0188 rtems_device_driver console_open(
0189   rtems_device_major_number major,
0190   rtems_device_minor_number minor,
0191   void                      *arg
0192 )
0193 {
0194   rtems_status_code              status;
0195   static rtems_termios_callbacks cb =
0196 #if defined(USE_POLLED_IO)
0197   {
0198      NULL,                              /* firstOpen */
0199      NULL,                              /* lastClose */
0200      NULL,                              /* pollRead */
0201      BSP_uart_termios_write_polled,     /* write */
0202      conSetAttr,                        /* setAttributes */
0203      NULL,                              /* stopRemoteTx */
0204      NULL,                              /* startRemoteTx */
0205      TERMIOS_POLLED                     /* outputUsesInterrupts */
0206   };
0207 #else
0208   {
0209      console_first_open,                /* firstOpen */
0210      console_last_close,                /* lastClose */
0211 #ifdef USE_TASK_DRIVEN_IO
0212      BSP_uart_termios_read_com,         /* pollRead */
0213 #else
0214      NULL,                              /* pollRead */
0215 #endif
0216      BSP_uart_termios_write_com,        /* write */
0217      conSetAttr,                        /* setAttributes */
0218      NULL,                              /* stopRemoteTx */
0219      NULL,                              /* startRemoteTx */
0220      TERMIOS_OUTPUT_MODE                /* outputUsesInterrupts */
0221   };
0222 #endif
0223 
0224   status = rtems_termios_open (major, minor, arg, &cb);
0225 
0226   if (status != RTEMS_SUCCESSFUL) {
0227     printk("Error opening console device\n");
0228     return status;
0229   }
0230 
0231   return RTEMS_SUCCESSFUL;
0232 }
0233 
0234 /*-------------------------------------------------------------------------+
0235 | Console device driver CLOSE entry point
0236 +--------------------------------------------------------------------------*/
0237 rtems_device_driver
0238 console_close(
0239   rtems_device_major_number major,
0240   rtems_device_minor_number minor,
0241   void                      *arg
0242 )
0243 {
0244   rtems_device_driver res = RTEMS_SUCCESSFUL;
0245 
0246   res =  rtems_termios_close (arg);
0247 
0248   return res;
0249 } /* console_close */
0250 
0251 /*-------------------------------------------------------------------------+
0252 | Console device driver READ entry point.
0253 +--------------------------------------------------------------------------+
0254 | Read characters from the I/O console. We only have stdin.
0255 +--------------------------------------------------------------------------*/
0256 rtems_device_driver console_read(
0257   rtems_device_major_number major,
0258   rtems_device_minor_number minor,
0259   void                      *arg
0260 )
0261 {
0262   return rtems_termios_read (arg);
0263 } /* console_read */
0264 
0265 /*-------------------------------------------------------------------------+
0266 | Console device driver WRITE entry point.
0267 +--------------------------------------------------------------------------+
0268 | Write characters to the I/O console. Stderr and stdout are the same.
0269 +--------------------------------------------------------------------------*/
0270 rtems_device_driver console_write(
0271   rtems_device_major_number major,
0272   rtems_device_minor_number minor,
0273   void                      *arg
0274 )
0275 {
0276   return rtems_termios_write (arg);
0277 } /* console_write */
0278 
0279 /*
0280  * Handle ioctl request.
0281  */
0282 rtems_device_driver console_control(
0283   rtems_device_major_number major,
0284   rtems_device_minor_number minor,
0285   void                      *arg
0286 )
0287 {
0288 /* does the BSP support break callbacks ? */
0289 #if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB)
0290   rtems_libio_ioctl_args_t  *ioa=arg;
0291   switch (ioa->command) {
0292     case BIOCSETBREAKCB: return BSP_uart_set_break_cb(minor, ioa);
0293     case BIOCGETBREAKCB: return BSP_uart_get_break_cb(minor, ioa);
0294     default:             break;
0295   }
0296 #endif
0297   return rtems_termios_ioctl (arg);
0298 }
0299 
0300 static int conSetAttr(
0301   int                   minor,
0302   const struct termios *t
0303 )
0304 {
0305   rtems_termios_baud_t baud;
0306 
0307   baud = rtems_termios_baud_to_number(t->c_ospeed);
0308   if ( baud > 115200 )
0309     rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
0310 
0311   BSP_uart_set_baud(minor, baud);
0312 
0313   return 0;
0314 }