source: rtems/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c @ 37a25cf

4.104.114.84.95
Last change on this file since 37a25cf was 37a25cf, checked in by Joel Sherrill <joel.sherrill@…>, on 11/04/02 at 14:28:09

2002-11-04 Joel Sherrill <joel@…>

  • console/console.c, irq/irq.c, network/if_hdlcsubr.c, network/if_hdlcsubr.h, network/network.c, vectors/vectors_init.c: Removed warnings.
  • Property mode set to 100644
File size: 13.0 KB
RevLine 
[5edbffe]1/*
2 *  console.c
3 *
4 *  This file contains the MBX8xx termios serial I/O package.
5 *  Only asynchronous I/O is supported.
6 *
7 *  The SCCs and SMCs are assigned as follows
8 *
9 *   Channel     Device      Minor   Note
10 *    SMC1      /dev/tty0      0
11 *    SMC2      /dev/tty1      1
12 *    SCC1                     2     N/A. Hardwired as ethernet port
13 *    SCC2      /dev/tty2      3
14 *    SCC3      /dev/tty3      4
15 *    SCC4      /dev/tty4      5
16 *
17 *  All ports support termios. The use of termios is recommended for real-time
18 *  applications. Termios provides buffering and input processing. When not
19 *  using termios, processing is limited to the substitution of LF for CR on
20 *  input, and the output of a CR following the output of a LF character.
21 *  Note that the terminal should not send CR/LF pairs when the return key
22 *  is pressed, and that output lines are terminated with LF/CR, not CR/LF
23 *  (although that would be easy to change).
24 *
25 *  I/O may be interrupt-driven (recommended for real-time applications) or
26 *  polled. Polled I/O may be performed by this device driver entirely, or
27 *  in part by EPPCBug. With EPPCBug 1.1, polled I/O is limited to the
28 *  EPPCBug debug console. This is a limitation of the firmware. Later
29 *  firmware may be able to do I/O through any port. This code assumes
30 *  that the EPPCBug console is the default: SMC1. If the console and
31 *  printk ports are set to anything else with EPPCBug polled I/O, the
32 *  system will hang. Only port SMC1 is usable with EPPCBug polled I/O.
33 *
34 *  LIMITATIONS:
35 *
36 *  It is not possible to use different I/O modes on the different ports. The
37 *  exception is with printk. The printk port can use a different mode from
38 *  the other ports. If this is done, it is important not to open the printk
39 *  port from an RTEMS application.
40 *
41 *  Currently, the I/O modes are determined at build time. It would be much
42 *  better to have the mode selected at boot time based on parameters in
43 *  NVRAM.
44 *
45 *  Interrupt-driven I/O requires termios.
46 *
47 *  TESTS:
48 *
49 *  TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests
50 *  play with the interrupt masks and turn off I/O. Those tests will hang
51 *  when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O
52 *  from the static constructors before the console is open. This test
53 *  will not work with interrupt-driven I/O. Because of the buffering
54 *  performed in termios, test output may not be in sequence.The tests
55 *  should all be fixed to work with interrupt-driven I/O and to
56 *  produce output in the expected sequence. Obviously, the termios test
57 *  requires termios support in the driver.
58 * 
59 *  Set CONSOLE_MINOR to the appropriate device minor number in the
60 *  config file. This allows the RTEMS application console to be different
61 *  from the EPPBug debug console or the GDB port.
62 *
63 *  This driver handles all five available serial ports: it distinguishes
64 *  the sub-devices using minor device numbers. It is not possible to have
65 *  other protocols running on the other ports when this driver is used as
66 *  currently written.
67 * 
68 *  Based on code (alloc860.c in eth_comm port) by
69 *  Jay Monkman (jmonkman@frasca.com),
70 *  Copyright (C) 1998 by Frasca International, Inc.
71 *
72 *  Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
73 *  and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>.
74 *  Copyright (c) 2000, National Research Council of Canada
75 *
76 *  Modifications by Andy Dachs <iwe@fsmal.net> for MPC8260
77 *  support.
78 *
79 * The SCCs and SMCs on the eval board are assigned as follows
80 *
81 *   Channel     Device      Minor   Termios
82 *    SMC1      /dev/tty3      4       no
83 *    SMC2      /dev/tty4      5       no
84 *    SCC1      /dev/tty0      0       no
85 *    SCC2      /dev/console   1       yes
86 *    SCC3      /dev/tty1      2       no       * USED FOR NETWORK I/F
87 *    SCC4      /dev/tty2      3       no       * USED FOR NETWORK I/F
88 *
89 */
90#include <stdarg.h>
91#include <stdio.h>
92#include <bsp.h>                /* Must be before libio.h */
[0bebe52]93#include <rtems/bspIo.h>
[5edbffe]94#include <rtems/libio.h>
95#include <termios.h>
96
97static void _BSP_output_char( char c );
98static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
99static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
100
101
102BSP_output_char_function_type BSP_output_char = _BSP_output_char;
103
104
105
106
107/*
108 *  do_poll_read
109 *
110 *  Input characters through polled I/O. Returns has soon as a character has
111 *  been received. Otherwise, if we wait for the number of requested characters,
112 *  we could be here forever!
113 *
114 *  CR is converted to LF on input. The terminal should not send a CR/LF pair
115 *  when the return or enter key is pressed.
116 *
117 *  Input parameters:
118 *    major - ignored. Should be the major number for this driver.
119 *    minor - selected channel.
120 *    arg->buffer - where to put the received characters.
121 *    arg->count  - number of characters to receive before returning--Ignored.
122 *
123 *  Output parameters:
124 *    arg->bytes_moved - the number of characters read. Always 1.
125 *
126 *  Return value: RTEMS_SUCCESSFUL
127 *
128 *  CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
129 */
130static rtems_status_code do_poll_read(
131  rtems_device_major_number major,
132  rtems_device_minor_number minor,
133  void                    * arg
134)
135{
136  rtems_libio_rw_args_t *rw_args = arg;
137  int c;
138
139#define BSP_READ  m8xx_uart_pollRead
140
141  while( (c = BSP_READ(minor)) == -1 );
142  rw_args->buffer[0] = (unsigned8)c;
143  if( rw_args->buffer[0] == '\r' )
144      rw_args->buffer[0] = '\n';
145  rw_args->bytes_moved = 1;
146  return RTEMS_SUCCESSFUL;
147}
148
149
150/*
151 *  do_poll_write
152 *
153 *  Output characters through polled I/O. Returns only once every character has
154 *  been sent.
155 *
156 *  CR is transmitted AFTER a LF on output.
157 *
158 *  Input parameters:
159 *    major - ignored. Should be the major number for this driver.
160 *    minor - selected channel
161 *    arg->buffer - where to get the characters to transmit.
162 *    arg->count  - the number of characters to transmit before returning.
163 *
164 *  Output parameters:
165 *    arg->bytes_moved - the number of characters read
166 *
167 *  Return value: RTEMS_SUCCESSFUL
168 *
169 *  CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
170 */
171static rtems_status_code do_poll_write(
172  rtems_device_major_number major,
173  rtems_device_minor_number minor,
174  void                    * arg
175)
176{
177  rtems_libio_rw_args_t *rw_args = arg;
178  unsigned32 i;
179  char cr ='\r';
180
181#define BSP_WRITE m8xx_uart_pollWrite
182
183  for( i = 0; i < rw_args->count; i++ ) {
184    BSP_WRITE(minor, &(rw_args->buffer[i]), 1);
185    if ( rw_args->buffer[i] == '\n' )
186      BSP_WRITE(minor, &cr, 1);
187  }
188  rw_args->bytes_moved = i;
189  return RTEMS_SUCCESSFUL;
190
191}
192
193
194/*
195 *  Print functions prototyped in bspIo.h
196 */
197
198static void _BSP_output_char( char c )
199{
200  char cr = '\r';
201 
202  /*
203   *  Can't rely on console_initialize having been called before this function
204   *  is used, so it may fail unless output is done through EPPC-Bug.
205   */
206#define PRINTK_WRITE m8xx_uart_pollWrite
207
208  PRINTK_WRITE( PRINTK_MINOR, &c, 1 );
209  if( c == '\n' )
210    PRINTK_WRITE( PRINTK_MINOR, &cr, 1 );
211   
212}
213
214
215/*
216 ***************
217 * BOILERPLATE *
218 ***************
219 *
220 *  All these functions are prototyped in rtems/c/src/lib/include/console.h.
221 */
222
223/*
224 * Initialize and register the device
225 */
226rtems_device_driver console_initialize(
227  rtems_device_major_number major,
228  rtems_device_minor_number minor,
229  void *arg
230)
231{
232  rtems_status_code status;
233  rtems_device_minor_number console_minor;
234 
235  /*
236   * Set up TERMIOS if needed
237   */
238
239    console_minor = CONSOLE_MINOR;
240
241#if UARTS_USE_TERMIOS == 1
242
243    rtems_termios_initialize ();
244#else
245    rtems_termios_initialize ();
246#endif /* UARTS_USE_TERMIOS */
247   
248  /*
249   *  Do common initialization.
250   */
251  m8xx_uart_initialize();
252 
253  /*
254   * Do device-specific initialization
255   */
256#if 0
257  m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty4 */
258  m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty5 */
259#endif
260
261  m8xx_uart_scc_initialize(SCC1_MINOR); /* /dev/tty0    */
262  m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty1    */
263
264#if 0  /* used as network connections */
265  m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty2    */
266  m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty3    */
267#endif
268
269
270
271  /*
272   * Set up interrupts
273   */
274  m8xx_uart_interrupts_initialize();
275
276  status = rtems_io_register_name ("/dev/tty0", major, SCC1_MINOR);
277  if (status != RTEMS_SUCCESSFUL)
278    rtems_fatal_error_occurred (status);
279  chmod("/dev/tty0",0660);
280  chown("/dev/tty0",2,0);
281
282
283  status = rtems_io_register_name ("/dev/tty1", major, SCC2_MINOR);
284  if (status != RTEMS_SUCCESSFUL)
285    rtems_fatal_error_occurred (status);
286  chmod("/dev/tty1",0660);
287  chown("/dev/tty1",2,0);
288
289#if 0
290  status = rtems_io_register_name ("/dev/tty2", major, SCC3_MINOR);
291  if (status != RTEMS_SUCCESSFUL)
292    rtems_fatal_error_occurred (status);
293                             
294  status = rtems_io_register_name ("/dev/tty3", major, SCC4_MINOR);
295  if (status != RTEMS_SUCCESSFUL)
296    rtems_fatal_error_occurred (status);
297
298  status = rtems_io_register_name ("/dev/tty4", major, SMC1_MINOR);
299  if (status != RTEMS_SUCCESSFUL)
300    rtems_fatal_error_occurred (status);
301
302  status = rtems_io_register_name ("/dev/tty5", major, SMC2_MINOR);
303  if (status != RTEMS_SUCCESSFUL)
304    rtems_fatal_error_occurred (status);
305#endif
306  /* Now register the RTEMS console */
307  status = rtems_io_register_name ("/dev/console", major, console_minor);
308  if (status != RTEMS_SUCCESSFUL)
309    rtems_fatal_error_occurred (status);
310  chmod("/dev/console",0666);
311  chown("/dev/console",2,0);
312   
313  return RTEMS_SUCCESSFUL;
314}
315
316
317/*
318 * Open the device
319 */
320rtems_device_driver console_open(
321  rtems_device_major_number major,
322  rtems_device_minor_number minor,
323  void *arg
324)
325{
[37a25cf]326#if UARTS_IO_MODE == 1  /* RTEMS interrupt-driven I/O with termios */
[5edbffe]327  /* Used to track termios private data for callbacks */
328  extern struct rtems_termios_tty *ttyp[];
329  rtems_libio_open_close_args_t *args = arg;
330
331  static const rtems_termios_callbacks intrCallbacks = {
332    NULL,                               /* firstOpen */
333    NULL,                               /* lastClose */
334    NULL,                         /* pollRead */
335    m8xx_uart_write,                  /* write */
336    m8xx_uart_setAttributes,            /* setAttributes */
337    NULL,                               /* stopRemoteTx */
338    NULL,                               /* startRemoteTx */
339    1                                   /* outputUsesInterrupts */
340  };
[37a25cf]341#else
342#if (UARTS_USE_TERMIOS == 1) && (UARTS_IO_MODE != 1)
[5edbffe]343  static const rtems_termios_callbacks pollCallbacks = {
344    NULL,                               /* firstOpen */
345    NULL,                               /* lastClose */
346    m8xx_uart_pollRead,           /* pollRead */
347    m8xx_uart_pollWrite,          /* write */
348    m8xx_uart_setAttributes,      /* setAttributes */
349    NULL,                               /* stopRemoteTx */
350    NULL,                               /* startRemoteTx */
351    0                                   /* outputUsesInterrupts */
352  };
[37a25cf]353#endif
[5edbffe]354   
[37a25cf]355#endif
356 
357  rtems_status_code sc;
358 
[5edbffe]359  if ( minor > NUM_PORTS-1 )
360    return RTEMS_INVALID_NUMBER;
361
362
363#if UARTS_USE_TERMIOS == 1
364
365#if UARTS_IO_MODE == 1  /* RTEMS interrupt-driven I/O with termios */
366  sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
367  ttyp[minor] = args->iop->data1;        /* Keep cookie returned by termios_open */
368#else                     /* RTEMS polled I/O with termios */
369  sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
370#endif
371
372#else /* UARTS_USE_TERMIOS != 1 */
373  /* no termios -- default to polled I/O */
374  sc = RTEMS_SUCCESSFUL;
375#endif /* UARTS_USE_TERMIOS != 1 */
376
377  return sc;
378 
379}
380
381
382/*
383 * Close the device
384 */
385rtems_device_driver console_close(
386  rtems_device_major_number major,
387  rtems_device_minor_number minor,
388  void *arg
389)
390{
391  if ( minor > NUM_PORTS-1 )
392    return RTEMS_INVALID_NUMBER;
393
394#if UARTS_USE_TERMIOS == 1
395  return rtems_termios_close( arg );
396#else
397  return RTEMS_SUCCESSFUL;
398#endif
399
400}
401
402
403/*
404 * Read from the device
405 */
406rtems_device_driver console_read(
407  rtems_device_major_number major,
408  rtems_device_minor_number minor,
409  void *arg
410)
411{
412  if ( minor > NUM_PORTS-1 )
413    return RTEMS_INVALID_NUMBER;
414
415
416#if UARTS_USE_TERMIOS == 1
417  return rtems_termios_read( arg );
418#else
419  return do_poll_read( major, minor, arg );
420#endif
421
422}
423
424
425/*
426 * Write to the device
427 */
428rtems_device_driver console_write(
429  rtems_device_major_number major,
430  rtems_device_minor_number minor,
431  void *arg
432)
433{
434  if ( minor > NUM_PORTS-1 )
435    return RTEMS_INVALID_NUMBER;
436
437
438#if UARTS_USE_TERMIOS == 1
439  return rtems_termios_write( arg );
440#else
441    /* no termios -- default to polled */
442  return do_poll_write( major, minor, arg );
443#endif
444
445}
446
447
448/*
449 * Handle ioctl request.
450 */
451rtems_device_driver console_control(
452  rtems_device_major_number major,
453  rtems_device_minor_number minor,
454  void *arg
455)
456{
457  if ( minor > NUM_PORTS-1 )
458    return RTEMS_INVALID_NUMBER;
459
460
461#if UARTS_USE_TERMIOS == 1
462  return rtems_termios_ioctl( arg );
463#else
464  return RTEMS_SUCCESSFUL;
465#endif
466
467}
468
469/*
470 *  Support routine for console-generic
471 */
472
473int mbx8xx_console_get_configuration(void)
474{
475#if UARTS_IO_MODE == 1
476  return 0x02;
477#else
478  return 0;
479#endif
480
481}
482
Note: See TracBrowser for help on using the repository browser.