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

4.104.114.84.95
Last change on this file since dbfa3148 was dbfa3148, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 10, 1998 at 3:43:18 PM

Patch from Quality Quorum <qqi@…>. Comments:

c/src/lib/libbsp/i386/pc386/console/console.c

assert() modified so it prints on selected console instead of
PC console

c/src/lib/libbsp/i386/pc386/console/inch.c

inch_sleep() modified, so it does not depend upon tmacros.h

c/src/lib/libbsp/i386/pc386/pc386dev/GDB.HOWTO

description updated

c/src/lib/libbsp/i386/pc386/startup/exit.c

last output before call to exit() will be printed properly on
serial console

c/src/lib/libbsp/i386/pc386/startup/irq.c

re-submitted bug fix for problem in irqs over 7.

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