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
Line 
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| **************************************************************************
22| *  COPYRIGHT (c) 1989-1999.
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
27| *  http://www.rtems.com/license/LICENSE.
28| **************************************************************************
29|
30|  $Id$
31+--------------------------------------------------------------------------*/
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <assert.h>
36#include <unistd.h>
37#undef __assert
38void __assert (const char *file, int line, const char *msg);
39
40#include <bsp.h>
41#include <bsp/irq.h>
42#include <rtems/libio.h>
43#include <termios.h>
44#include <uart.h>
45#include <libcpu/cpuModel.h>
46
47#include <rtems/mw_uid.h>
48#include "mouse_parser.h"
49
50/*
51 * Possible value for console input/output :
52 *      BSP_CONSOLE_PORT_CONSOLE
53 *      BSP_UART_COM1
54 *      BSP_UART_COM2
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
62 */
63
64#if (USE_COM1_AS_CONSOLE == 1)
65int BSPConsolePort = BSP_UART_COM1;
66int BSPPrintkPort  = BSP_UART_COM1;
67#else
68int BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
69int BSPPrintkPort  = BSP_CONSOLE_PORT_CONSOLE;
70#endif
71
72int BSPBaseBaud    = 115200;
73
74extern BSP_polling_getchar_function_type BSP_poll_char;
75extern int getch( void );
76extern void kbd_init( void );
77
78/*-------------------------------------------------------------------------+
79| External Prototypes
80+--------------------------------------------------------------------------*/
81extern void keyboard_interrupt(void );
82extern void keyboard_interrupt_wrapper(void *);
83extern char BSP_wait_polled_input(void);
84extern void _IBMPC_initVideo(void);
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
91extern int rtems_kbpoll( void );
92
93static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
94                                                  keyboard_interrupt_wrapper,
95                                                  0,
96                                                  isr_on,
97                                                  isr_off,
98                                                  isr_is_on};
99
100static void
101isr_on(const rtems_irq_connect_data *unused)
102{
103  return;
104}
105
106static void
107isr_off(const rtems_irq_connect_data *unused)
108{
109  return;
110}
111
112static int
113isr_is_on(const rtems_irq_connect_data *irq)
114{
115  return BSP_irq_enabled_at_i8259s(irq->name);
116}
117
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
155void __assert (const char *file, int line, const char *msg)
156{
157    static   char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
158  unsigned char  ch;
159
160  /*
161   * Note we cannot call exit or printf from here,
162   * assert can fail inside ISR too
163   */
164
165   /*
166   * Close console
167   */
168  close(2);
169  close(1);
170  close(0);
171
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");
178  rtemsReboot();
179
180}
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
194  /* Initialize the KBD interface */
195  kbd_init();
196
197  /*
198   * Set up TERMIOS
199   */
200  rtems_termios_initialize ();
201
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
215  /*
216   *  The video was initialized in the start.s code and does not need
217   *  to be reinitialized.
218   */
219
220  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
221    {
222      /* Install keyboard interrupt handler */
223      status = BSP_install_rtems_irq_handler(&console_isr_data);
224
225    if (!status)
226        {
227          printk("Error installing keyboard interrupt handler!\n");
228          rtems_fatal_error_occurred(status);
229        }
230
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 */
245      BSP_uart_init(BSPConsolePort, 9600, CHR_8_BITS, 0, 0, 0);
246
247      /* Set interrupt handler */
248      if(BSPConsolePort == BSP_UART_COM1)
249        {
250             console_isr_data.name = BSP_UART_COM1_IRQ;
251        console_isr_data.hdl  = BSP_uart_termios_isr_com1;
252
253        }
254      else
255           {
256          assert(BSPConsolePort == BSP_UART_COM2);
257          console_isr_data.name = BSP_UART_COM2_IRQ;
258          console_isr_data.hdl  = BSP_uart_termios_isr_com2;
259        }
260      status = BSP_install_rtems_irq_handler(&console_isr_data);
261
262      if (!status){
263          printk("Error installing serial console interrupt handler!\n");
264          rtems_fatal_error_occurred(status);
265      }
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
276      if(BSPConsolePort == BSP_UART_COM1)
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        }
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        {
300           printk("illegal assignement of printk channel");
301         rtems_fatal_error_occurred (status);
302        }
303
304    }
305  return RTEMS_SUCCESSFUL;
306} /* console_initialize */
307
308static int console_open_count = 0;
309
310static int console_last_close(int major, int minor, void *arg)
311{
312  BSP_remove_rtems_irq_handler (&console_isr_data);
313
314  return 0;
315}
316
317/*-------------------------------------------------------------------------+
318| Console device driver OPEN entry point
319+--------------------------------------------------------------------------*/
320rtems_device_driver
321console_open(rtems_device_major_number major,
322                rtems_device_minor_number minor,
323                void                      *arg)
324{
325  rtems_status_code              status;
326  static rtems_termios_callbacks cb =
327  {
328    NULL,                     /* firstOpen */
329    console_last_close,       /* lastClose */
330    NULL,          /* pollRead */
331    BSP_uart_termios_write_com1, /* write */
332    conSetAttr,               /* setAttributes */
333    NULL,                     /* stopRemoteTx */
334    NULL,                     /* startRemoteTx */
335    1                         /* outputUsesInterrupts */
336  };
337
338  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
339    {
340
341      /* Let's set the routines for termios to poll the
342       * Kbd queue for data
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;
350      ++console_open_count;
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;
357    }
358
359  if(BSPConsolePort == BSP_UART_COM2)
360    {
361      cb.write = BSP_uart_termios_write_com2;
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   */
375  BSP_uart_termios_set(BSPConsolePort,
376                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
377
378  /* Enable interrupts  on channel */
379  BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
380
381  return RTEMS_SUCCESSFUL;
382}
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{
392   return rtems_termios_close (arg);
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{
405 return rtems_termios_read( arg );
406} /* console_read */
407
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;
420  int                    maximum  = rw_args->count;
421
422  if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
423    {
424      return rtems_termios_write (arg);
425    }
426
427  /* write data to VGA */
428  ibmpc_console_write( minor, buffer, maximum );
429  rw_args->bytes_moved = maximum;
430  return RTEMS_SUCCESSFUL;
431} /* console_write */
432
433extern int vt_ioctl( unsigned int cmd, unsigned long arg);
434
435/*
436 * Handle ioctl request.
437 */
438rtems_device_driver
439console_control(rtems_device_major_number major,
440                rtems_device_minor_number minor,
441                void                      * arg
442)
443{
444        rtems_libio_ioctl_args_t *args = arg;
445        switch (args->command)
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;
463}
464
465static int
466conSetAttr(int minor, const struct termios *t)
467{
468  unsigned long baud, databits, parity, stopbits;
469
470  switch (t->c_cflag & CBAUD)
471    {
472    case B50:
473      baud = 50;
474      break;
475    case B75:
476      baud = 75;
477      break;
478    case B110:
479      baud = 110;
480      break;
481    case B134:
482      baud = 134;
483      break;
484    case B150:
485      baud = 150;
486      break;
487    case B200:
488      baud = 200;
489      break;
490    case B300:
491      baud = 300;
492      break;
493    case B600:
494      baud = 600;
495      break;
496    case B1200:
497      baud = 1200;
498      break;
499    case B1800:
500      baud = 1800;
501      break;
502    case B2400:
503      baud = 2400;
504      break;
505    case B4800:
506      baud = 4800;
507      break;
508    case B9600:
509      baud = 9600;
510      break;
511    case B19200:
512      baud = 19200;
513      break;
514    case B38400:
515      baud = 38400;
516      break;
517    case B57600:
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
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  }
543
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;
548    default: /* just to avoid warnings -- all cases are covered. */
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);
562
563  return 0;
564}
565
566void keyboard_interrupt_wrapper(void *unused){
567  keyboard_interrupt();
568}
569
570/*
571 * BSP initialization
572 */
573
574BSP_output_char_function_type BSP_output_char =
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.