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

4.9
Last change on this file since 160e8fb was 160e8fb, checked in by Till Straumann <strauman@…>, on Nov 3, 2008 at 8:56:02 PM

2008-11-03 Till Straumann <strauman@…>

PR 1332: call BSP_uart_termios_set()/BSP_uart_intr_ctrl()
only from 'firstOpen' and only if this is a serial console.

  • Property mode set to 100644
File size: 13.4 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
38#include <bsp.h>
39#include <bsp/irq.h>
40#include <rtems/libio.h>
41#include <termios.h>
42#include <uart.h>
43#include <libcpu/cpuModel.h>
44
45#include <rtems/mw_uid.h>
46#include "mouse_parser.h"
47
48/*
49 * Possible value for console input/output :
50 *      BSP_CONSOLE_PORT_CONSOLE
51 *      BSP_UART_COM1
52 *      BSP_UART_COM2
53 *
54 * Note:
55 *   1. Currently BSPPrintkPort, cannot be assigned to COM2,
56 *      it will be fixed soon.
57 *
58 *   2. If both BSPConsolePort and BSPPrintkport are assigned
59 *      to same serial device it does not work that great
60 */
61
62#if (USE_COM1_AS_CONSOLE == 1)
63int BSPConsolePort = BSP_UART_COM1;
64int BSPPrintkPort  = BSP_UART_COM1;
65#else
66int BSPConsolePort = BSP_CONSOLE_PORT_CONSOLE;
67int BSPPrintkPort  = BSP_CONSOLE_PORT_CONSOLE;
68#endif
69
70int BSPBaseBaud    = 115200;
71
72extern BSP_polling_getchar_function_type BSP_poll_char;
73extern int getch( void );
74extern void kbd_init( void );
75
76/*-------------------------------------------------------------------------+
77| External Prototypes
78+--------------------------------------------------------------------------*/
79extern void keyboard_interrupt(void );
80extern void keyboard_interrupt_wrapper(void *);
81extern char BSP_wait_polled_input(void);
82extern void _IBMPC_initVideo(void);
83
84static int  conSetAttr(int minor, const struct termios *);
85static void isr_on(const rtems_irq_connect_data *);
86static void isr_off(const rtems_irq_connect_data *);
87static int  isr_is_on(const rtems_irq_connect_data *);
88
89extern int rtems_kbpoll( void );
90
91static rtems_irq_connect_data console_isr_data = {BSP_KEYBOARD,
92                                                  keyboard_interrupt_wrapper,
93                                                  0,
94                                                  isr_on,
95                                                  isr_off,
96                                                  isr_is_on};
97
98static void
99isr_on(const rtems_irq_connect_data *unused)
100{
101  return;
102}
103
104static void
105isr_off(const rtems_irq_connect_data *unused)
106{
107  return;
108}
109
110static int
111isr_is_on(const rtems_irq_connect_data *irq)
112{
113  return BSP_irq_enabled_at_i8259s(irq->name);
114}
115
116extern int  rtems_kbpoll( void );
117
118static int
119ibmpc_console_write(int minor, const char *buf, int len)
120{
121  int count;
122  for (count = 0; count < len; count++)
123  {
124    _IBMPC_outch( buf[ count ] );
125    if( buf[ count ] == '\n')
126      _IBMPC_outch( '\r' );            /* LF = LF + CR */
127  }
128  return 0;
129}
130
131int kbd_poll_read( int minor )
132{
133  if( rtems_kbpoll() )
134  {
135     int c = getch();
136     return c;
137  }
138  return -1;
139}
140
141/*-------------------------------------------------------------------------+
142| Console device driver INITIALIZE entry point.
143+--------------------------------------------------------------------------+
144| Initilizes the I/O console (keyboard + VGA display) driver.
145+--------------------------------------------------------------------------*/
146rtems_device_driver
147console_initialize(rtems_device_major_number major,
148                   rtems_device_minor_number minor,
149                   void                      *arg)
150{
151  rtems_status_code status;
152
153  /* Initialize the KBD interface */
154  kbd_init();
155
156  /*
157   * Set up TERMIOS
158   */
159  rtems_termios_initialize ();
160
161#ifdef RTEMS_RUNTIME_CONSOLE_SELECT
162  /*
163   * If no video card, fall back to serial port console
164   */
165#include <crt.h>
166  if((BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
167   && (*(unsigned char*) NB_MAX_ROW_ADDR == 0)
168   && (*(unsigned short*)NB_MAX_COL_ADDR == 0)) {
169    BSPConsolePort = BSP_UART_COM2;
170    BSPPrintkPort  = BSP_UART_COM1;
171  }
172#endif
173
174  /*
175   *  The video was initialized in the start.s code and does not need
176   *  to be reinitialized.
177   */
178
179  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
180    {
181      /* Install keyboard interrupt handler */
182      status = BSP_install_rtems_irq_handler(&console_isr_data);
183
184    if (!status)
185        {
186          printk("Error installing keyboard interrupt handler!\n");
187          rtems_fatal_error_occurred(status);
188        }
189
190      status = rtems_io_register_name("/dev/console", major, 0);
191      if (status != RTEMS_SUCCESSFUL)
192        {
193          printk("Error registering console device!\n");
194          rtems_fatal_error_occurred(status);
195        }
196      printk("Initialized console on port CONSOLE\n\n");
197    }
198  else
199    {
200      /*
201       * Do device-specific initialization
202       */
203      /* 9600-8-N-1 */
204      BSP_uart_init(BSPConsolePort, 9600, CHR_8_BITS, 0, 0, 0);
205
206      /* Set interrupt handler */
207      if(BSPConsolePort == BSP_UART_COM1)
208        {
209             console_isr_data.name = BSP_UART_COM1_IRQ;
210        console_isr_data.hdl  = BSP_uart_termios_isr_com1;
211
212        }
213      else
214           {
215          assert(BSPConsolePort == BSP_UART_COM2);
216          console_isr_data.name = BSP_UART_COM2_IRQ;
217          console_isr_data.hdl  = BSP_uart_termios_isr_com2;
218        }
219      status = BSP_install_rtems_irq_handler(&console_isr_data);
220
221      if (!status){
222          printk("Error installing serial console interrupt handler!\n");
223          rtems_fatal_error_occurred(status);
224      }
225      /*
226       * Register the device
227       */
228      status = rtems_io_register_name ("/dev/console", major, 0);
229      if (status != RTEMS_SUCCESSFUL)
230        {
231          printk("Error registering console device!\n");
232          rtems_fatal_error_occurred (status);
233        }
234
235      if(BSPConsolePort == BSP_UART_COM1)
236        {
237          printk("Initialized console on port COM1 9600-8-N-1\n\n");
238        }
239      else
240        {
241          printk("Initialized console on port COM2 9600-8-N-1\n\n");
242        }
243
244      if(BSPPrintkPort == BSP_UART_COM1)
245        {
246          printk("Warning : This will be the last message on console\n");
247
248          /*
249           * FIXME: cast below defeats the very idea of having
250           * function pointer types defined
251           */
252          BSP_output_char = (BSP_output_char_function_type)
253                              BSP_output_char_via_serial;
254          BSP_poll_char   = (BSP_polling_getchar_function_type)
255                              BSP_poll_char_via_serial;
256        }
257      else if(BSPPrintkPort != BSP_CONSOLE_PORT_CONSOLE)
258        {
259           printk("illegal assignement of printk channel");
260         rtems_fatal_error_occurred (status);
261        }
262
263    }
264  return RTEMS_SUCCESSFUL;
265} /* console_initialize */
266
267static int console_open_count = 0;
268
269static int console_last_close(int major, int minor, void *arg)
270{
271  BSP_remove_rtems_irq_handler (&console_isr_data);
272
273  return 0;
274}
275
276static int ser_console_first_open(int major, int minor, void *arg)
277{
278  /*
279   * Pass data area info down to driver
280   */
281  BSP_uart_termios_set(BSPConsolePort,
282                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
283
284  /* Enable interrupts  on channel */
285  BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
286
287  return 0;
288}
289
290/*-------------------------------------------------------------------------+
291| Console device driver OPEN entry point
292+--------------------------------------------------------------------------*/
293rtems_device_driver
294console_open(rtems_device_major_number major,
295                rtems_device_minor_number minor,
296                void                      *arg)
297{
298  rtems_status_code              status;
299  static rtems_termios_callbacks cb =
300  {
301    NULL,                     /* firstOpen */
302    console_last_close,       /* lastClose */
303    NULL,          /* pollRead */
304    BSP_uart_termios_write_com1, /* write */
305    conSetAttr,               /* setAttributes */
306    NULL,                     /* stopRemoteTx */
307    NULL,                     /* startRemoteTx */
308    1                         /* outputUsesInterrupts */
309  };
310
311  if(BSPConsolePort == BSP_CONSOLE_PORT_CONSOLE)
312    {
313
314      /* Let's set the routines for termios to poll the
315       * Kbd queue for data
316       */
317      cb.pollRead = kbd_poll_read;
318      cb.outputUsesInterrupts = 0;
319      /* write the "echo" if it is on */
320      cb.write = ibmpc_console_write;
321
322      cb.setAttributes = NULL;
323      ++console_open_count;
324      status = rtems_termios_open (major, minor, arg, &cb);
325      if(status != RTEMS_SUCCESSFUL)
326      {
327         printk("Error openning console device\n");
328      }
329      return status;
330    }
331
332  if(BSPConsolePort == BSP_UART_COM2)
333    {
334      cb.write = BSP_uart_termios_write_com2;
335    }
336
337  cb.firstOpen = ser_console_first_open;
338
339  status = rtems_termios_open (major, minor, arg, &cb);
340
341  if(status != RTEMS_SUCCESSFUL)
342    {
343      printk("Error openning console device\n");
344      return status;
345    }
346
347  return RTEMS_SUCCESSFUL;
348}
349
350/*-------------------------------------------------------------------------+
351| Console device driver CLOSE entry point
352+--------------------------------------------------------------------------*/
353rtems_device_driver
354console_close(rtems_device_major_number major,
355              rtems_device_minor_number minor,
356              void                      *arg)
357{
358   return rtems_termios_close (arg);
359} /* console_close */
360
361/*-------------------------------------------------------------------------+
362| Console device driver READ entry point.
363+--------------------------------------------------------------------------+
364| Read characters from the I/O console. We only have stdin.
365+--------------------------------------------------------------------------*/
366rtems_device_driver
367console_read(rtems_device_major_number major,
368             rtems_device_minor_number minor,
369             void                      *arg)
370{
371 return rtems_termios_read( arg );
372} /* console_read */
373
374/*-------------------------------------------------------------------------+
375| Console device driver WRITE entry point.
376+--------------------------------------------------------------------------+
377| Write characters to the I/O console. Stderr and stdout are the same.
378+--------------------------------------------------------------------------*/
379rtems_device_driver
380console_write(rtems_device_major_number major,
381              rtems_device_minor_number minor,
382              void                    * arg)
383{
384  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
385  char                  *buffer  = rw_args->buffer;
386  int                    maximum  = rw_args->count;
387
388  if(BSPConsolePort != BSP_CONSOLE_PORT_CONSOLE)
389    {
390      return rtems_termios_write (arg);
391    }
392
393  /* write data to VGA */
394  ibmpc_console_write( minor, buffer, maximum );
395  rw_args->bytes_moved = maximum;
396  return RTEMS_SUCCESSFUL;
397} /* console_write */
398
399extern int vt_ioctl( unsigned int cmd, unsigned long arg);
400
401/*
402 * Handle ioctl request.
403 */
404rtems_device_driver
405console_control(rtems_device_major_number major,
406                rtems_device_minor_number minor,
407                void                      * arg
408)
409{
410        rtems_libio_ioctl_args_t *args = arg;
411        switch (args->command)
412        {
413           default:
414      if( vt_ioctl( args->command, (unsigned long)args->buffer ) != 0 )
415          return rtems_termios_ioctl (arg);
416                break;
417
418      case MW_UID_REGISTER_DEVICE:
419      printk( "SerialMouse: reg=%s\n", args->buffer );
420      register_kbd_msg_queue( args->buffer, 0 );
421                break;
422
423      case MW_UID_UNREGISTER_DEVICE:
424      unregister_kbd_msg_queue( 0 );
425                break;
426   }
427        args->ioctl_return = 0;
428   return RTEMS_SUCCESSFUL;
429}
430
431static int
432conSetAttr(int minor, const struct termios *t)
433{
434  unsigned long baud, databits, parity, stopbits;
435
436  baud = termios_baud_to_number(t->c_cflag & CBAUD);
437  if ( baud > 115200 )
438    rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
439
440  if (t->c_cflag & PARENB) {
441    /* Parity is enabled */
442    if (t->c_cflag & PARODD) {
443      /* Parity is odd */
444      parity = PEN;
445    }
446    else {
447      /* Parity is even */
448      parity = PEN | EPS;
449    }
450  }
451  else {
452    /* No parity */
453    parity = 0;
454  }
455
456  switch (t->c_cflag & CSIZE) {
457    case CS5: databits = CHR_5_BITS; break;
458    case CS6: databits = CHR_6_BITS; break;
459    case CS7: databits = CHR_7_BITS; break;
460    default: /* just to avoid warnings -- all cases are covered. */
461    case CS8: databits = CHR_8_BITS; break;
462   }
463
464  if (t->c_cflag & CSTOPB) {
465    /* 2 stop bits */
466    stopbits = STB;
467  }
468  else {
469    /* 1 stop bit */
470    stopbits = 0;
471  }
472
473  BSP_uart_set_attributes(BSPConsolePort, baud, databits, parity, stopbits);
474
475  return 0;
476}
477
478void keyboard_interrupt_wrapper(void *unused){
479  keyboard_interrupt();
480}
481
482/*
483 * BSP initialization
484 */
485
486BSP_output_char_function_type BSP_output_char =
487                       (BSP_output_char_function_type) _IBMPC_outch;
488
489BSP_polling_getchar_function_type BSP_poll_char = BSP_wait_polled_input;
Note: See TracBrowser for help on using the repository browser.