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

4.104.114.84.95
Last change on this file since 67a2288 was 67a2288, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 23, 1998 at 10:02:34 PM

Patch from Eric VALETTE <valette@…>:

Here is a enhanced version of my previous patch. This patch enables
to potentially share the new interrupt management code for all Intel targets
(pc386, go32 and force386) bsp.

Note : this patch is complete only for pc386. It still needs to

be completed for go32 and force386. I carrefully checked
that anything needed is in for force386 (only some function
name changes for IDT manipulation and GDT segment
manipulation). But anyway I will not be able to test any
of theses targets...

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