source: rtems/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c @ 0bebe52

4.104.114.84.95
Last change on this file since 0bebe52 was 0bebe52, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 4, 2002 at 5:40:52 PM

2002-01-03 Ralf Corsepius <corsepiu@…>

  • clock/p_clock.c: Include rtems/bspIo.h instead of bspIo.h.
  • console/console.c: Include rtems/bspIo.h instead of bspIo.h.
  • irq/irq_init.c: Include rtems/bspIo.h instead of bspIo.h.
  • Property mode set to 100644
File size: 12.8 KB
Line 
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 */
93#include <rtems/bspIo.h>
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{
326  /* Used to track termios private data for callbacks */
327  extern struct rtems_termios_tty *ttyp[];
328 
329  rtems_libio_open_close_args_t *args = arg;
330  rtems_status_code sc;
331 
332
333  static const rtems_termios_callbacks intrCallbacks = {
334    NULL,                               /* firstOpen */
335    NULL,                               /* lastClose */
336    NULL,                         /* pollRead */
337    m8xx_uart_write,                  /* write */
338    m8xx_uart_setAttributes,            /* setAttributes */
339    NULL,                               /* stopRemoteTx */
340    NULL,                               /* startRemoteTx */
341    1                                   /* outputUsesInterrupts */
342  };
343 
344  static const rtems_termios_callbacks pollCallbacks = {
345    NULL,                               /* firstOpen */
346    NULL,                               /* lastClose */
347    m8xx_uart_pollRead,           /* pollRead */
348    m8xx_uart_pollWrite,          /* write */
349    m8xx_uart_setAttributes,      /* setAttributes */
350    NULL,                               /* stopRemoteTx */
351    NULL,                               /* startRemoteTx */
352    0                                   /* outputUsesInterrupts */
353  };
354   
355  if ( minor > NUM_PORTS-1 ) 
356    return RTEMS_INVALID_NUMBER;
357
358
359#if UARTS_USE_TERMIOS == 1
360
361#if UARTS_IO_MODE == 1  /* RTEMS interrupt-driven I/O with termios */
362  sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
363  ttyp[minor] = args->iop->data1;        /* Keep cookie returned by termios_open */
364#else                     /* RTEMS polled I/O with termios */
365  sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
366#endif
367
368#else /* UARTS_USE_TERMIOS != 1 */
369  /* no termios -- default to polled I/O */
370  sc = RTEMS_SUCCESSFUL;
371#endif /* UARTS_USE_TERMIOS != 1 */
372
373  return sc;
374 
375}
376
377
378/*
379 * Close the device
380 */
381rtems_device_driver console_close(
382  rtems_device_major_number major,
383  rtems_device_minor_number minor,
384  void *arg
385)
386{
387  if ( minor > NUM_PORTS-1 )
388    return RTEMS_INVALID_NUMBER;
389
390#if UARTS_USE_TERMIOS == 1
391  return rtems_termios_close( arg );
392#else
393  return RTEMS_SUCCESSFUL;
394#endif
395
396}
397
398
399/*
400 * Read from the device
401 */
402rtems_device_driver console_read(
403  rtems_device_major_number major,
404  rtems_device_minor_number minor,
405  void *arg
406)
407{
408  if ( minor > NUM_PORTS-1 )
409    return RTEMS_INVALID_NUMBER;
410
411
412#if UARTS_USE_TERMIOS == 1
413  return rtems_termios_read( arg );
414#else
415  return do_poll_read( major, minor, arg );
416#endif
417
418}
419
420
421/*
422 * Write to the device
423 */
424rtems_device_driver console_write(
425  rtems_device_major_number major,
426  rtems_device_minor_number minor,
427  void *arg
428)
429{
430  if ( minor > NUM_PORTS-1 )
431    return RTEMS_INVALID_NUMBER;
432
433
434#if UARTS_USE_TERMIOS == 1
435  return rtems_termios_write( arg );
436#else
437    /* no termios -- default to polled */
438  return do_poll_write( major, minor, arg );
439#endif
440
441}
442
443
444/*
445 * Handle ioctl request.
446 */
447rtems_device_driver console_control(
448  rtems_device_major_number major,
449  rtems_device_minor_number minor,
450  void *arg
451)
452{ 
453  if ( minor > NUM_PORTS-1 )
454    return RTEMS_INVALID_NUMBER;
455
456
457#if UARTS_USE_TERMIOS == 1
458  return rtems_termios_ioctl( arg );
459#else
460  return RTEMS_SUCCESSFUL;
461#endif
462
463}
464
465/*
466 *  Support routine for console-generic
467 */
468
469int mbx8xx_console_get_configuration(void)
470{
471#if UARTS_IO_MODE == 1
472  return 0x02;
473#else
474  return 0;
475#endif
476
477}
478
Note: See TracBrowser for help on using the repository browser.