source: rtems/c/src/lib/libbsp/powerpc/mbx8xx/console/console.c @ 35bb69b

4.104.114.84.95
Last change on this file since 35bb69b was 35bb69b, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 6, 2001 at 3:52:03 PM

2001-03-30 Eric Valette <valette@…>

  • clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, include/8xx_immap.h, include/commproc.h, include/mbx.h, irq/.cvsignore, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: New files.
  • Makefile.am, configure.in, console/console.c, include/Makefile.am, network/network.c, startup/Makefile.am, startup/bspstart.c, startup/imbx8xx.c, startup/linkcmds, startup/mmutlbtab.c, startup/start.S, wrapup/Makefile.am: The modifications to this BSP reflect the conversion of the mpc8xx CPU to the "new exception processing model."
  • Property mode set to 100644
File size: 23.6 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 */
77#include <stdarg.h>
78#include <stdio.h>
79#include <bsp.h>                /* Must be before libio.h */
80#include <bspIo.h>
81#include <rtems/libio.h>
82#include <termios.h>
83#include <bsp/mbx.h>
84
85static int _EPPCBug_pollRead( int minor );
86static int _EPPCBug_pollWrite( int minor, const char *buf, int len );
87static void _BSP_output_char( char c );
88static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
89static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg);
90
91static void _BSP_null_char( char c ) {return;}
92
93BSP_output_char_function_type BSP_output_char = _BSP_null_char;
94
95
96/*
97 * _EPPCBug_pollRead
98 *
99 *  Read a character from the EPPCBug console, and return it. Return -1
100 *  if there is no character in the input FIFO.
101 *
102 *  Input parameters:
103 *    minor - selected channel
104 *
105 *  Output parameters:  NONE
106 *
107 *  Return value: char returned as positive signed int
108 *                -1 if no character is present in the input FIFO.
109 */
110static int _EPPCBug_pollRead(
111  int minor
112)
113{
114  extern volatile m8xx_t m8xx;
115
116  char c;
117  volatile int simask;          /* We must read and write m8xx.simask */
118  int retval;
119  ISR_Level level;
120 
121  struct {
122    int clun;
123    int dlun;
124    char * inbuf;
125    int nbytes_requested;
126    int reserved;
127  } volatile input_params;
128 
129  struct {
130    int status;
131    union {
132      struct {
133        int input_char_available;
134        int output_possible;
135        int break_detected;
136        int modem_status;
137      } stat;
138      struct {
139        int nbytes_received;
140      } read;
141    } u;
142  } volatile output_params;
143
144  retval = -1;
145
146  input_params.clun = 0;
147 
148  switch( minor ) {
149    case SMC1_MINOR:   
150      input_params.dlun = 0;  /* Should be 4, but doesn't work with EPPCBug 1.1 */
151      break;
152    case SMC2_MINOR:   
153      input_params.dlun = 5;
154      break;
155    case SCC2_MINOR:   
156      input_params.dlun = 1;
157      break;
158#ifdef mpc860
159    case SCC3_MINOR:   
160      input_params.dlun = 2;
161      break;
162    case SCC4_MINOR:   
163      input_params.dlun = 3;
164      break;
165#endif
166    default:   
167      input_params.dlun = 0;
168      break;
169  }
170 
171  _ISR_Disable( level );
172  simask = m8xx.simask;
173
174  /* Check for a char in the input FIFO using .CIO_STAT */
175  asm volatile( "li 10,0x202
176                 mr 3, %0
177                 mr 4, %1
178                 sc"
179    :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
180
181  if ( (output_params.status == 0) && output_params.u.stat.input_char_available) {
182 
183    /* Read the char and return it */
184    input_params.inbuf = &c;
185    input_params.nbytes_requested = 1;
186 
187    asm volatile( "li     10,0x200     /* Code for .CIO_READ */
188                   mr    3, %0         /* Address of input_params */
189                   mr    4, %1         /* Address of output_params */
190                   sc"             /* Call EPPCBUG */
191      :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
192
193    if ( (output_params.status == 0) && output_params.u.read.nbytes_received)
194      retval = (int)c;
195  }
196 
197  m8xx.simask = simask;
198  _ISR_Enable( level );
199  return retval;
200}
201
202
203/*
204 * _EPPCBug_pollWrite
205 *
206 *  Output buffer through EPPCBug. Returns only once every character has been
207 *  sent (polled output).
208 *
209 *  Input parameters:
210 *    minor - selected channel
211 *    buf - output buffer
212 *    len - number of chars to output
213 *
214 *  Output parameters:  NONE
215 *
216 *  Return value: IGNORED
217 */
218static int _EPPCBug_pollWrite(
219  int minor,
220  const char *buf,
221  int len
222)
223{
224  extern volatile m8xx_t m8xx;
225
226  volatile int simask;
227  int i, retval;
228  ISR_Level level;
229 
230  struct {
231    int clun;
232    int dlun;
233    const char * outbuf;
234    int nbytes_to_output;
235    int reserved;
236  } volatile input_params;
237 
238  struct {
239    int status;
240    union {
241      struct {
242        int input_char_available;
243        int output_possible;
244        int break_detected;
245        int modem_status;
246      } stat;
247      struct {
248        int nbytes_sent;
249      } write;
250    } u;
251  } volatile output_params;
252
253  retval = -1;
254
255  input_params.clun = 0;
256  input_params.reserved = 0;
257 
258  switch( minor ) {
259    case SMC1_MINOR:   
260      input_params.dlun = 0;  /* Should be 4, but doesn't work with EPPCBug 1.1 */
261      break;
262    case SMC2_MINOR:   
263      input_params.dlun = 5;
264      break;
265    case SCC2_MINOR:   
266      input_params.dlun = 1;
267      break;
268#ifdef mpc860
269    case SCC3_MINOR:   
270      input_params.dlun = 2;
271      break;
272    case SCC4_MINOR:   
273      input_params.dlun = 3;
274      break;
275#endif
276    default:   
277      input_params.dlun = 0;
278      break;
279  }
280
281  i = 0;
282
283  _ISR_Disable( level );
284  simask = m8xx.simask;
285
286  while (i < len) {
287    /* Wait for space in the output buffer */
288    do {
289      /* Check for space in the output FIFO */
290      asm volatile( "li 10,0x202        /* Code for .CIO_STAT */
291                     mr 3, %0           /* Address of input_params */
292                     mr 4, %1           /* Address of output_params */
293                     sc"            /* Call EPPCBUG */
294        :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
295
296      if (output_params.status)
297        goto error;
298    } while (!output_params.u.stat.output_possible);
299
300    /* Output the characters until done */
301    input_params.outbuf = &buf[i];
302    input_params.nbytes_to_output = len - i;
303 
304    asm volatile( "li 10,0x201          /* Code for .CIO_WRITE */
305                   mr 3, %0             /* Address of input_params */
306                   mr 4, %1             /* Address of output_params */
307                   sc"                  /* Call EPPCBUG */
308      :: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
309
310    if (output_params.status)
311      goto error;
312
313    i += output_params.u.write.nbytes_sent;
314  }
315 
316  /* Return something */
317  m8xx.simask = simask;
318  _ISR_Enable( level );
319  return RTEMS_SUCCESSFUL;
320
321error:
322  m8xx.simask = simask;
323  _ISR_Enable( level );
324  return -1;
325}
326
327
328/*
329 *  do_poll_read
330 *
331 *  Input characters through polled I/O. Returns has soon as a character has
332 *  been received. Otherwise, if we wait for the number of requested characters,
333 *  we could be here forever!
334 *
335 *  CR is converted to LF on input. The terminal should not send a CR/LF pair
336 *  when the return or enter key is pressed.
337 *
338 *  Input parameters:
339 *    major - ignored. Should be the major number for this driver.
340 *    minor - selected channel.
341 *    arg->buffer - where to put the received characters.
342 *    arg->count  - number of characters to receive before returning--Ignored.
343 *
344 *  Output parameters:
345 *    arg->bytes_moved - the number of characters read. Always 1.
346 *
347 *  Return value: RTEMS_SUCCESSFUL
348 *
349 *  CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
350 */
351static rtems_status_code do_poll_read(
352  rtems_device_major_number major,
353  rtems_device_minor_number minor,
354  void                    * arg
355)
356{
357  rtems_libio_rw_args_t *rw_args = arg;
358  int c;
359
360#if NVRAM_CONFIGURE == 1
361
362  int (*pollRead)( int minor );
363 
364  if ( (nvram->console_mode & 0x06) == 0x04 )
365    pollRead = _EPPCBug_pollRead;
366  else
367    pollRead = m8xx_uart_pollRead;
368
369  while( (c = (*pollRead)(minor)) == -1 );
370  rw_args->buffer[0] = (unsigned8)c;
371  if( rw_args->buffer[0] == '\r' )
372      rw_args->buffer[0] = '\n';
373  rw_args->bytes_moved = 1;
374  return RTEMS_SUCCESSFUL;
375
376#else
377
378#if UARTS_IO_MODE == 2
379#define BSP_READ  _EPPCBug_pollRead
380#else
381#define BSP_READ  m8xx_uart_pollRead
382#endif
383
384  while( (c = BSP_READ(minor)) == -1 );
385  rw_args->buffer[0] = (unsigned8)c;
386  if( rw_args->buffer[0] == '\r' )
387      rw_args->buffer[0] = '\n';
388  rw_args->bytes_moved = 1;
389  return RTEMS_SUCCESSFUL;
390
391#endif
392}
393
394
395/*
396 *  do_poll_write
397 *
398 *  Output characters through polled I/O. Returns only once every character has
399 *  been sent.
400 *
401 *  CR is transmitted AFTER a LF on output.
402 *
403 *  Input parameters:
404 *    major - ignored. Should be the major number for this driver.
405 *    minor - selected channel
406 *    arg->buffer - where to get the characters to transmit.
407 *    arg->count  - the number of characters to transmit before returning.
408 *
409 *  Output parameters:
410 *    arg->bytes_moved - the number of characters read
411 *
412 *  Return value: RTEMS_SUCCESSFUL
413 *
414 *  CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O!
415 */
416static rtems_status_code do_poll_write(
417  rtems_device_major_number major,
418  rtems_device_minor_number minor,
419  void                    * arg
420)
421{
422  rtems_libio_rw_args_t *rw_args = arg;
423  unsigned32 i;
424  char cr ='\r';
425
426#if NVRAM_CONFIGURE == 1
427
428  int (*pollWrite)(int minor, const char *buf, int len);
429 
430  if ( (nvram->console_mode & 0x06) == 0x04 )
431    pollWrite = _EPPCBug_pollWrite;
432  else
433    pollWrite = m8xx_uart_pollWrite;
434
435  for( i = 0; i < rw_args->count; i++ ) {
436    (*pollWrite)(minor, &(rw_args->buffer[i]), 1);
437    if ( rw_args->buffer[i] == '\n' )
438      (*pollWrite)(minor, &cr, 1);
439  }
440  rw_args->bytes_moved = i;
441  return RTEMS_SUCCESSFUL;
442
443#else
444
445#if UARTS_IO_MODE == 2
446#define BSP_WRITE _EPPCBug_pollWrite
447#else
448#define BSP_WRITE m8xx_uart_pollWrite
449#endif
450
451  for( i = 0; i < rw_args->count; i++ ) {
452    BSP_WRITE(minor, &(rw_args->buffer[i]), 1);
453    if ( rw_args->buffer[i] == '\n' )
454      BSP_WRITE(minor, &cr, 1);
455  }
456  rw_args->bytes_moved = i;
457  return RTEMS_SUCCESSFUL;
458
459#endif
460}
461
462
463/*
464 *  Print functions prototyped in bspIo.h
465 */
466
467static void _BSP_output_char( char c )
468{
469  char cr = '\r';
470 
471  /*
472   *  Can't rely on console_initialize having been called before this function
473   *  is used, so it may fail unless output is done through EPPC-Bug.
474   */
475#if NVRAM_CONFIGURE == 1
476
477  rtems_device_minor_number printk_minor;
478
479  /* Use NVRAM info for configuration */
480  printk_minor = (nvram->console_printk_port & 0x70) >> 4;
481  if( (nvram->console_mode & 0x30) == 0x20 ) {
482    _EPPCBug_pollWrite( printk_minor, &c, 1 );
483    if( c == '\n' )
484      _EPPCBug_pollWrite( printk_minor, &cr, 1 );
485  }
486  else {
487    m8xx_uart_pollWrite( printk_minor, &c, 1 );
488    if( c == '\n' )
489      m8xx_uart_pollWrite( PRINTK_MINOR, &cr, 1 );
490        }
491       
492#else 
493
494#if PRINTK_IO_MODE == 2
495#define PRINTK_WRITE _EPPCBug_pollWrite
496#else
497#define PRINTK_WRITE m8xx_uart_pollWrite
498#endif
499
500  PRINTK_WRITE( PRINTK_MINOR, &c, 1 );
501  if( c == '\n' )
502    PRINTK_WRITE( PRINTK_MINOR, &cr, 1 );
503   
504#endif
505}
506
507bd_t *eppcbugInfo= (bd_t *)0xdeadbeef;
508bd_t fakeEppcBugInfo = {
509        0x42444944,             /* Should be 0x42444944 "BDID" */
510        sizeof(bd_t),           /* Size of this structure */
511        0,                      /* revision of this structure */
512        0,                      /* EPPCbug date, i.e. 0x11061997 */
513        0,                      /* Memory start address */
514        0x1000000,              /* Memory (end) size in bytes */
515        0x28,                   /* Internal Freq, in Hz */
516        0,                      /* Bus Freq, in Hz */
517        0,                      /* Boot device controller */
518        0                       /* Boot device logical dev */
519};
520
521
522/*
523 ***************
524 * BOILERPLATE *
525 ***************
526 *
527 *  All these functions are prototyped in rtems/c/src/lib/include/console.h.
528 */
529
530/*
531 * Initialize and register the device
532 */
533rtems_device_driver console_initialize(
534  rtems_device_major_number major,
535  rtems_device_minor_number minor,
536  void *arg
537)
538{
539  rtems_status_code status;
540  rtems_device_minor_number console_minor;
541 
542  /*
543   * Set up TERMIOS if needed
544   */
545#if NVRAM_CONFIGURE == 1
546  /* Use NVRAM info for configuration */
547  console_minor = nvram->console_printk_port & 0x07;
548       
549  if ( nvram->console_mode & 0x01 )
550    /* termios */
551    rtems_termios_initialize ();
552
553  /*
554   *  Do common initialization.
555   */
556  m8xx_uart_initialize();
557 
558  /*
559   * Do device-specific initialization
560   */
561  if ( !nvram->eppcbug_smc1 &&
562    ( ((nvram->console_mode & 0x30) != 0x20) ||
563     (((nvram->console_printk_port & 0x30) >> 4) != SMC1_MINOR) ) )
564    m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
565
566  if ( ((nvram->console_mode & 0x30) != 0x20) ||
567      (((nvram->console_printk_port & 0x30) >> 4) != SMC2_MINOR) )
568    m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */                             
569
570  if ( ((nvram->console_mode & 0x30) != 0x20) ||
571      (((nvram->console_printk_port & 0x30) >> 4) != SCC2_MINOR) )
572    m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2    */
573                           
574#ifdef mpc860
575
576  if ( ((nvram->console_mode & 0x30) != 0x20) ||
577      (((nvram->console_printk_port & 0x30) >> 4) != SCC3_MINOR) )
578    m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3    */
579
580  if ( ((nvram->console_mode & 0x30) != 0x20) ||
581      (((nvram->console_printk_port & 0x30) >> 4) != SCC4_MINOR) )
582    m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4    */
583
584#endif /* mpc860 */
585  BSP_output_char = _BSP_output_char;
586#else /* NVRAM_CONFIGURE != 1 */
587
588    console_minor = CONSOLE_MINOR;
589   
590#if UARTS_USE_TERMIOS == 1
591
592    rtems_termios_initialize ();
593   
594#endif /* UARTS_USE_TERMIOS */
595   
596  /*
597   *  Do common initialization.
598   */
599  m8xx_uart_initialize();
600 
601  /*
602   * Do device-specific initialization
603   */
604#if !defined(EPPCBUG_SMC1) && ( PRINTK_IO_MODE != 2 || PRINTK_MINOR != SMC1_MINOR )
605  m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
606#endif
607
608#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SMC2_MINOR
609  m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */                             
610#endif
611
612  #if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC2_MINOR
613  m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2    */
614   #endif
615                           
616#ifdef mpc860
617
618#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC3_MINOR
619  m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3    */
620#endif
621
622#if PRINTK_IO_MODE != 2 || PRINTK_MINOR != SCC4_MINOR
623  m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4    */
624#endif
625
626#endif /* mpc860 */
627
628  BSP_output_char = _BSP_output_char;
629
630#endif /* NVRAM_CONFIGURE != 1 */
631
632
633  status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR);
634  if (status != RTEMS_SUCCESSFUL)
635    rtems_fatal_error_occurred (status);
636   
637  status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR);
638  if (status != RTEMS_SUCCESSFUL)
639    rtems_fatal_error_occurred (status);
640   
641  status = rtems_io_register_name ("/dev/tty2", major, SCC2_MINOR);
642  if (status != RTEMS_SUCCESSFUL)
643    rtems_fatal_error_occurred (status);
644   
645#ifdef mpc860
646  status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR);
647  if (status != RTEMS_SUCCESSFUL)
648    rtems_fatal_error_occurred (status);
649                             
650  status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR);
651  if (status != RTEMS_SUCCESSFUL)
652    rtems_fatal_error_occurred (status);
653   
654#endif /* mpc860 */
655   
656  /* Now register the RTEMS console */
657  status = rtems_io_register_name ("/dev/console", major, console_minor);
658  if (status != RTEMS_SUCCESSFUL)
659    rtems_fatal_error_occurred (status);
660   
661  return RTEMS_SUCCESSFUL;
662}
663
664
665/*
666 * Open the device
667 */
668rtems_device_driver console_open(
669  rtems_device_major_number major,
670  rtems_device_minor_number minor,
671  void *arg
672)
673{
674  /* Used to track termios private data for callbacks */
675  extern struct rtems_termios_tty *ttyp[];
676 
677  rtems_libio_open_close_args_t *args = arg;
678  rtems_status_code sc;
679 
680  static const rtems_termios_callbacks sccEPPCBugCallbacks = {
681    NULL,                               /* firstOpen */
682    NULL,                               /* lastClose */
683    _EPPCBug_pollRead,                  /* pollRead */
684    _EPPCBug_pollWrite,                 /* write */
685    NULL,                               /* stopRemoteTx */
686    NULL,                               /* startRemoteTx */
687    0                                   /* outputUsesInterrupts */
688  };
689 
690  static const rtems_termios_callbacks intrCallbacks = {
691    NULL,                               /* firstOpen */
692    NULL,                               /* lastClose */
693    NULL,                         /* pollRead */
694    m8xx_uart_write,                  /* write */
695    m8xx_uart_setAttributes,            /* setAttributes */
696    NULL,                               /* stopRemoteTx */
697    NULL,                               /* startRemoteTx */
698    1                                   /* outputUsesInterrupts */
699  };
700 
701  static const rtems_termios_callbacks pollCallbacks = {
702    NULL,                               /* firstOpen */
703    NULL,                               /* lastClose */
704    m8xx_uart_pollRead,           /* pollRead */
705    m8xx_uart_pollWrite,          /* write */
706    m8xx_uart_setAttributes,      /* setAttributes */
707    NULL,                               /* stopRemoteTx */
708    NULL,                               /* startRemoteTx */
709    0                                   /* outputUsesInterrupts */
710  };
711   
712  if ( minor > NUM_PORTS-1 ) 
713    return RTEMS_INVALID_NUMBER;
714
715#if NVRAM_CONFIGURE == 1
716
717  /* Use NVRAM info for configuration */ 
718  if ( nvram->console_mode & 0x01 ) {
719    /* Use termios */
720    if ( (nvram->console_mode & 0x06) == 0x02 ) {
721      /* interrupt-driven I/O */
722      sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
723      ttyp[minor] = args->iop->data1;        /* Keep cookie returned by termios_open */
724      return sc;
725    }
726    else if ( (nvram->console_mode & 0x06) == 0x04 )
727      /* polled I/O through EPPC-Bug, better be through SMC1 */
728      return rtems_termios_open( major, minor, arg, &sccEPPCBugCallbacks );
729    else
730      /* normal polled I/O */
731      return rtems_termios_open( major, minor, arg, &pollCallbacks );
732  }
733  else
734    /* no termios -- default to polled I/O */
735    return RTEMS_SUCCESSFUL;
736         
737#else /* NVRAM_CONFIGURE != 1 */
738
739#if UARTS_USE_TERMIOS == 1
740
741#if UARTS_IO_MODE == 2    /* EPPCBug polled I/O with termios */
742  sc = rtems_termios_open( major, minor, arg, &sccEPPCBugCallbacks );
743#elif UARTS_IO_MODE == 1  /* RTEMS interrupt-driven I/O with termios */
744  sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
745  ttyp[minor] = args->iop->data1;        /* Keep cookie returned by termios_open */
746#else                     /* RTEMS polled I/O with termios */
747  sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
748#endif
749
750#else /* UARTS_USE_TERMIOS != 1 */
751  /* no termios -- default to polled I/O */
752  sc = RTEMS_SUCCESSFUL;
753#endif /* UARTS_USE_TERMIOS != 1 */
754
755  return sc;
756 
757#endif /* NVRAM_CONFIGURE != 1 */
758}
759
760
761/*
762 * Close the device
763 */
764rtems_device_driver console_close(
765  rtems_device_major_number major,
766  rtems_device_minor_number minor,
767  void *arg
768)
769{
770  if ( minor > NUM_PORTS-1 )
771    return RTEMS_INVALID_NUMBER;
772
773#if NVRAM_CONFIGURE == 1
774
775  /* Use NVRAM info for configuration */ 
776  if ( nvram->console_mode & 0x01 )
777    /* use termios */
778    return rtems_termios_close( arg );
779  else
780    /* no termios */
781    return RTEMS_SUCCESSFUL;
782
783#else /* NVRAM_CONFIGURE != 1 */
784
785#if UARTS_USE_TERMIOS == 1
786  return rtems_termios_close( arg );
787#else
788  return RTEMS_SUCCESSFUL;
789#endif
790
791#endif /* NVRAM_CONFIGURE != 1 */
792}
793
794
795/*
796 * Read from the device
797 */
798rtems_device_driver console_read(
799  rtems_device_major_number major,
800  rtems_device_minor_number minor,
801  void *arg
802)
803{
804  if ( minor > NUM_PORTS-1 )
805    return RTEMS_INVALID_NUMBER;
806
807#if NVRAM_CONFIGURE == 1
808
809  /* Use NVRAM info for configuration */ 
810  if ( nvram->console_mode & 0x01 )
811    /* use termios */
812    return rtems_termios_read( arg );
813  else
814    /* no termios -- default to polled */
815    return do_poll_read( major, minor, arg );
816
817#else
818
819#if UARTS_USE_TERMIOS == 1
820  return rtems_termios_read( arg );
821#else
822  return do_poll_read( major, minor, arg );
823#endif
824
825#endif
826}
827
828
829/*
830 * Write to the device
831 */
832rtems_device_driver console_write(
833  rtems_device_major_number major,
834  rtems_device_minor_number minor,
835  void *arg
836)
837{
838  if ( minor > NUM_PORTS-1 )
839    return RTEMS_INVALID_NUMBER;
840
841#if NVRAM_CONFIGURE == 1
842
843  /* Use NVRAM info for configuration */ 
844  if ( nvram->console_mode & 0x01 )
845    /* use termios */
846    return rtems_termios_write( arg );
847  else
848    /* no termios -- default to polled */
849    return do_poll_write( major, minor, arg );
850
851#else
852
853#if UARTS_USE_TERMIOS == 1
854  return rtems_termios_write( arg );
855#else
856    /* no termios -- default to polled */
857  return do_poll_write( major, minor, arg );
858#endif
859
860#endif
861}
862
863
864/*
865 * Handle ioctl request.
866 */
867rtems_device_driver console_control(
868  rtems_device_major_number major,
869  rtems_device_minor_number minor,
870  void *arg
871)
872{ 
873  if ( minor > NUM_PORTS-1 )
874    return RTEMS_INVALID_NUMBER;
875
876#if NVRAM_CONFIGURE == 1
877
878  /* Uuse NVRAM info for configuration */ 
879  if ( nvram->console_mode & 0x01 )
880    /* termios */
881    return rtems_termios_ioctl( arg );
882  else
883    /* no termios -- default to polled */
884    return RTEMS_SUCCESSFUL;
885
886#else
887
888#if UARTS_USE_TERMIOS == 1
889  return rtems_termios_ioctl( arg );
890#else
891  return RTEMS_SUCCESSFUL;
892#endif
893
894#endif
895}
896
897/*
898 *  Support routine for console-generic
899 */
900
901int mbx8xx_console_get_configuration(void)
902{
903#if NVRAM_CONFIGURE == 1
904  return nvram->console_mode;
905#else
906#if UARTS_IO_MODE == 1
907  return 0x02;
908#else
909  return 0;
910#endif
911#endif
912
913}
914
Note: See TracBrowser for help on using the repository browser.