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

4.8
Last change on this file since c592a7f was c592a7f, checked in by Till Straumann <strauman@…>, on 11/03/08 at 20:54:33

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