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

4.104.114.84.95
Last change on this file since 6bd0fe4 was 6bd0fe4, checked in by Joel Sherrill <joel.sherrill@…>, on 09/20/98 at 23:52:43

Patch from Eric Valette <valette@…>:

Compiled and booted without problem. However console was set on COM2.
At least for 4.0 it should be video :-)

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