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

4.104.114.84.95
Last change on this file since b285860 was b285860, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 31, 1998 at 11:03:45 PM

Patch from Eric Valette <valette@…>:

Eric> NB : there is still a bug on PC386 serial line : exit does not
Eric> flush the remaining output queue. As this is not a bug in the
Eric> driver itself but somewhere in PC386 initialization/termios
Eric> relationship it will be part of another patch.

Eric> NB2 : As Emmanuel excerced the exception hanlder code, while
Eric> porting the SMC driver to the new BSD stack, we found a bug
Eric> in the exception handler : it shall not delete the current
Eric> thread in case we are running at interrupt level. This will
Eric> be part of another patch...

So here is the patch. This patch fixes the two problems mentionned above

+ it use vpath mechanism intead of copying the irq related files in

the right directory. This avoid to compile them each time and is
more homogenous with other Makefiles.

  • Property mode set to 100644
File size: 12.6 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-1998.
23| *  On-Line Applications Research Corporation (OAR).
24| *  Copyright assigned to U.S. Government, 1994.
25| *
26| *  The license and distribution terms for this file may be
27| *  found in found in the file LICENSE in this distribution or at
28| *  http://www.OARcorp.com/rtems/license.html.
29| **************************************************************************
30|
31|  $Id$
32+--------------------------------------------------------------------------*/
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <assert.h>
37
38#include <bsp.h>
39#include <irq.h>
40#include <rtems/libio.h>
41#include <termios.h>
42#include <pc386uart.h>
43#include <libcpu/cpuModel.h>
44
45/*
46 * Possible value for console input/output :
47 *      PC386_CONSOLE_PORT_CONSOLE
48 *      PC386_UART_COM1
49 *      PC386_UART_COM2
50 */
51
52int PC386ConsolePort = PC386_CONSOLE_PORT_CONSOLE;
53
54static int conSetAttr(int minor, const struct termios *);
55extern BSP_polling_getchar_function_type BSP_poll_char;
56
57/*-------------------------------------------------------------------------+
58| External Prototypes
59+--------------------------------------------------------------------------*/
60extern void     _IBMPC_keyboard_isr(void);
61extern void     _IBMPC_keyboard_isr_on(const rtems_irq_connect_data*);
62extern void     _IBMPC_keyboard_isr_off(const rtems_irq_connect_data*);
63extern int      _IBMPC_keyboard_isr_is_on(const rtems_irq_connect_data*);
64
65static rtems_irq_connect_data console_isr_data = {PC_386_KEYBOARD,
66                                                   _IBMPC_keyboard_isr,
67                                                   _IBMPC_keyboard_isr_on,
68                                                   _IBMPC_keyboard_isr_off,
69                                                   _IBMPC_keyboard_isr_is_on};
70                                                   
71
72extern rtems_boolean _IBMPC_scankey(char *);  /* defined in 'inch.c' */
73extern char BSP_wait_polled_input(void);
74extern void _IBMPC_initVideo(void);
75
76void console_reserve_resources(rtems_configuration_table *conf)
77{
78  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
79    {
80      rtems_termios_reserve_resources(conf, 1);
81    }
82  return;
83}
84
85void __assert(const char *file, int line, const char *msg)
86{
87  static   char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
88  unsigned char  ch;
89 
90  /*
91   * Note we cannot call exit or printf from here,
92   * assert can fail inside ISR too
93   */
94  /*
95   * Close console
96   */
97  __rtems_close(2);
98  __rtems_close(1);
99  __rtems_close(0);
100
101  printk("\nassert failed: %s: ", file);
102  printk("%d: ", line);
103  printk("%s\n\n", msg);
104  printk(exit_msg);
105  ch = BSP_poll_char();
106  printk("\n\n");
107  rtemsReboot();
108}
109
110
111/*-------------------------------------------------------------------------+
112| Console device driver INITIALIZE entry point.
113+--------------------------------------------------------------------------+
114| Initilizes the I/O console (keyboard + VGA display) driver.
115+--------------------------------------------------------------------------*/
116rtems_device_driver
117console_initialize(rtems_device_major_number major,
118                   rtems_device_minor_number minor,
119                   void                      *arg)
120{
121  rtems_status_code status;
122
123  /* Initialize video */
124  _IBMPC_initVideo();
125
126  if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
127    {
128
129      /* Install keyboard interrupt handler */
130      status = pc386_install_rtems_irq_handler(&console_isr_data);
131 
132      if (!status)
133        {
134          printk("Error installing keyboard interrupt handler!\n");
135          rtems_fatal_error_occurred(status);
136        }
137     
138      status = rtems_io_register_name("/dev/console", major, 0);
139      if (status != RTEMS_SUCCESSFUL)
140        {
141          printk("Error registering console device!\n");
142          rtems_fatal_error_occurred(status);
143        }
144      printk("Initialized console on port CONSOLE\n\n");
145    }
146  else
147    {
148      /*
149       * Set up TERMIOS
150       */
151      rtems_termios_initialize ();
152     
153      /*
154       * Do device-specific initialization
155       */
156     
157      /* 9600-8-N-1 */
158      PC386_uart_init(PC386ConsolePort, 9600, 0);
159     
160     
161      /* Set interrupt handler */
162      if(PC386ConsolePort == PC386_UART_COM1)
163        {
164          console_isr_data.name = PC386_UART_COM1_IRQ;
165          console_isr_data.hdl  = PC386_uart_termios_isr_com1;
166         
167        }
168      else
169        {
170          assert(PC386ConsolePort == PC386_UART_COM2);
171          console_isr_data.name = PC386_UART_COM2_IRQ;
172          console_isr_data.hdl  = PC386_uart_termios_isr_com2;
173        }
174
175      status = pc386_install_rtems_irq_handler(&console_isr_data);
176
177      if (!status){
178          printk("Error installing serial console interrupt handler!\n");
179          rtems_fatal_error_occurred(status);
180      }
181      /*
182       * Register the device
183       */
184      status = rtems_io_register_name ("/dev/console", major, 0);
185      if (status != RTEMS_SUCCESSFUL)
186        {
187          printk("Error registering console device!\n");
188          rtems_fatal_error_occurred (status);
189        }
190
191      if(PC386ConsolePort == PC386_UART_COM1)
192        {
193          printk("Initialized console on port COM1 9600-8-N-1\n\n");
194        }
195      else
196        {
197          printk("Initialized console on port COM2 9600-8-N-1\n\n");
198        }
199#define  PRINTK_ON_SERIAL     
200#ifdef PRINTK_ON_SERIAL
201      /*
202       * You can remove the follwoing tree lines if you want to have printk
203       * using the video console for output while printf use serial line.
204       * This may be convenient to debug the serial line driver itself...
205       */
206      printk("Warning : This will be the last message displayed on console\n");
207      BSP_output_char = (BSP_output_char_function_type) BSP_output_char_via_serial;
208      BSP_poll_char   = (BSP_polling_getchar_function_type) BSP_poll_char_via_serial;
209#endif 
210    }
211  return RTEMS_SUCCESSFUL;
212} /* console_initialize */
213
214
215static int console_open_count = 0;
216
217static void console_last_close()
218{
219  pc386_remove_rtems_irq_handler (&console_isr_data);
220}
221
222/*-------------------------------------------------------------------------+
223| Console device driver OPEN entry point
224+--------------------------------------------------------------------------*/
225rtems_device_driver
226console_open(rtems_device_major_number major,
227                rtems_device_minor_number minor,
228                void                      *arg)
229{
230  rtems_status_code              status;
231  static rtems_termios_callbacks cb = 
232  {
233    NULL,                     /* firstOpen */
234    console_last_close,       /* lastClose */
235    NULL,                     /* pollRead */
236    PC386_uart_termios_write_com1, /* write */
237    conSetAttr,               /* setAttributes */
238    NULL,                     /* stopRemoteTx */
239    NULL,                     /* startRemoteTx */
240    1                         /* outputUsesInterrupts */
241  };
242
243  if(PC386ConsolePort == PC386_CONSOLE_PORT_CONSOLE)
244    {
245      ++console_open_count;
246      return RTEMS_SUCCESSFUL;
247    }
248
249  if(PC386ConsolePort == PC386_UART_COM2)
250    {
251      cb.write = PC386_uart_termios_write_com2;
252    }
253
254  status = rtems_termios_open (major, minor, arg, &cb);
255
256  if(status != RTEMS_SUCCESSFUL)
257    {
258      printk("Error openning console device\n");
259      return status;
260    }
261
262  /*
263   * Pass data area info down to driver
264   */
265  PC386_uart_termios_set(PC386ConsolePort, 
266                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
267 
268  /* Enable interrupts  on channel */
269  PC386_uart_intr_ctrl(PC386ConsolePort, PC386_UART_INTR_CTRL_TERMIOS);
270
271  return RTEMS_SUCCESSFUL;
272}
273
274/*-------------------------------------------------------------------------+
275| Console device driver CLOSE entry point
276+--------------------------------------------------------------------------*/
277rtems_device_driver
278console_close(rtems_device_major_number major,
279              rtems_device_minor_number minor,
280              void                      *arg)
281{
282  rtems_device_driver res = RTEMS_SUCCESSFUL;
283
284  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
285    {
286      res =  rtems_termios_close (arg);
287    }
288  else {
289    if (--console_open_count == 0) { 
290      console_last_close();
291    }
292  }
293 
294  return res;
295} /* console_close */
296
297 
298/*-------------------------------------------------------------------------+
299| Console device driver READ entry point.
300+--------------------------------------------------------------------------+
301| Read characters from the I/O console. We only have stdin.
302+--------------------------------------------------------------------------*/
303rtems_device_driver
304console_read(rtems_device_major_number major,
305             rtems_device_minor_number minor,
306             void                      *arg)
307{
308  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
309  char                  *buffer  = rw_args->buffer;
310  int            count, maximum  = rw_args->count;
311
312  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
313    {
314      return rtems_termios_read (arg);
315    }
316 
317  for (count = 0; count < maximum; count++)
318  {
319    /* Get character */
320    buffer[count] = _IBMPC_inch_sleep();
321
322    /* Echo character to screen */
323    _IBMPC_outch(buffer[count]);
324    if (buffer[count] == '\r')
325      {
326        _IBMPC_outch('\n');  /* CR = CR + LF */
327      }
328
329    if (buffer[count] == '\n' || buffer[count] == '\r')
330    {
331      /* What if this goes past the end of the buffer?  We're hosed. [bhc] */
332      buffer[count++]  = '\n';
333      buffer[count]    = '\0';
334      break;
335    }
336  }
337 
338  rw_args->bytes_moved = count;
339  return ((count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED);
340} /* console_read */
341 
342
343/*-------------------------------------------------------------------------+
344| Console device driver WRITE entry point.
345+--------------------------------------------------------------------------+
346| Write characters to the I/O console. Stderr and stdout are the same.
347+--------------------------------------------------------------------------*/
348rtems_device_driver
349console_write(rtems_device_major_number major,
350              rtems_device_minor_number minor,
351              void                    * arg)
352{
353  rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg;
354  char                  *buffer  = rw_args->buffer;
355  int            count, maximum  = rw_args->count;
356
357  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
358    {
359      return rtems_termios_write (arg);
360    }
361 
362  for (count = 0; count < maximum; count++)
363  {
364    _IBMPC_outch(buffer[count]);
365    if (buffer[count] == '\n')
366      _IBMPC_outch('\r');            /* LF = LF + CR */
367  }
368
369  rw_args->bytes_moved = maximum;
370  return RTEMS_SUCCESSFUL;
371} /* console_write */
372
373
374 
375/*
376 * Handle ioctl request.
377 */
378rtems_device_driver
379console_control(rtems_device_major_number major,
380                rtems_device_minor_number minor,
381                void                      * arg
382)
383{ 
384  if(PC386ConsolePort != PC386_CONSOLE_PORT_CONSOLE)
385    {
386      return rtems_termios_ioctl (arg);
387    }
388
389  return RTEMS_SUCCESSFUL;
390}
391
392static int
393conSetAttr(int minor, const struct termios *t)
394{
395  int baud;
396
397  switch (t->c_cflag & CBAUD) 
398    {
399    case B50:   
400      baud = 50;
401      break;
402    case B75:   
403      baud = 75;       
404      break;
405    case B110: 
406      baud = 110;       
407      break;
408    case B134: 
409      baud = 134;       
410      break;
411    case B150: 
412      baud = 150;       
413      break;
414    case B200:
415      baud = 200;       
416      break;
417    case B300: 
418      baud = 300;
419      break;
420    case B600: 
421      baud = 600;       
422      break;
423    case B1200: 
424      baud = 1200;
425      break;
426    case B1800: 
427      baud = 1800;     
428      break;
429    case B2400: 
430      baud = 2400;
431      break;
432    case B4800: 
433      baud = 4800;
434      break;
435    case B9600: 
436      baud = 9600;
437      break;
438    case B19200:
439      baud = 19200;
440      break;
441    case B38400:
442      baud = 38400;
443      break;
444    case B57600:       
445      baud = 57600;
446      break;
447    case B115200:
448      baud = 115200;
449      break;
450    default:
451      baud = 0;
452      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
453      return 0;
454    }
455
456  PC386_uart_set_baud(PC386ConsolePort, baud);
457
458  return 0;
459}
460
461/*
462 * BSP initialization
463 */
464
465BSP_output_char_function_type BSP_output_char = 
466                       (BSP_output_char_function_type) _IBMPC_outch;
467
468BSP_polling_getchar_function_type BSP_poll_char = BSP_wait_polled_input;
469
470void BSP_emergency_output_init()
471{
472  _IBMPC_initVideo();
473}
474
475
Note: See TracBrowser for help on using the repository browser.