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

4.104.114.84.95
Last change on this file since bd8c8b2a was bd8c8b2a, checked in by Joel Sherrill <joel.sherrill@…>, on 08/05/98 at 16:51:39

Patch from Eric Valette <valette@…> which brings the i386ex BSP
inline with the new IRQ structure.

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