source: rtems/c/src/lib/libbsp/i386/pc386/console/console.c @ 36ffcf3

4.104.114.84.95
Last change on this file since 36ffcf3 was 36ffcf3, checked in by Joel Sherrill <joel.sherrill@…>, on 02/01/06 at 20:57:35

2006-02-01 Joel Sherrill <joel@…>

  • configure.ac, console/console.c: Add USE_COM1_AS_CONSOLE BSP option. This makes it easy to build the pc386 BSP in a configuration that corresponds to qemu with COM1 redirected to stdio.
  • Property mode set to 100644
File size: 14.9 KB
RevLine 
[7150f00f]1/*-------------------------------------------------------------------------+
2| console.c v1.1 - PC386 BSP - 1997/08/07
3+--------------------------------------------------------------------------+
4| This file contains the PC386 console I/O package.
5+--------------------------------------------------------------------------+
6| (C) Copyright 1997 -
7| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
8|
9| http://pandora.ist.utl.pt
10|
11| Instituto Superior Tecnico * Lisboa * PORTUGAL
12+--------------------------------------------------------------------------+
13| Disclaimer:
14|
15| This file is provided "AS IS" without warranty of any kind, either
16| expressed or implied.
17+--------------------------------------------------------------------------+
18| This code is based on:
19|   console.c,v 1.4 1995/12/19 20:07:23 joel Exp - go32 BSP
20| With the following copyright notice:
21| **************************************************************************
[08311cc3]22| *  COPYRIGHT (c) 1989-1999.
[6f9c75c3]23| *  On-Line Applications Research Corporation (OAR).
24| *
25| *  The license and distribution terms for this file may be
26| *  found in found in the file LICENSE in this distribution or at
[af2abc9e]27| *  http://www.rtems.com/license/LICENSE.
[7150f00f]28| **************************************************************************
[6f9c75c3]29|
30|  $Id$
[7150f00f]31+--------------------------------------------------------------------------*/
32
[dbfa3148]33#include <stdio.h>
[7150f00f]34#include <stdlib.h>
[5d18fb0]35#include <assert.h>
[c629812]36#include <unistd.h>
[0ebbf66]37#undef __assert
38void __assert (const char *file, int line, const char *msg);
[7150f00f]39
40#include <bsp.h>
[6daada6]41#include <bsp/irq.h>
[7150f00f]42#include <rtems/libio.h>
[5d18fb0]43#include <termios.h>
[0ebbf66]44#include <uart.h>
[2d7d605]45#include <libcpu/cpuModel.h>
[5d18fb0]46
[3cbb63a]47#include <rtems/mw_uid.h>
48#include "mouse_parser.h"
49
[de9edc4]50/*
51 * Possible value for console input/output :
[0ebbf66]52 *      BSP_CONSOLE_PORT_CONSOLE
53 *      BSP_UART_COM1
54 *      BSP_UART_COM2
[45544f0]55 *
56 * Note:
57 *   1. Currently BSPPrintkPort, cannot be assigned to COM2,
58 *      it will be fixed soon.
59 *
60 *   2. If both BSPConsolePort and BSPPrintkport are assigned
61 *      to same serial device it does not work that great
[b7e3949]62 */
63
[36ffcf3]64#if (USE_COM1_AS_CONSOLE == 1)
65int BSPConsolePort = BSP_UART_COM1;
66int BSPPrintkPort  = BSP_UART_COM1;
67#else
[0ebbf66]68int BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
[45544f0]69int BSPPrintkPort  = BSP_CONSOLE_PORT_CONSOLE;
[36ffcf3]70#endif
[0ebbf66]71
72int BSPBaseBaud    = 115200;
[5d18fb0]73
[69036586]74extern BSP_polling_getchar_function_type BSP_poll_char;
[3cbb63a]75extern int getch( void );
76extern void kbd_init( void );
[7150f00f]77
78/*-------------------------------------------------------------------------+
79| External Prototypes
80+--------------------------------------------------------------------------*/
[9dee9833]81extern void keyboard_interrupt(void );
82extern void keyboard_interrupt_wrapper(void *);
[8a496e46]83extern char BSP_wait_polled_input(void);
[0ebbf66]84extern void _IBMPC_initVideo(void);
[8a496e46]85
86static int  conSetAttr(int minor, const struct termios *);
87static void isr_on(const rtems_irq_connect_data *);
88static void isr_off(const rtems_irq_connect_data *);
89static int  isr_is_on(const rtems_irq_connect_data *);
90
[3cbb63a]91extern int rtems_kbpoll( void );
[67a2288]92
[0ebbf66]93static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
[9dee9833]94                                                  keyboard_interrupt_wrapper,
[68f4e5f]95                                                  0,
96                                                  isr_on,
97                                                  isr_off,
98                                                  isr_is_on};
[8a496e46]99
100static void
101isr_on(const rtems_irq_connect_data *unused)
102{
103  return;
104}
[6128a4a]105
[8a496e46]106static void
107isr_off(const rtems_irq_connect_data *unused)
108{
109  return;
110}
[7150f00f]111
[8a496e46]112static int
113isr_is_on(const rtems_irq_connect_data *irq)
114{
[0ebbf66]115  return BSP_irq_enabled_at_i8259s(irq->name);
[8a496e46]116}
[7150f00f]117
[3cbb63a]118extern char _IBMPC_inch(void);
119extern int  rtems_kbpoll( void );
120
121static int
122ibmpc_console_write(int minor, const char *buf, int len)
123{
124  int count;
125  for (count = 0; count < len; count++)
126  {
127    _IBMPC_outch( buf[ count ] );
128    if( buf[ count ] == '\n')
129      _IBMPC_outch( '\r' );            /* LF = LF + CR */
130  }
131  return 0;
132}
133
134int kbd_poll_read( int minor )
135{
136  if( rtems_kbpoll() )
137  {
138     int c = getch();
139     return c;
140  }
141  return -1;
142}
143
144/*
145static void*         termios_ttyp_console         = NULL;
146void enq_key( char key )
147{
148  if( termios_ttyp_console )
149  {
150          rtems_termios_enqueue_raw_characters(termios_ttyp_console, &key,1 );
151  }
152}
153*/
154
[0ebbf66]155void __assert (const char *file, int line, const char *msg)
[7150f00f]156{
[0ebbf66]157    static   char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
[dbfa3148]158  unsigned char  ch;
[6128a4a]159
[dbfa3148]160  /*
[6128a4a]161   * Note we cannot call exit or printf from here,
[dbfa3148]162   * assert can fail inside ISR too
163   */
[0ebbf66]164
165   /*
[b285860]166   * Close console
167   */
[97d6366]168  close(2);
169  close(1);
170  close(0);
[b285860]171
[69036586]172  printk("\nassert failed: %s: ", file);
173  printk("%d: ", line);
174  printk("%s\n\n", msg);
175  printk(exit_msg);
176  ch = BSP_poll_char();
177  printk("\n\n");
[dbfa3148]178  rtemsReboot();
[0ebbf66]179
[5d18fb0]180}
[7150f00f]181
182/*-------------------------------------------------------------------------+
183| Console device driver INITIALIZE entry point.
184+--------------------------------------------------------------------------+
185| Initilizes the I/O console (keyboard + VGA display) driver.
186+--------------------------------------------------------------------------*/
187rtems_device_driver
188console_initialize(rtems_device_major_number major,
189                   rtems_device_minor_number minor,
190                   void                      *arg)
191{
192  rtems_status_code status;
193
[3cbb63a]194  /* Initialize the KBD interface */
195  kbd_init();
196
197  /*
198   * Set up TERMIOS
199   */
200  rtems_termios_initialize ();
201
[cd66632]202#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
203  /*
204   * If no video card, fall back to serial port console
205   */
206#include <crt.h>
207  if((BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
208   && (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
209   && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
210    BSPConsolePort = BSP_UART_COM2;
211    BSPPrintkPort  = BSP_UART_COM1;
212  }
213#endif
214
[da38d8a]215  /*
216   *  The video was initialized in the start.s code and does not need
217   *  to be reinitialized.
218   */
[7150f00f]219
[0ebbf66]220  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
221    {
[5d18fb0]222      /* Install keyboard interrupt handler */
[0ebbf66]223      status = BSP_install_rtems_irq_handler(&console_isr_data);
[6128a4a]224
[3cbb63a]225    if (!status)
[5d18fb0]226        {
227          printk("Error installing keyboard interrupt handler!\n");
228          rtems_fatal_error_occurred(status);
229        }
[6128a4a]230
[5d18fb0]231      status = rtems_io_register_name("/dev/console", major, 0);
232      if (status != RTEMS_SUCCESSFUL)
233        {
234          printk("Error registering console device!\n");
235          rtems_fatal_error_occurred(status);
236        }
237      printk("Initialized console on port CONSOLE\n\n");
238    }
239  else
240    {
241      /*
242       * Do device-specific initialization
243       */
244      /* 9600-8-N-1 */
[664db30b]245      BSP_uart_init(BSPConsolePort, 9600, CHR_8_BITS, 0, 0, 0);
[6128a4a]246
[5d18fb0]247      /* Set interrupt handler */
[0ebbf66]248      if(BSPConsolePort == BSP_UART_COM1)
[3cbb63a]249        {
250             console_isr_data.name = BSP_UART_COM1_IRQ;
251        console_isr_data.hdl  = BSP_uart_termios_isr_com1;
[6128a4a]252
[3cbb63a]253        }
[5d18fb0]254      else
[3cbb63a]255           {
[0ebbf66]256          assert(BSPConsolePort == BSP_UART_COM2);
[3cbb63a]257          console_isr_data.name = BSP_UART_COM2_IRQ;
258          console_isr_data.hdl  = BSP_uart_termios_isr_com2;
259        }
[0ebbf66]260      status = BSP_install_rtems_irq_handler(&console_isr_data);
[69036586]261
262      if (!status){
263          printk("Error installing serial console interrupt handler!\n");
264          rtems_fatal_error_occurred(status);
265      }
[5d18fb0]266      /*
267       * Register the device
268       */
269      status = rtems_io_register_name ("/dev/console", major, 0);
270      if (status != RTEMS_SUCCESSFUL)
271        {
272          printk("Error registering console device!\n");
273          rtems_fatal_error_occurred (status);
274        }
275
[0ebbf66]276      if(BSPConsolePort == BSP_UART_COM1)
[5d18fb0]277        {
278          printk("Initialized console on port COM1 9600-8-N-1\n\n");
279        }
280      else
281        {
282          printk("Initialized console on port COM2 9600-8-N-1\n\n");
283        }
[45544f0]284
285      if(BSPPrintkPort == BSP_UART_COM1)
286        {
287          printk("Warning : This will be the last message on console\n");
288
289          /*
290           * FIXME: cast below defeats the very idea of having
291           * function pointer types defined
292           */
293          BSP_output_char = (BSP_output_char_function_type)
294                              BSP_output_char_via_serial;
295          BSP_poll_char   = (BSP_polling_getchar_function_type)
296                              BSP_poll_char_via_serial;
297        }
298      else if(BSPPrintkPort != BSP_CONSOLE_PORT_CONSOLE)
299        {
[499cdee]300           printk("illegal assignement of printk channel");
[45544f0]301         rtems_fatal_error_occurred (status);
302        }
303
[5d18fb0]304    }
[7150f00f]305  return RTEMS_SUCCESSFUL;
306} /* console_initialize */
307
[b285860]308static int console_open_count = 0;
309
[8a496e46]310static int console_last_close(int major, int minor, void *arg)
[b285860]311{
[0ebbf66]312  BSP_remove_rtems_irq_handler (&console_isr_data);
[8a496e46]313
314  return 0;
[b285860]315}
316
[7150f00f]317/*-------------------------------------------------------------------------+
318| Console device driver OPEN entry point
319+--------------------------------------------------------------------------*/
320rtems_device_driver
321console_open(rtems_device_major_number major,
[5d18fb0]322                rtems_device_minor_number minor,
323                void                      *arg)
[7150f00f]324{
[5d18fb0]325  rtems_status_code              status;
[6128a4a]326  static rtems_termios_callbacks cb =
[5d18fb0]327  {
328    NULL,                     /* firstOpen */
[b285860]329    console_last_close,       /* lastClose */
[3cbb63a]330    NULL,          /* pollRead */
[0ebbf66]331    BSP_uart_termios_write_com1, /* write */
[5d18fb0]332    conSetAttr,               /* setAttributes */
333    NULL,                     /* stopRemoteTx */
334    NULL,                     /* startRemoteTx */
335    1                         /* outputUsesInterrupts */
336  };
337
[0ebbf66]338  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
[5d18fb0]339    {
[3cbb63a]340
341      /* Let's set the routines for termios to poll the
[6128a4a]342       * Kbd queue for data
[3cbb63a]343       */
344      cb.pollRead = kbd_poll_read;
345      cb.outputUsesInterrupts = 0;
346      /* write the "echo" if it is on */
347      cb.write = ibmpc_console_write;
348
349      cb.setAttributes = NULL;
[b285860]350      ++console_open_count;
[3cbb63a]351      status = rtems_termios_open (major, minor, arg, &cb);
352      if(status != RTEMS_SUCCESSFUL)
353      {
354         printk("Error openning console device\n");
355      }
356      return status;
[5d18fb0]357    }
[7150f00f]358
[0ebbf66]359  if(BSPConsolePort == BSP_UART_COM2)
[5d18fb0]360    {
[0ebbf66]361      cb.write = BSP_uart_termios_write_com2;
[5d18fb0]362    }
363
364  status = rtems_termios_open (major, minor, arg, &cb);
365
366  if(status != RTEMS_SUCCESSFUL)
367    {
368      printk("Error openning console device\n");
369      return status;
370    }
371
372  /*
373   * Pass data area info down to driver
374   */
[6128a4a]375  BSP_uart_termios_set(BSPConsolePort,
[5d18fb0]376                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
[6128a4a]377
[5d18fb0]378  /* Enable interrupts  on channel */
[0ebbf66]379  BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
[5d18fb0]380
381  return RTEMS_SUCCESSFUL;
382}
[7150f00f]383
384/*-------------------------------------------------------------------------+
385| Console device driver CLOSE entry point
386+--------------------------------------------------------------------------*/
387rtems_device_driver
388console_close(rtems_device_major_number major,
389              rtems_device_minor_number minor,
390              void                      *arg)
391{
[3cbb63a]392   return rtems_termios_close (arg);
[7150f00f]393} /* console_close */
394
395/*-------------------------------------------------------------------------+
396| Console device driver READ entry point.
397+--------------------------------------------------------------------------+
398| Read characters from the I/O console. We only have stdin.
399+--------------------------------------------------------------------------*/
400rtems_device_driver
401console_read(rtems_device_major_number major,
402             rtems_device_minor_number minor,
403             void                      *arg)
404{
[3cbb63a]405 return rtems_termios_read( arg );
[7150f00f]406} /* console_read */
[6128a4a]407
[7150f00f]408/*-------------------------------------------------------------------------+
409| Console device driver WRITE entry point.
410+--------------------------------------------------------------------------+
411| Write characters to the I/O console. Stderr and stdout are the same.
412+--------------------------------------------------------------------------*/
413rtems_device_driver
414console_write(rtems_device_major_number major,
415              rtems_device_minor_number minor,
416              void                    * arg)
417{
418  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
419  char                  *buffer  = rw_args->buffer;
[3cbb63a]420  int                    maximum  = rw_args->count;
[5d18fb0]421
[0ebbf66]422  if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
[5d18fb0]423    {
424      return rtems_termios_write (arg);
425    }
[6128a4a]426
[3cbb63a]427  /* write data to VGA */
428  ibmpc_console_write( minor, buffer, maximum );
[7150f00f]429  rw_args->bytes_moved = maximum;
430  return RTEMS_SUCCESSFUL;
431} /* console_write */
432
[3cbb63a]433extern int vt_ioctl( unsigned int cmd, unsigned long arg);
[6128a4a]434
[5d18fb0]435/*
436 * Handle ioctl request.
437 */
[6128a4a]438rtems_device_driver
[7150f00f]439console_control(rtems_device_major_number major,
[5d18fb0]440                rtems_device_minor_number minor,
441                void                      * arg
442)
[6128a4a]443{
[3cbb63a]444        rtems_libio_ioctl_args_t *args = arg;
[6128a4a]445        switch (args->command)
[3cbb63a]446        {
447           default:
448      if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
449          return rtems_termios_ioctl (arg);
450                break;
451
452      case MW_UID_REGISTER_DEVICE:
453      printk( "SerialMouse: reg=%s\n", args->buffer );
454      register_kbd_msg_queue( args->buffer, 0 );
455                break;
456
457      case MW_UID_UNREGISTER_DEVICE:
458      unregister_kbd_msg_queue( 0 );
459                break;
460   }
461        args->ioctl_return = 0;
462   return RTEMS_SUCCESSFUL;
[5d18fb0]463}
464
465static int
466conSetAttr(int minor, const struct termios *t)
467{
[664db30b]468  unsigned long baud, databits, parity, stopbits;
[5d18fb0]469
[6128a4a]470  switch (t->c_cflag & CBAUD)
[5d18fb0]471    {
[6128a4a]472    case B50:
[5d18fb0]473      baud = 50;
474      break;
[6128a4a]475    case B75:
476      baud = 75;
[5d18fb0]477      break;
[6128a4a]478    case B110:
479      baud = 110;
[5d18fb0]480      break;
[6128a4a]481    case B134:
482      baud = 134;
[5d18fb0]483      break;
[6128a4a]484    case B150:
485      baud = 150;
[5d18fb0]486      break;
487    case B200:
[6128a4a]488      baud = 200;
[5d18fb0]489      break;
[6128a4a]490    case B300:
[5d18fb0]491      baud = 300;
492      break;
[6128a4a]493    case B600:
494      baud = 600;
[5d18fb0]495      break;
[6128a4a]496    case B1200:
[5d18fb0]497      baud = 1200;
498      break;
[6128a4a]499    case B1800:
500      baud = 1800;
[5d18fb0]501      break;
[6128a4a]502    case B2400:
[5d18fb0]503      baud = 2400;
504      break;
[6128a4a]505    case B4800:
[5d18fb0]506      baud = 4800;
507      break;
[6128a4a]508    case B9600:
[5d18fb0]509      baud = 9600;
510      break;
511    case B19200:
512      baud = 19200;
513      break;
514    case B38400:
515      baud = 38400;
516      break;
[6128a4a]517    case B57600:
[5d18fb0]518      baud = 57600;
519      break;
520    case B115200:
521      baud = 115200;
522      break;
523    default:
524      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
525      return 0;
526    }
527
[664db30b]528  if (t->c_cflag & PARENB) {
529    /* Parity is enabled */
530    if (t->c_cflag & PARODD) {
531      /* Parity is odd */
532      parity = PEN;
533    }
534    else {
535      /* Parity is even */
536      parity = PEN | EPS;
537    }
538  }
539  else {
540    /* No parity */
541    parity = 0;
542  }
[6128a4a]543
[664db30b]544  switch (t->c_cflag & CSIZE) {
545    case CS5: databits = CHR_5_BITS; break;
546    case CS6: databits = CHR_6_BITS; break;
547    case CS7: databits = CHR_7_BITS; break;
[9751c913]548    default: /* just to avoid warnings -- all cases are covered. */
[664db30b]549    case CS8: databits = CHR_8_BITS; break;
550   }
551
552  if (t->c_cflag & CSTOPB) {
553    /* 2 stop bits */
554    stopbits = STB;
555  }
556  else {
557    /* 1 stop bit */
558    stopbits = 0;
559  }
560
561  BSP_uart_set_attributes(BSPConsolePort, baud, databits, parity, stopbits);
[5d18fb0]562
563  return 0;
564}
565
[9dee9833]566void keyboard_interrupt_wrapper(void *unused){
567  keyboard_interrupt();
568}
569
[bd8c8b2a]570/*
571 * BSP initialization
572 */
573
[6128a4a]574BSP_output_char_function_type BSP_output_char =
[2d7d605]575                       (BSP_output_char_function_type) _IBMPC_outch;
576
577BSP_polling_getchar_function_type BSP_poll_char = BSP_wait_polled_input;
Note: See TracBrowser for help on using the repository browser.