Changeset 92a6454 in rtems


Ignore:
Timestamp:
07/05/98 11:00:00 (25 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
e7ff2b2
Parents:
0e8c2000
Message:

Converted the console driver to use libchip/serial and added support
for the z85c30 found on the DMV177. This effort started with the
console driver from the Radstone PPC2. But some simplifications were
made in the hope that console.c can be made a shared file at some point
in the near future.

Split the debugio from console. This was done so at some point in the
future printk support as is found in the pc386 BSP can be shared
across all BSPs.

Location:
c/src/lib/libbsp/powerpc/dmv177/console
Files:
5 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/dmv177/console/Makefile.in

    r0e8c2000 r92a6454  
    1212
    1313# C source names, if any, go here -- minus the .c
    14 C_PIECES=console duart
     14C_PIECES=config console debugio mc68681cfg z85c30cfg
    1515C_FILES=$(C_PIECES:%=%.c)
    1616C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
  • c/src/lib/libbsp/powerpc/dmv177/console/console.c

    r0e8c2000 r92a6454  
    11/*
    2  *  console.c
     2 *  This file contains the TTY driver for the PPCn_60x
    33 *
    44 *  This driver uses the termios pseudo driver.
    55 *
    6  *  Currently only polled mode is supported.
    7  *
    8  *  COPYRIGHT (c) 1989-1998.
     6 *  COPYRIGHT (c) 1998 by Radstone Technology
     7 *
     8 *
     9 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
     10 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
     11 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
     12 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
     13 *
     14 * You are hereby granted permission to use, copy, modify, and distribute
     15 * this file, provided that this notice, plus the above copyright notice
     16 * and disclaimer, appears in all copies. Radstone Technology will provide
     17 * no support for this code.
     18 *
     19 *  COPYRIGHT (c) 1989-1997.
    920 *  On-Line Applications Research Corporation (OAR).
    1021 *  Copyright assigned to U.S. Government, 1994.
     
    1425 *  http://www.OARcorp.com/rtems/license.html.
    1526 *
    16  *  $Id: console.c
    17  */
    18 
    19 #include <stdlib.h>
    20 #include <motorola/mc68681.h>
     27 *  $Id$
     28 */
     29
    2130#include <bsp.h>
    2231#include <rtems/libio.h>
     32#include <stdlib.h>
    2333#include <assert.h>
    24 
    25 #define COM1                      0
    26 #define COM2                      1
    27 #define NUM_PORTS                 2
    28 #define USE_FOR_CONSOLE           COM2
     34#include <termios.h>
     35
     36#include <libchip/serial.h>
    2937
    3038/*
    31  *  Define RDB_BREAK_IN if you need to be able to break in to the
    32  *  program with a ctrl-c during remote target debugging. If so,
    33  *  UART B will not be accessible from rtems during remote debugging
    34  *  if interrupt driven console is used. Does not affect UART A, polled
    35  *  mode or when the program runs without remote debugging.
    36  */
    37 #define RDB_BREAK_IN
    38 
    39 /* Proto-types for Duart.C */
    40 void console_initialize_interrupts( void );
    41 int console_inbyte_nonblocking( int port );
    42 void console_outbyte_polled(int  port, char ch);
    43 rtems_isr console_isr (rtems_vector_number vector);
    44 volatile void init_mc88681();
    45 
    46 /*  PAGE
     39 * Load configuration table
     40 */
     41
     42extern console_data  Console_Port_Data[];
     43extern unsigned long  Console_Port_Count;
     44extern rtems_device_minor_number  Console_Port_Minor;
     45 
     46/* PAGE
     47 *
     48 *  console_open
     49 *
     50 *  open a port as a termios console.
     51 *
     52 */
     53rtems_device_driver console_open(
     54  rtems_device_major_number major,
     55  rtems_device_minor_number minor,
     56  void                    * arg
     57)
     58{
     59  rtems_status_code              status;
     60  rtems_libio_open_close_args_t *args = arg;
     61  rtems_libio_ioctl_args_t       IoctlArgs;
     62  struct termios                 Termios;
     63  rtems_termios_callbacks        Callbacks;
     64  console_tbl                   *cptr;
     65
     66  /*
     67   * Verify the port number is valid.
     68   */
     69  if ( minor > Console_Port_Count ) {
     70    return RTEMS_INVALID_NUMBER;
     71  }
     72
     73  /*
     74   * Open the port as a termios console driver.
     75   */
     76
     77  cptr = &Console_Port_Tbl[minor];
     78  Callbacks.firstOpen            = cptr->pDeviceFns->deviceFirstOpen;
     79  Callbacks.lastClose            = cptr->pDeviceFns->deviceLastClose;
     80  Callbacks.pollRead             = cptr->pDeviceFns->deviceRead;
     81  Callbacks.write                = cptr->pDeviceFns->deviceWrite;
     82  Callbacks.setAttributes        = cptr->pDeviceFns->deviceSetAttributes;
     83  Callbacks.stopRemoteTx         = cptr->pDeviceFlow->deviceStopRemoteTx;
     84  Callbacks.startRemoteTx        = cptr->pDeviceFlow->deviceStartRemoteTx;
     85  Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts;
     86
     87  /* XXX what about
     88   *        Console_Port_Tbl[minor].ulMargin,
     89   *        Console_Port_Tbl[minor].ulHysteresis);
     90   */
     91
     92  status = rtems_termios_open ( major, minor, arg, &Callbacks );
     93  Console_Port_Data[minor].termios_data = args->iop->data1;
     94
     95  if (minor!=Console_Port_Minor) {
     96    /*
     97     * If this is not the console we do not want ECHO and
     98     * so forth
     99     */
     100    IoctlArgs.iop=args->iop;
     101    IoctlArgs.command=RTEMS_IO_GET_ATTRIBUTES;
     102    IoctlArgs.buffer=&Termios;
     103    rtems_termios_ioctl(&IoctlArgs);
     104    Termios.c_lflag=ICANON;
     105    IoctlArgs.command=RTEMS_IO_SET_ATTRIBUTES;
     106    rtems_termios_ioctl(&IoctlArgs);
     107  }
     108
     109  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
     110      Console_Port_Tbl[minor].pDeviceFlow &&
     111      Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx) {
     112    Console_Port_Tbl[minor].pDeviceFlow->deviceStartRemoteTx(minor);
     113  }
     114
     115  return status;
     116}
     117 
     118void console_reserve_resources(
     119  rtems_configuration_table *configuration
     120)
     121{
     122  rtems_termios_reserve_resources( configuration, 4 );
     123}
     124
     125
     126rtems_device_driver console_close(
     127  rtems_device_major_number major,
     128  rtems_device_minor_number minor,
     129  void                    * arg
     130)
     131{
     132  rtems_libio_open_close_args_t *args = arg;
     133
     134  if ( (args->iop->flags&LIBIO_FLAGS_READ) &&
     135        Console_Port_Tbl[minor].pDeviceFlow &&
     136        Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx) {
     137    Console_Port_Tbl[minor].pDeviceFlow->deviceStopRemoteTx(minor);
     138  }
     139
     140  return rtems_termios_close (arg);
     141}
     142 
     143rtems_device_driver console_read(
     144  rtems_device_major_number major,
     145  rtems_device_minor_number minor,
     146  void                    * arg
     147)
     148{
     149  return rtems_termios_read (arg);
     150}
     151 
     152rtems_device_driver console_write(
     153  rtems_device_major_number major,
     154  rtems_device_minor_number minor,
     155  void                    * arg
     156)
     157{
     158  return rtems_termios_write (arg);
     159}
     160 
     161rtems_device_driver console_control(
     162  rtems_device_major_number major,
     163  rtems_device_minor_number minor,
     164  void                    * arg
     165)
     166{
     167  return rtems_termios_ioctl (arg);
     168}
     169
     170/* PAGE
    47171 *
    48172 *  console_initialize
    49173 *
    50  *  This routine initializes the console IO driver.
    51  *
    52  *  Input parameters:
    53  *    major - console device major number
    54  *    minor - console device minor number
    55  *    arg   - pointer to optional device driver arguments
    56  *
    57  *  Output parameters:  NONE
    58  *
    59  *  Return values:
    60  *    rtems_device_driver status code
    61  */
    62  
     174 *  Routine called to initialize the console device driver.
     175 */
     176
    63177rtems_device_driver console_initialize(
    64178  rtems_device_major_number  major,
     
    67181)
    68182{
    69   rtems_status_code status;
    70   int               console;
     183  rtems_status_code        status;
    71184
    72185  /*
    73186   * initialize the termio interface.
    74187   */
     188
    75189  rtems_termios_initialize();
    76190
    77   /*
    78    *  Register Device Names
    79    */
    80   console = USE_FOR_CONSOLE;
    81   status = rtems_io_register_name( "/dev/console", major, console );
    82   if (status != RTEMS_SUCCESSFUL)
     191  for (minor=0; minor<Console_Port_Count; minor++) {
     192    /*
     193     * First perform the configuration dependent probe, then the
     194     * device dependent probe
     195     */
     196
     197    if ((!Console_Port_Tbl[minor].deviceProbe ||
     198         Console_Port_Tbl[minor].deviceProbe(minor)) &&
     199         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
     200      /*
     201       * Use this device for the console
     202       */
     203      break;
     204    }
     205  }
     206  if ( minor==Console_Port_Count ) {
     207    /*
     208     * Failed to find a working device
     209     */
     210    rtems_fatal_error_occurred(RTEMS_IO_ERROR);
     211  }
     212 
     213  Console_Port_Minor=minor;
     214
     215  /*
     216   * Register Device Names
     217   */
     218  status = rtems_io_register_name("/dev/console", major, Console_Port_Minor );
     219  if (status != RTEMS_SUCCESSFUL) {
    83220    rtems_fatal_error_occurred(status);
    84 
    85   /*
    86    *  Initialize Hardware
    87    */
    88 
    89   init_mc88681 ();
    90 
    91 #if CONSOLE_USE_INTERRUPTS
    92   console_initialize_interrupts();
    93 #endif
    94  
     221  }
     222  Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(Console_Port_Minor);
     223
     224  for (minor++;minor<Console_Port_Count;minor++) {
     225    /*
     226     * First perform the configuration dependent probe, then the
     227     * device dependent probe
     228     */
     229
     230    if ( (!Console_Port_Tbl[minor].deviceProbe ||
     231         Console_Port_Tbl[minor].deviceProbe(minor)) &&
     232         Console_Port_Tbl[minor].pDeviceFns->deviceProbe(minor)) {
     233      status = rtems_io_register_name(
     234        Console_Port_Tbl[minor].sDeviceName,
     235        major,
     236        minor );
     237      if (status != RTEMS_SUCCESSFUL) {
     238        rtems_fatal_error_occurred(status);
     239      }
     240
     241      /*
     242       * Initialize the hardware device.
     243       */
     244
     245      Console_Port_Tbl[minor].pDeviceFns->deviceInitialize(minor);
     246
     247    }
     248  }
     249
    95250  return RTEMS_SUCCESSFUL;
    96251}
    97252
    98 /* PAGE
    99  *
    100  *  console_write_support
    101  *
    102  *  This routine is Console Termios output entry point.
    103  *
    104  *  Input parameters:
    105  *    minor - console device minor number
    106  *    buf   - buffer of data to be written
    107  *    len   - length of data to be written
    108  *
    109  *  Output parameters:  NONE
    110  *
    111  *  Return values:
    112  *    int     number of bytes written
    113  */
    114 
    115 int console_write_support(
    116   int         minor,
    117   const char *buf,
    118   int         len)
    119 {
    120   int                       nwrite = 0;
    121   int                       port = minor;
    122 
    123   /*
    124    * verify port Number
    125    */
    126   assert ( port < NUM_PORTS );
    127 
    128   /*
    129    * poll each byte in the string out of the port.
    130    */
    131   while (nwrite < len) {
    132 #if CONSOLE_USE_INTERRUPTS
    133 #else
    134     console_outbyte_polled(port, *buf++);
    135 #endif
    136    nwrite++;
    137   }
    138 
    139   /*
    140    * return the number of bytes written.
    141    */
    142   return nwrite;
    143 }
    144 
    145 
    146 /*  PAGE
    147  *
    148  *  DEBUG_puts
    149  *
    150  *  This should be safe in the event of an error.  It attempts to insure
    151  *  that no TX empty interrupts occur while it is doing polled IO.  Then
    152  *  it restores the state of that external interrupt.
    153  *
    154  *  Input parameters:
    155  *    string  - pointer to debug output string
    156  *
    157  *  Output parameters:  NONE
    158  *
    159  *  Return values:      NONE
    160  */
    161 
    162 void DEBUG_puts(
    163   char *string
    164 )
    165 {
    166   char *s;
    167   rtems_unsigned32    isrlevel;
    168 
    169   rtems_interrupt_disable( isrlevel );
    170   for ( s = string ; *s ; s++ )
    171     console_outbyte_polled( 0, *s );
    172 
    173   console_outbyte_polled( 0, '\r' );
    174   console_outbyte_polled( 0, '\n' );
    175   rtems_interrupt_enable( isrlevel );
    176 }
    177 
    178 
    179 /* PAGE
    180  *
    181  *  console_open
    182  *
    183  *  This routine is the console device driver open entry point.
    184  *
    185  *  Input parameters:
    186  *    major - console device major number
    187  *    minor - console device minor number
    188  *    arg   - pointer to optional device driver arguments
    189  *
    190  *  Output parameters:  NONE
    191  *
    192  *  Return values:
    193  *    rtems_device_driver status code
    194  */
    195  
    196 rtems_device_driver console_open(
    197   rtems_device_major_number major,
    198   rtems_device_minor_number minor,
    199   void                    * arg
    200 )
    201 {
    202   rtems_status_code sc;
    203   int               port = minor;
    204   static const rtems_termios_callbacks pollCallbacks = {
    205     NULL,                        /* firstOpen */
    206     NULL,                        /* lastClose */
    207     console_inbyte_nonblocking,  /* pollRead */
    208     console_write_support,       /* write */
    209     NULL,                        /* setAttributes */
    210     NULL,                        /* stopRemoteTx */
    211     NULL,                        /* startRemoteTx */
    212     0                            /* outputUsesInterrupts */
    213   };
    214 
    215   /*
    216    * Verify the minor number is valid.
    217    */
    218   if (minor < 0)
    219     return RTEMS_INVALID_NUMBER;
    220 
    221   if ( port > NUM_PORTS )
    222      return RTEMS_INVALID_NUMBER;
    223 
    224   /*
    225    *  open the port as a termios console driver.
    226    */
    227   sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
    228 
    229   return sc;
    230 }
    231  
    232  
    233 
    234 /* PAGE
    235  *
    236  *  console_reserve_resources
    237  *
    238  *  This routine reserves resources for each port which may be
    239  *  used as a console.
    240  *
    241  *  Input parameters:
    242  *    configuration  - rtems configuration table.
    243  *
    244  *  Output parameters: NONE
    245  *
    246  *  Return values: NONE
    247  */
    248 
    249 void console_reserve_resources(
    250   rtems_configuration_table *configuration
    251 )
    252 {
    253   rtems_termios_reserve_resources( configuration, NUM_PORTS );
    254 }
    255 
    256 /* PAGE
    257  *
    258  *  console_close
    259  *
    260  *  This routine is the console device driver close entry point.
    261  *
    262  *  Input parameters:
    263  *    major - console device major number
    264  *    minor - console device minor number
    265  *    arg   - pointer to optional device driver arguments
    266  *
    267  *  Output parameters:  NONE
    268  *
    269  *  Return values:
    270  *    rtems_device_driver status code
    271  */
    272  
    273 rtems_device_driver console_close(
    274   rtems_device_major_number major,
    275   rtems_device_minor_number minor,
    276   void                    * arg
    277 )
    278 {
    279   return rtems_termios_close (arg);
    280 }
    281  
    282 /* PAGE
    283  *
    284  *  console_read
    285  *
    286  *  This routine is the console device driver read entry point.
    287  *
    288  *  Input parameters:
    289  *    major - console device major number
    290  *    minor - console device minor number
    291  *    arg   - pointer to optional device driver arguments
    292  *
    293  *  Output parameters:  NONE
    294  *
    295  *  Return values:
    296  *    rtems_device_driver status code
    297  *
    298  */
    299  rtems_device_driver console_read(
    300   rtems_device_major_number major,
    301   rtems_device_minor_number minor,
    302   void                    * arg
    303 )
    304 {
    305   return rtems_termios_read (arg);
    306 }
    307  
    308 /* PAGE
    309  *
    310  *  console_write
    311  *
    312  *  This routine is the console device driver write entry point.
    313  *
    314  *  Input parameters:
    315  *    major - console device major number
    316  *    minor - console device minor number
    317  *    arg   - pointer to optional device driver arguments
    318  *
    319  *  Output parameters:  NONE
    320  *
    321  *  Return values:
    322  *    rtems_device_driver status code
    323  *
    324  */
    325 rtems_device_driver console_write(
    326   rtems_device_major_number major,
    327   rtems_device_minor_number minor,
    328   void                    * arg
    329 )
    330 {
    331   return rtems_termios_write (arg);
    332 }
    333  
    334 /* PAGE
    335  *
    336  *  console_control
    337  *
    338  *  This routine is console device driver control entry point
    339  *
    340  *  Input parameters:
    341  *    major - console device major number
    342  *    minor - console device minor number
    343  *    arg   - pointer to optional device driver arguments
    344  *
    345  *  Output parameters:  NONE
    346  *
    347  *  Return values:
    348  *    rtems_device_driver status code
    349  *
    350  */
    351 rtems_device_driver console_control(
    352   rtems_device_major_number major,
    353   rtems_device_minor_number minor,
    354   void                    * arg
    355 )
    356 {
    357   return rtems_termios_ioctl (arg);
    358 }
    359 
    360 
    361 /*
    362  *  Interrupt driven console IO
    363  */
    364 
    365 #if CONSOLE_USE_INTERRUPTS
    366 
    367 /*
    368  *  Buffers between task and ISRs
    369  */
    370 
    371 #include <ringbuf.h>
    372 extern Ring_buffer_t TX_Buffer[2];
    373 extern Ring_buffer_t RX_Buffer[2];
    374 
    375 /*
    376  *  console_inbyte_interrupts
    377  *
    378  *  This routine reads a character from the UART.
    379  *
    380  *  Input parameters: NONE
    381  *
    382  *  Output parameters:  NONE
    383  *
    384  *  Return values:
    385  *    character read from UART
    386  */
    387  
    388 char console_inbyte_interrupts( int port )
    389 {
    390   char ch;
    391 
    392   while ( Ring_buffer_Is_empty( &RX_Buffer[ port ] ) );
    393  
    394   Ring_buffer_Remove_character( &RX_Buffer[ port ], ch );
    395   return ch;
    396 }
    397  
    398 /*
    399  *  console_outbyte_interrupts
    400  *
    401  *  This routine transmits a character out.
    402  *
    403  *  Input parameters:
    404  *    port - port to transmit character to
    405  *    ch  - character to be transmitted
    406  *
    407  *  Output parameters:  NONE
    408  *
    409  *  Return values:      NONE
    410  */
    411  
    412 void console_outbyte_interrupts(
    413   int  port,
    414   char ch
    415 )
    416 {
    417   /*
    418    *  If this is the first character then we need to prime the pump
    419    */
    420 
    421   if ( Is_TX_active[ port ] == FALSE ) {
    422     Is_TX_active[ port ] = TRUE;
    423     console_outbyte_polled( port, ch );
    424     return;
    425   }
    426 
    427   while ( Ring_buffer_Is_full( &TX_Buffer[ port ] ) );
    428  
    429   Ring_buffer_Add_character( &TX_Buffer[ port ], ch );
    430 }
    431 
    432 /*
    433  *  console_exit
    434  *
    435  *  This routine allows the console to exit by masking its associated interrupt
    436  *  vectors.
    437  *
    438  *  Input parameters:  NONE
    439  *
    440  *  Output parameters: NONE
    441  *
    442  *  Return values:     NONE
    443  */
    444 
    445 void console_exit()
    446 {
    447   volatile unsigned char *_addr;
    448   int port;
    449 
    450   /*
    451    *  Although the interrupts for the UART are unmasked, the PIL is set to
    452    *  disable all external interrupts.  So we might as well do this first.
    453    */
    454 
    455   /* ??? Mask All UART Interrupts           */
    456 
    457   for (port = MC68681_PORT_A; port <= MC68681_PORT_B; port++) {
    458     while (!Ring_buffer_Is_empty (&TX_Buffer[port])) {
    459       Ring_buffer_Remove_character (&TX_Buffer[port],ch);
    460       console_outbyte_polled (port,ch);
    461     }
    462   }
    463 
    464   /*
    465    *  Now wait for all the data to actually get out ... the send register
    466    *  should be empty.
    467    */
    468    _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_A);
    469    while (!(*_addr & MC68681_TX_EMPTY));
    470 
    471   _addr = (unsigned char *) (DUART_ADDR + MC68681_STATUS_REG_B);
    472    while (!(*_addr & MC68681_TX_EMPTY));
    473 }
    474 #endif /* CONSOLE_USE_INTERRUPTS */
Note: See TracChangeset for help on using the changeset viewer.