source: rtems/c/src/lib/libbsp/powerpc/shared/console/console.c @ 8e861444

4.104.114.95
Last change on this file since 8e861444 was 8e861444, checked in by Till Straumann <strauman@…>, on Mar 20, 2008 at 6:50:14 AM

2008-03-19 Till Straumann <strauman@…>

  • shared/console/console.c, shared/console/uart.c, shared/console/uart.h: added support for task-driven console.
  • Property mode set to 100644
File size: 9.5 KB
Line 
1/*
2 *  console.c  -- console I/O package
3 *
4 *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
5 *
6 * This code is based on the pc386 BSP console.c so the following
7 * copyright also applies :
8 *
9 * (C) Copyright 1997 -
10 * - NavIST Group - Real-Time Distributed Systems and Industrial Automation
11 *
12 * Till Straumann, <strauman@slac.stanford.edu>, 12/20/2001
13 * separate BSP specific stuff from generics...
14 *
15 * http://pandora.ist.utl.pt
16 *
17 * Instituto Superior Tecnico * Lisboa * PORTUGAL
18 *  The license and distribution terms for this file may be
19 *  found in found in the file LICENSE in this distribution or at
20 *  http://www.rtems.com/license/LICENSE.
21 *
22 * $Id$
23 */
24
25#include <stdlib.h>
26#include <assert.h>
27#include <stdlib.h>
28
29extern int close(int fd);
30
31#include <bsp.h>
32#include <bsp/irq.h>
33#include <rtems/bspIo.h>
34#include <rtems/libio.h>
35#include <rtems/termiostypes.h>
36#include <termios.h>
37#include <bsp/uart.h>
38#include <rtems/bspIo.h>        /* printk */
39
40/* Definitions for BSPConsolePort */
41/*
42 * Possible value for console input/output :
43 *      BSP_CONSOLE_PORT_CONSOLE
44 *      BSP_UART_COM1
45 *      BSP_UART_COM2
46 */
47int BSPConsolePort = BSP_CONSOLE_PORT;
48
49int BSPBaseBaud    = BSP_UART_BAUD_BASE;
50
51/*
52 * TERMIOS_OUTPUT_MODE should be a 'bspopts.h/configure'-able option;
53 * we could even make it a link-time option (but that would require
54 * small changes)...
55 */
56#ifndef TERMIOS_OUTPUT_MODE
57#if 1
58#define TERMIOS_OUTPUT_MODE TERMIOS_IRQ_DRIVEN
59#else
60#define TERMIOS_OUTPUT_MODE TERMIOS_TASK_DRIVEN
61#endif
62#endif
63
64#if ! defined(USE_POLLED_IO) && (TERMIOS_OUTPUT_MODE == TERMIOS_POLLED)
65#define USE_POLLED_IO
66#endif
67
68/*-------------------------------------------------------------------------+
69| External Prototypes
70+--------------------------------------------------------------------------*/
71
72static int  conSetAttr(int minor, const struct termios *);
73
74typedef struct TtySTblRec_ {
75                char          *name;
76                rtems_irq_hdl isr;
77} TtySTblRec, *TtySTbl;               
78
79static TtySTblRec ttyS[]={
80                { "/dev/ttyS0",
81#ifdef BSP_UART_IOBASE_COM1
82                  BSP_uart_termios_isr_com1
83#else
84                  0
85#endif
86                },
87                { "/dev/ttyS1",
88#ifdef BSP_UART_IOBASE_COM2
89                  BSP_uart_termios_isr_com2
90#else
91                  0
92#endif
93                },
94};
95
96/*-------------------------------------------------------------------------+
97| Console device driver INITIALIZE entry point.
98+--------------------------------------------------------------------------+
99| Initilizes the I/O console (keyboard + VGA display) driver.
100+--------------------------------------------------------------------------*/
101rtems_device_driver
102console_initialize(rtems_device_major_number major,
103                   rtems_device_minor_number minor,
104                   void                      *arg)
105{
106  rtems_status_code status;
107
108  /*
109   *  The video was initialized in the start.s code and does not need
110   *  to be reinitialized.
111   */
112
113  /*
114   * Set up TERMIOS
115   */
116  rtems_termios_initialize ();
117
118  /*
119   * Do device-specific initialization
120   */
121
122  /* RTEMS calls this routine once with 'minor'==0; loop through
123   * all known instances...
124   */
125
126  for (minor=0; minor < sizeof(ttyS)/sizeof(ttyS[0]); minor++) {
127        char *nm;
128          /*
129           * Skip ports (possibly not supported by BSP...) we have no ISR for
130           */
131          if ( ! ttyS[minor].isr )
132                continue;
133          /*
134           * Register the device
135           */
136          status = rtems_io_register_name ((nm=ttyS[minor].name), major, minor);
137          if ( RTEMS_SUCCESSFUL==status && BSPConsolePort == minor)
138                {
139                  printk("Registering /dev/console as minor %d (==%s)\n",
140                                                        minor,
141                                                        ttyS[minor].name);
142                  /* also register an alias */
143                  status = rtems_io_register_name (
144                                                        (nm="/dev/console"),
145                                                        major,
146                                                        minor);
147                }
148          if (status != RTEMS_SUCCESSFUL)
149                {
150                  printk("Error registering %s!\n",nm);
151                  rtems_fatal_error_occurred (status);
152                }
153  }
154
155  return RTEMS_SUCCESSFUL;
156} /* console_initialize */
157
158static int console_first_open(int major, int minor, void *arg)
159{
160  rtems_status_code status;
161
162          /* must not open a minor device we have no ISR for */
163          assert( minor>=0 && minor < sizeof(ttyS)/sizeof(ttyS[0]) && ttyS[minor].isr );
164
165          /* 9600-8-N-1 */
166          BSP_uart_init(minor, 9600, 0);
167          status = BSP_uart_install_isr(minor, ttyS[minor].isr);
168          if (!status)
169                {
170                  printk("Error installing serial console interrupt handler for '%s'!\n",
171                                ttyS[minor].name);
172                  rtems_fatal_error_occurred(status);
173                }
174          return 0;
175}
176
177static int console_last_close(int major, int minor, void *arg)
178{
179  BSP_uart_remove_isr(minor, ttyS[minor].isr);
180  return 0;
181}
182
183/*-------------------------------------------------------------------------+
184| Console device driver OPEN entry point
185+--------------------------------------------------------------------------*/
186rtems_device_driver
187console_open(rtems_device_major_number major,
188                rtems_device_minor_number minor,
189                void                      *arg)
190{
191  rtems_status_code              status;
192  static rtems_termios_callbacks cb =
193#if defined(USE_POLLED_IO)
194  { 
195     NULL,                              /* firstOpen */
196     NULL,                              /* lastClose */
197     NULL,                              /* pollRead */
198     BSP_uart_termios_write_polled,     /* write */
199     conSetAttr,                        /* setAttributes */
200     NULL,                              /* stopRemoteTx */
201     NULL,                              /* startRemoteTx */
202     TERMIOS_POLLED                     /* outputUsesInterrupts */
203  };
204#else
205  { 
206     console_first_open,                /* firstOpen */
207     console_last_close,                /* lastClose */
208#if ( TERMIOS_OUTPUT_MODE == TERMIOS_TASK_DRIVEN )
209     BSP_uart_termios_read_com,         /* pollRead */
210#else
211     NULL,                              /* pollRead */
212#endif
213     BSP_uart_termios_write_com,        /* write */
214     conSetAttr,                        /* setAttributes */
215     NULL,                              /* stopRemoteTx */
216     NULL,                              /* startRemoteTx */
217     TERMIOS_OUTPUT_MODE                /* outputUsesInterrupts */
218  };
219#endif
220
221  status = rtems_termios_open (major, minor, arg, &cb);
222
223  if(status != RTEMS_SUCCESSFUL)
224    {
225      printk("Error opening console device\n");
226      return status;
227    }
228
229  /*
230   * Pass data area info down to driver
231   */
232  BSP_uart_termios_set(minor,
233                         ((rtems_libio_open_close_args_t *)arg)->iop->data1);
234  /* Enable interrupts  on channel */
235  BSP_uart_intr_ctrl(minor, BSP_UART_INTR_CTRL_TERMIOS);
236
237  return RTEMS_SUCCESSFUL;
238}
239
240/*-------------------------------------------------------------------------+
241| Console device driver CLOSE entry point
242+--------------------------------------------------------------------------*/
243rtems_device_driver
244console_close(rtems_device_major_number major,
245              rtems_device_minor_number minor,
246              void                      *arg)
247{
248  rtems_device_driver res = RTEMS_SUCCESSFUL;
249
250  res =  rtems_termios_close (arg);
251
252  return res;
253} /* console_close */
254
255/*-------------------------------------------------------------------------+
256| Console device driver READ entry point.
257+--------------------------------------------------------------------------+
258| Read characters from the I/O console. We only have stdin.
259+--------------------------------------------------------------------------*/
260rtems_device_driver
261console_read(rtems_device_major_number major,
262             rtems_device_minor_number minor,
263             void                      *arg)
264{
265
266  return rtems_termios_read (arg);
267} /* console_read */
268
269/*-------------------------------------------------------------------------+
270| Console device driver WRITE entry point.
271+--------------------------------------------------------------------------+
272| Write characters to the I/O console. Stderr and stdout are the same.
273+--------------------------------------------------------------------------*/
274rtems_device_driver
275console_write(rtems_device_major_number major,
276              rtems_device_minor_number minor,
277              void                    * arg)
278{
279
280  return rtems_termios_write (arg);
281
282} /* console_write */
283
284/*
285 * Handle ioctl request.
286 */
287rtems_device_driver
288console_control(rtems_device_major_number       major,
289                rtems_device_minor_number                       minor,
290                void                                            *arg
291)
292{
293/* does the BSP support break callbacks ? */
294#if defined(BIOCSETBREAKCB) && defined(BIOCGETBREAKCB)
295rtems_libio_ioctl_args_t        *ioa=arg;
296        switch (ioa->command) {
297                        case BIOCSETBREAKCB:
298                                return BSP_uart_set_break_cb(minor, ioa);
299                        case BIOCGETBREAKCB:
300                                return BSP_uart_get_break_cb(minor, ioa);
301
302                        default:
303                                break;
304        }
305#endif
306  return rtems_termios_ioctl (arg);
307}
308
309static int
310conSetAttr(int minor, const struct termios *t)
311{
312  int baud;
313
314  switch (t->c_cflag & CBAUD)
315    {
316    case B50:
317      baud = 50;
318      break;
319    case B75:
320      baud = 75;
321      break;
322    case B110:
323      baud = 110;
324      break;
325    case B134:
326      baud = 134;
327      break;
328    case B150:
329      baud = 150;
330      break;
331    case B200:
332      baud = 200;
333      break;
334    case B300:
335      baud = 300;
336      break;
337    case B600:
338      baud = 600;
339      break;
340    case B1200:
341      baud = 1200;
342      break;
343    case B1800:
344      baud = 1800;
345      break;
346    case B2400:
347      baud = 2400;
348      break;
349    case B4800:
350      baud = 4800;
351      break;
352    case B9600:
353      baud = 9600;
354      break;
355    case B19200:
356      baud = 19200;
357      break;
358    case B38400:
359      baud = 38400;
360      break;
361    case B57600:
362      baud = 57600;
363      break;
364    case B115200:
365      baud = 115200;
366      break;
367    default:
368      baud = 0;
369      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
370      return 0;
371    }
372
373  BSP_uart_set_baud(minor, baud);
374
375  return 0;
376}
Note: See TracBrowser for help on using the repository browser.