Changeset 4b557617 in rtems


Ignore:
Timestamp:
Apr 5, 2012, 3:23:18 PM (8 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
4.11, master
Children:
e60e862
Parents:
a36d1b4
git-author:
Daniel Hellstrom <daniel@…> (04/05/12 15:23:18)
git-committer:
Joel Sherrill <joel.sherrill@…> (04/05/12 19:33:48)
Message:

LEON3: cleanup console UART indexing handling

The UART indexing was rather a mess when MP was enabled. The changes
introduces two weak variables syscon_uart_index and debug_uart_index
so that the user can override the default system debug console (printk)
and system console UART (/dev/console).

The two weak variables is updated on boot to reflect the "real" UART
index.

MINOR DEVICE-FS-NAME UART
0 /dev/console Default /dev/console_a, user selectable
1 /dev/console_a APBUART[0] (missing by default)
2 /dev/console_b APBUART[1]
...

/dev/console_a is by default renamed /dev/console and assigned minor=0,
but user can select /dev/console_['a'+N] to be renamed to /dev/console
by setting syscon_uart_index=N.

On a MP system the console renamed to /dev/console is selected by CPU
index (LEON3_Cpu_Index). /dev/console_+ LEON3_Cpu_Index? is
renamed unless overrided. Resource sharing is performed by the user,
one should not open/access a console that another OS instance uses.

This patch also moves the initialization of the UART to the open()
call, note that before APBUART[0] was always enabled as debug uart
even on MP systems. The debug UART is initialized at boot time.

Signed-off-by: Daniel Hellstrom <daniel@…>

Location:
c/src/lib/libbsp/sparc/leon3/console
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/leon3/console/console.c

    ra36d1b4 r4b557617  
    2525#include <amba.h>
    2626
     27/* Let user override which on-chip APBUART will be debug UART
     28 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
     29 * 1 = APBUART[0]
     30 * 2 = APBUART[1]
     31 * 3 = APBUART[2]
     32 * ...
     33 */
     34int syscon_uart_index __attribute__((weak)) = 0;
     35
    2736/*
    2837 *  Should we use a polled or interrupt drived console?
     
    4554
    4655/*
    47  *  console_inbyte_nonblocking
     56 *  apbuart_inbyte_nonblocking
    4857 *
    4958 *  This routine polls for a character.
    5059 */
    5160
    52 int console_inbyte_nonblocking( int port );
     61int apbuart_inbyte_nonblocking(int port);
    5362
    5463/* body is in debugputs.c */
     
    6271ssize_t console_write_support (int minor, const char *buf, size_t len)
    6372{
    64   int nwrite = 0;
     73  int nwrite = 0, port;
     74
     75  if (minor == 0)
     76    port = syscon_uart_index;
     77  else
     78    port = minor - 1;
    6579
    6680  while (nwrite < len) {
    67     console_outbyte_polled( minor, *buf++ );
     81    console_outbyte_polled(port, *buf++);
    6882    nwrite++;
    6983  }
     
    7185}
    7286
     87int console_inbyte_nonblocking(int minor)
     88{
     89  int port;
     90
     91  if (minor == 0)
     92    port = syscon_uart_index;
     93  else
     94    port = minor - 1;
     95
     96  return apbuart_inbyte_nonblocking(port);
     97}
    7398
    7499/*
     
    86111{
    87112  rtems_status_code status;
    88   int i, uart0;
     113  int i;
    89114  char console_name[16];
    90115
    91116  rtems_termios_initialize();
    92117
    93   /* default console to zero and override if multiprocessing */
    94   uart0 = 0;
    95   #if defined(RTEMS_MULTIPROCESSING)
    96     if (rtems_configuration_get_user_multiprocessing_table() != NULL)
    97       uart0 =  LEON3_Cpu_Index;
    98   #endif
    99 
    100   /*  Register Device Names */
    101   if (uarts && (uart0 < uarts)) {
     118  /* Update syscon_uart_index to index used as /dev/console
     119   * Let user select System console by setting syscon_uart_index. If the
     120   * BSP is to provide the default UART (syscon_uart_index==0):
     121   *   non-MP: APBUART[0] is system console
     122   *   MP: LEON CPU index select UART
     123   */
     124  if (syscon_uart_index == 0) {
     125#if defined(RTEMS_MULTIPROCESSING)
     126    syscon_uart_index = LEON3_Cpu_Index;
     127#else
     128    syscon_uart_index = 0;
     129#endif
     130  } else {
     131    syscon_uart_index = syscon_uart_index - 1; /* User selected sys-console */
     132  }
     133
     134  /*  Register Device Names
     135   *
     136   *  0 /dev/console   - APBUART[USER-SELECTED, DEFAULT=APBUART[0]]
     137   *  1 /dev/console_a - APBUART[0] (by default not present because is console)
     138   *  2 /dev/console_b - APBUART[1]
     139   *  ...
     140   *
     141   * On a MP system one should not open UARTs that other OS instances use.
     142   */
     143  if (syscon_uart_index < uarts) {
    102144    status = rtems_io_register_name( "/dev/console", major, 0 );
    103145    if (status != RTEMS_SUCCESSFUL)
    104146      rtems_fatal_error_occurred(status);
    105 
    106     strcpy(console_name,"/dev/console_a");
    107     for (i = uart0+1; i < uarts; i++) {
    108       console_name[13]++;
    109       status = rtems_io_register_name( console_name, major, i);
    110     }
    111   }
    112 
    113   /*
    114    *  Initialize Hardware if ONLY CPU or first CPU in MP system
    115    */
    116 
    117   #if defined(RTEMS_MULTIPROCESSING)
    118     if (rtems_configuration_get_user_multiprocessing_table()->node == 1)
    119   #endif
    120   {
    121     for (i = uart0; i < uarts; i++)
    122     {
    123       LEON3_Console_Uart[i]->ctrl |=
    124         LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
    125       LEON3_Console_Uart[i]->status = 0;
    126     }
     147  }
     148  strcpy(console_name,"/dev/console_a");
     149  for (i = 0; i < uarts; i++) {
     150    if (i == syscon_uart_index)
     151      continue; /* skip UART that is registered as /dev/console */
     152    console_name[13] = 'a' + i;
     153    status = rtems_io_register_name( console_name, major, i+1);
    127154  }
    128155
     
    137164{
    138165  rtems_status_code sc;
     166  int port;
    139167
    140168  static const rtems_termios_callbacks pollCallbacks = {
     
    149177  };
    150178
    151 
    152   assert( minor <= LEON3_APBUARTS );
    153   if ( minor > LEON3_APBUARTS )
     179  assert(minor <= uarts);
     180  if (minor > uarts || minor == (syscon_uart_index + 1))
    154181    return RTEMS_INVALID_NUMBER;
    155182
    156183  sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
    157 
     184  if (sc != RTEMS_SUCCESSFUL)
     185    return sc;
     186
     187  if (minor == 0)
     188    port = syscon_uart_index;
     189  else
     190    port = minor - 1;
     191
     192  /* Initialize UART on opening */
     193  LEON3_Console_Uart[port]->ctrl |= LEON_REG_UART_CTRL_RE |
     194                                     LEON_REG_UART_CTRL_TE;
     195  LEON3_Console_Uart[port]->status = 0;
    158196
    159197  return RTEMS_SUCCESSFUL;
  • c/src/lib/libbsp/sparc/leon3/console/debugputs.c

    ra36d1b4 r4b557617  
    88 *
    99 *  Modified for LEON3 BSP.
    10  *  COPYRIGHT (c) 2004.
    11  *  Gaisler Research.
     10 *  COPYRIGHT (c) 2011.
     11 *  Aeroflex Gaisler.
    1212 *
    1313 *  The license and distribution terms for this file may be
     
    3030static int isinit = 0;
    3131
     32/* Let user override which on-chip APBUART will be debug UART
     33 * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
     34 * 1 = APBUART[0]
     35 * 2 = APBUART[1]
     36 * 3 = APBUART[2]
     37 * ...
     38 */
     39int debug_uart_index __attribute__((weak)) = 0;
     40
    3241/*
    3342 *  Scan for UARTS in configuration
     
    4857    }
    4958
    50     /* initialize uart 0 if present for printk */
    51     if ( uarts ) {
    52       LEON3_Console_Uart[0]->ctrl |=
    53         LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
    54       LEON3_Console_Uart[0]->status = 0;
     59    /* Update debug_uart_index to index used as debug console.
     60     * Let user select Debug console by setting debug_uart_index. If the
     61     * BSP is to provide the default UART (debug_uart_index==0):
     62     *   non-MP: APBUART[0] is debug console
     63     *   MP: LEON CPU index select UART
     64     */
     65    if (debug_uart_index == 0) {
     66#if defined(RTEMS_MULTIPROCESSING)
     67      debug_uart_index = LEON3_Cpu_Index;
     68#else
     69      debug_uart_index = 0;
     70#endif
     71    } else {
     72      debug_uart_index = debug_uart_index - 1; /* User selected dbg-console */
     73    }
     74
     75    /* initialize debug uart if present for printk */
     76    if (debug_uart_index < uarts) {
     77      LEON3_Console_Uart[debug_uart_index]->ctrl |= LEON_REG_UART_CTRL_RE |
     78                                                    LEON_REG_UART_CTRL_TE;
     79      LEON3_Console_Uart[debug_uart_index]->status = 0;
    5580    }
    5681    isinit = 1;
     
    7196{
    7297  if ((port >= 0) && (port < uarts)) {
    73     int u = LEON3_Cpu_Index+port;
    74     while ( (LEON3_Console_Uart[u]->status & LEON_REG_UART_STATUS_THE) == 0 );
    75     LEON3_Console_Uart[u]->data = (unsigned int) ch;
    76   }
     98    return;
     99
     100  while ( (LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_THE) == 0 );
     101  LEON3_Console_Uart[port]->data = (unsigned int) ch;
    77102}
    78103
     
    82107 *  This routine polls for a character.
    83108 */
    84 int console_inbyte_nonblocking( int port )
     109int apbuart_inbyte_nonblocking(int port)
    85110{
    86111  if ((port >= 0) && (port < uarts)) {
    87     int u = LEON3_Cpu_Index+port;
    88     if (LEON3_Console_Uart[u]->status & LEON_REG_UART_STATUS_ERR)
    89       LEON3_Console_Uart[u]->status = ~LEON_REG_UART_STATUS_ERR;
     112    assert( 0 );
     113    return -1;
     114  }
    90115
    91     if ((LEON3_Console_Uart[u]->status & LEON_REG_UART_STATUS_DR) == 0)
    92       return -1;
    93     return (int) LEON3_Console_Uart[u]->data;
    94   } else {
    95     assert( 0 );
    96   }
    97   return -1;
     116  /* Clear errors */
     117  if (LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_ERR)
     118    LEON3_Console_Uart[port]->status = ~LEON_REG_UART_STATUS_ERR;
     119
     120  if ((LEON3_Console_Uart[port]->status & LEON_REG_UART_STATUS_DR) == 0)
     121    return -1;
     122  else
     123    return (int) LEON3_Console_Uart[port]->data;
    98124}
    99125
     
    101127static void bsp_out_char(char c)
    102128{
    103   console_outbyte_polled(0, c);
     129  console_outbyte_polled(debug_uart_index, c);
    104130}
    105131
     
    116142  int tmp;
    117143
    118   while ((tmp = console_inbyte_nonblocking(0)) < 0);
     144  while ((tmp = apbuart_inbyte_nonblocking(debug_uart_index)) < 0)
     145    ;
    119146  return tmp;
    120147}
Note: See TracChangeset for help on using the changeset viewer.