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

4.104.114.84.95
Last change on this file since 45544f0 was 45544f0, checked in by Joel Sherrill <joel.sherrill@…>, on 10/27/99 at 20:50:57

Patch from Aleksey (Quality Quorum <qqi@…>) to
increase ease of application configuration of the pc386 BSP. This
patch allows switching the printk console to a serial port and
overriding bsp_start by making it a weak alias.

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