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

4.115
Last change on this file since 3d4f749 was 1fef02ca, checked in by Joel Sherrill <joel.sherrill@…>, on 03/14/11 at 14:57:00

2011-03-14 Joel Sherrill <joel.sherrill@…>

PR 1762/cpukit

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