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

4.104.114.84.95
Last change on this file since 711a2a1 was da38d8a, checked in by Joel Sherrill <joel.sherrill@…>, on 09/24/98 at 15:43:38

Removed superfluous initialization of PC video.

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