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

4.104.114.84.95
Last change on this file since 8a496e46 was 8a496e46, checked in by Joel Sherrill <joel.sherrill@…>, on 09/23/98 at 13:20:34

Patch from Aleksey (Quality Quorum <qqi@…>):

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