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

4.115
Last change on this file since ba64905 was ba64905, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:35:34

2011-01-28 Joel Sherrill <joel.sherrilL@…>

  • clock/rtc.c, console/console.c, console/inch.c, console/outch.c, include/bsp.h, include/crt.h, ne2000/ne2000.c, startup/bspcmdline.c, startup/bspstart.c, startup/ldsegs.S, timer/timer.c, timer/timerisr.S: Fix typo where license said found in found in.
  • Property mode set to 100644
File size: 15.5 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 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
38#include <bsp.h>
39#include <bsp/irq.h>
40#include <rtems/libio.h>
41#include <termios.h>
42#include <rtems/termiostypes.h>
43#include <uart.h>
44#include <libcpu/cpuModel.h>
45
46#include <rtems/mw_uid.h>
47#include "mouse_parser.h"
48
49/*
50 * Possible value for console input/output :
51 *      BSP_CONSOLE_PORT_CONSOLE
52 *      BSP_UART_COM1
53 *      BSP_UART_COM2
54 *
55 * Note:
56 *   1. Currently BSPPrintkPort, cannot be assigned to COM2,
57 *      it will be fixed soon.
58 *
59 *   2. If both BSPConsolePort and BSPPrintkport are assigned
60 *      to same serial device it does not work that great
61 */
62
63#if (USE_COM1_AS_CONSOLE == 1)
64int BSPConsolePort = BSP_UART_COM1;
65int BSPPrintkPort  = BSP_UART_COM1;
66#else
67int BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
68int BSPPrintkPort  = BSP_CONSOLE_PORT_CONSOLE;
69#endif
70
71int BSPBaseBaud    = 115200;
72int BSPCmdBaud     = 9600;
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 int 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 int  rtems_kbpoll( void );
119
120static ssize_t
121ibmpc_console_write(int minor, const char *buf, size_t len)
122{
123  size_t count;
124  for (count = 0; count < len; count++)
125  {
126    _IBMPC_outch( buf[ count ] );
127    if( buf[ count ] == '\n')
128      _IBMPC_outch( '\r' );            /* LF = LF + CR */
129  }
130  return count;
131}
132
133int kbd_poll_read( int minor )
134{
135  if( rtems_kbpoll() )
136  {
137     int c = getch();
138     return c;
139  }
140  return -1;
141}
142
143/* provide default that does nothing */
144extern void
145BSP_runtime_console_select(int *, int *) __attribute__((weak));
146
147/* provide routine to select console; this
148 * is called very early so that early boot
149 * messages also make it to the redirected
150 * device.
151 */
152void
153BSP_console_select(void)
154{
155  const char* opt;
156
157  /*
158   * Check the command line for the type of mode the console is.
159   */
160  opt = bsp_cmdline_arg ("--console=");
161
162  if (opt)
163  {
164    const char* comma;
165   
166    opt += sizeof ("--console=") - 1;
167    if (strncmp (opt, "console", sizeof ("console") - 1) == 0)
168    {
169      BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
170      BSPPrintkPort  = BSP_CONSOLE_PORT_CONSOLE;
171    }
172    else if (strncmp (opt, "com1", sizeof ("com1") - 1) == 0)
173    {
174      BSPConsolePort = BSP_UART_COM1;
175      BSPPrintkPort  = BSP_UART_COM1;
176    }
177    else if (strncmp (opt, "com2", sizeof ("com2") - 1) == 0)
178    {
179      BSPConsolePort = BSP_UART_COM2;
180      BSPPrintkPort  = BSP_UART_COM2;
181    }
182
183    comma = strchr (opt, ',');
184
185    if (comma)
186    {
187      comma += 1;
188      if (strncmp (opt, "115200", sizeof ("115200") - 1) == 0)
189        BSPCmdBaud = 115200;
190      else if (strncmp (opt, "57600", sizeof ("57600") - 1) == 0)
191        BSPCmdBaud = 57600;
192      else if (strncmp (opt, "38400", sizeof ("38400") - 1) == 0)
193        BSPCmdBaud = 38400;
194      else if (strncmp (opt, "19200", sizeof ("19200") - 1) == 0)
195        BSPCmdBaud = 19200;
196      else if (strncmp (opt, "9600", sizeof ("9600") - 1) == 0)
197        BSPCmdBaud = 9600;
198      else if (strncmp (opt, "4800", sizeof ("4800") - 1) == 0)
199        BSPCmdBaud = 9600;
200    }
201  }
202
203  if ( BSP_runtime_console_select )
204    BSP_runtime_console_select(&BSPPrintkPort, &BSPConsolePort);
205
206#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
207  /*
208   * If no video card, fall back to serial port console
209   */
210#include <crt.h>
211  if((BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
212   && (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
213   && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
214    BSPConsolePort = BSP_UART_COM2;
215    BSPPrintkPort  = BSP_UART_COM1;
216  }
217#endif
218
219  if(BSPPrintkPort == BSP_UART_COM1)
220    {
221      printk("Initializing console on port COM1 %d-8-N-1\n\n", BSPCmdBaud);
222      printk("Warning : This will be the last message on console\n");
223
224      /*
225       * FIXME: cast below defeats the very idea of having
226       * function pointer types defined
227       */
228      BSP_output_char = (BSP_output_char_function_type)
229                          BSP_output_char_via_serial;
230      BSP_poll_char   = (BSP_polling_getchar_function_type)
231                          BSP_poll_char_via_serial;
232    }
233  else if(BSPPrintkPort != BSP_CONSOLE_PORT_CONSOLE)
234    {
235      printk("illegal assignement of printk channel");
236      /* just skip; at this early stage we don't want
237       * to call rtems_fatal_error_occurred().
238       */
239    }
240}
241
242/*-------------------------------------------------------------------------+
243| Console device driver INITIALIZE entry point.
244+--------------------------------------------------------------------------+
245| Initilizes the I/O console (keyboard + VGA display) driver.
246+--------------------------------------------------------------------------*/
247rtems_device_driver
248console_initialize(rtems_device_major_number major,
249                   rtems_device_minor_number minor,
250                   void                      *arg)
251{
252  rtems_status_code status;
253
254
255  /* Initialize the KBD interface */
256  kbd_init();
257
258  /*
259   * Set up TERMIOS
260   */
261  rtems_termios_initialize ();
262
263  /*
264   *  The video was initialized in the start.s code and does not need
265   *  to be reinitialized.
266   */
267
268  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
269    {
270      /* Install keyboard interrupt handler */
271      status = BSP_install_rtems_irq_handler(&console_isr_data);
272
273    if (!status)
274        {
275          printk("Error installing keyboard interrupt handler!\n");
276          rtems_fatal_error_occurred(status);
277        }
278
279      status = rtems_io_register_name("/dev/console", major, 0);
280      if (status != RTEMS_SUCCESSFUL)
281        {
282          printk("Error registering console device!\n");
283          rtems_fatal_error_occurred(status);
284        }
285      printk("Initialized console on port CONSOLE\n\n");
286    }
287  else
288    {
289      /*
290       * Do device-specific initialization
291       */
292      /* BSPCmdBaud-8-N-1 */
293      BSP_uart_init(BSPConsolePort, BSPCmdBaud, CHR_8_BITS, 0, 0, 0);
294
295      /* Set interrupt handler */
296      if(BSPConsolePort == BSP_UART_COM1)
297        {
298             console_isr_data.name = BSP_UART_COM1_IRQ;
299        console_isr_data.hdl  = BSP_uart_termios_isr_com1;
300
301        }
302      else
303           {
304          assert(BSPConsolePort == BSP_UART_COM2);
305          console_isr_data.name = BSP_UART_COM2_IRQ;
306          console_isr_data.hdl  = BSP_uart_termios_isr_com2;
307        }
308      status = BSP_install_rtems_irq_handler(&console_isr_data);
309
310      if (!status){
311          printk("Error installing serial console interrupt handler!\n");
312          rtems_fatal_error_occurred(status);
313      }
314      /*
315       * Register the device
316       */
317      status = rtems_io_register_name ("/dev/console", major, 0);
318      if (status != RTEMS_SUCCESSFUL)
319        {
320          printk("Error registering console device!\n");
321          rtems_fatal_error_occurred (status);
322        }
323
324      if(BSPConsolePort == BSP_UART_COM1)
325        {
326          printk("Initialized console on port COM1 %d-8-N-1\n\n", BSPCmdBaud);
327        }
328      else
329        {
330          printk("Initialized console on port COM2 %d-8-N-1\n\n", BSPCmdBaud);
331        }
332  }
333
334  if(BSPPrintkPort != BSP_CONSOLE_PORT_CONSOLE && BSPPrintkPort != BSP_UART_COM1)
335    {
336      printk("illegal assignement of printk channel");
337      rtems_fatal_error_occurred (status);
338    }
339
340  return RTEMS_SUCCESSFUL;
341} /* console_initialize */
342
343static int console_open_count = 0;
344
345static int console_last_close(int major, int minor, void *arg)
346{
347  BSP_remove_rtems_irq_handler (&console_isr_data);
348
349  return 0;
350}
351
352static int ser_console_first_open(int major, int minor, void *arg)
353{
354  /*
355   * Pass data area info down to driver
356   */
357  BSP_uart_termios_set(BSPConsolePort,
358                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
359
360  /* Enable interrupts  on channel */
361  BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
362
363  return 0;
364}
365
366/*-------------------------------------------------------------------------+
367| Console device driver OPEN entry point
368+--------------------------------------------------------------------------*/
369rtems_device_driver
370console_open(rtems_device_major_number major,
371                rtems_device_minor_number minor,
372                void                      *arg)
373{
374  rtems_status_code              status;
375  static rtems_termios_callbacks cb =
376  {
377    NULL,                     /* firstOpen */
378    console_last_close,       /* lastClose */
379    NULL,          /* pollRead */
380    BSP_uart_termios_write_com1, /* write */
381    conSetAttr,               /* setAttributes */
382    NULL,                     /* stopRemoteTx */
383    NULL,                     /* startRemoteTx */
384    1                         /* outputUsesInterrupts */
385  };
386
387  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
388    {
389
390      /* Let's set the routines for termios to poll the
391       * Kbd queue for data
392       */
393      cb.pollRead = kbd_poll_read;
394      cb.outputUsesInterrupts = 0;
395      /* write the "echo" if it is on */
396      cb.write = ibmpc_console_write;
397
398      cb.setAttributes = NULL;
399      ++console_open_count;
400      status = rtems_termios_open (major, minor, arg, &cb);
401      if(status != RTEMS_SUCCESSFUL)
402      {
403         printk("Error openning console device\n");
404      }
405      return status;
406    }
407
408  if(BSPConsolePort == BSP_UART_COM2)
409    {
410      cb.write = BSP_uart_termios_write_com2;
411    }
412
413  cb.firstOpen = ser_console_first_open;
414
415  status = rtems_termios_open (major, minor, arg, &cb);
416
417  if(status != RTEMS_SUCCESSFUL)
418    {
419      printk("Error openning console device\n");
420      return status;
421    }
422
423  return RTEMS_SUCCESSFUL;
424}
425
426/*-------------------------------------------------------------------------+
427| Console device driver CLOSE entry point
428+--------------------------------------------------------------------------*/
429rtems_device_driver
430console_close(rtems_device_major_number major,
431              rtems_device_minor_number minor,
432              void                      *arg)
433{
434   return rtems_termios_close (arg);
435} /* console_close */
436
437/*-------------------------------------------------------------------------+
438| Console device driver READ entry point.
439+--------------------------------------------------------------------------+
440| Read characters from the I/O console. We only have stdin.
441+--------------------------------------------------------------------------*/
442rtems_device_driver
443console_read(rtems_device_major_number major,
444             rtems_device_minor_number minor,
445             void                      *arg)
446{
447 return rtems_termios_read( arg );
448} /* console_read */
449
450/*-------------------------------------------------------------------------+
451| Console device driver WRITE entry point.
452+--------------------------------------------------------------------------+
453| Write characters to the I/O console. Stderr and stdout are the same.
454+--------------------------------------------------------------------------*/
455rtems_device_driver
456console_write(rtems_device_major_number major,
457              rtems_device_minor_number minor,
458              void                    * arg)
459{
460  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
461  char                  *buffer  = rw_args->buffer;
462  int                    maximum  = rw_args->count;
463
464  if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
465    {
466      return rtems_termios_write (arg);
467    }
468
469  /* write data to VGA */
470  ibmpc_console_write( minor, buffer, maximum );
471  rw_args->bytes_moved = maximum;
472  return RTEMS_SUCCESSFUL;
473} /* console_write */
474
475extern int vt_ioctl( unsigned int cmd, unsigned long arg);
476
477/*
478 * Handle ioctl request.
479 */
480rtems_device_driver
481console_control(rtems_device_major_number major,
482                rtems_device_minor_number minor,
483                void                      * arg
484)
485{
486        rtems_libio_ioctl_args_t *args = arg;
487        switch (args->command)
488        {
489           default:
490      if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
491          return rtems_termios_ioctl (arg);
492                break;
493
494      case MW_UID_REGISTER_DEVICE:
495      printk( "SerialMouse: reg=%s\n", args->buffer );
496      register_kbd_msg_queue( args->buffer, 0 );
497                break;
498
499      case MW_UID_UNREGISTER_DEVICE:
500      unregister_kbd_msg_queue( 0 );
501                break;
502   }
503        args->ioctl_return = 0;
504   return RTEMS_SUCCESSFUL;
505}
506
507static int
508conSetAttr(int minor, const struct termios *t)
509{
510  unsigned long baud, databits, parity, stopbits;
511
512  baud = rtems_termios_baud_to_number(t->c_cflag & CBAUD);
513  if ( baud > 115200 )
514    return RTEMS_INVALID_NUMBER;
515
516  if (t->c_cflag & PARENB) {
517    /* Parity is enabled */
518    if (t->c_cflag & PARODD) {
519      /* Parity is odd */
520      parity = PEN;
521    }
522    else {
523      /* Parity is even */
524      parity = PEN | EPS;
525    }
526  }
527  else {
528    /* No parity */
529    parity = 0;
530  }
531
532  switch (t->c_cflag & CSIZE) {
533    case CS5: databits = CHR_5_BITS; break;
534    case CS6: databits = CHR_6_BITS; break;
535    case CS7: databits = CHR_7_BITS; break;
536    default: /* just to avoid warnings -- all cases are covered. */
537    case CS8: databits = CHR_8_BITS; break;
538   }
539
540  if (t->c_cflag & CSTOPB) {
541    /* 2 stop bits */
542    stopbits = STB;
543  }
544  else {
545    /* 1 stop bit */
546    stopbits = 0;
547  }
548
549  BSP_uart_set_attributes(BSPConsolePort, baud, databits, parity, stopbits);
550 
551  return 0;
552}
553
554void keyboard_interrupt_wrapper(void *unused){
555  keyboard_interrupt();
556}
557
558/*
559 * BSP initialization
560 */
561
562BSP_output_char_function_type BSP_output_char =
563                       (BSP_output_char_function_type) _IBMPC_outch;
564
565BSP_polling_getchar_function_type BSP_poll_char = BSP_wait_polled_input;
Note: See TracBrowser for help on using the repository browser.