[PATCH 28] LEON3: cleanup console UART indexing handling

Joel Sherrill joel.sherrill at OARcorp.com
Thu Apr 5 19:35:58 UTC 2012


Committed.

Please review the Wiki and update it though.

On 04/05/2012 10:28 AM, Joel Sherrill wrote:
> This looks OK to apply to me.
>
> Very BSP specific and obviously dealing with a confusing
> hardware situation. :)
>
> Would you mind adding the console naming information
> to the Wiki for Leon3?
>
> http://wiki.rtems.org/wiki/index.php/Leon3
>
> It also probably needs updates for features, etc.
>
> On 04/05/2012 10:23 AM, Daniel Hellstrom wrote:
>> 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_['a' + 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 at gaisler.com>
>> ---
>>   c/src/lib/libbsp/sparc/leon3/console/console.c   |  114 ++++++++++++++-------
>>   c/src/lib/libbsp/sparc/leon3/console/debugputs.c |   73 ++++++++++-----
>>   2 files changed, 126 insertions(+), 61 deletions(-)
>>
>> diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c
>> index fee8721..a07fb15 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/console/console.c
>> +++ b/c/src/lib/libbsp/sparc/leon3/console/console.c
>> @@ -24,6 +24,15 @@
>>   #include<rtems/bspIo.h>
>>   #include<amba.h>
>>
>> +/* Let user override which on-chip APBUART will be debug UART
>> + * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
>> + * 1 = APBUART[0]
>> + * 2 = APBUART[1]
>> + * 3 = APBUART[2]
>> + * ...
>> + */
>> +int syscon_uart_index __attribute__((weak)) = 0;
>> +
>>   /*
>>    *  Should we use a polled or interrupt drived console?
>>    *
>> @@ -44,12 +53,12 @@ void console_outbyte_polled(
>>   /* body is in debugputs.c */
>>
>>   /*
>> - *  console_inbyte_nonblocking
>> + *  apbuart_inbyte_nonblocking
>>    *
>>    *  This routine polls for a character.
>>    */
>>
>> -int console_inbyte_nonblocking( int port );
>> +int apbuart_inbyte_nonblocking(int port);
>>
>>   /* body is in debugputs.c */
>>
>> @@ -61,15 +70,31 @@ int console_inbyte_nonblocking( int port );
>>
>>   ssize_t console_write_support (int minor, const char *buf, size_t len)
>>   {
>> -  int nwrite = 0;
>> +  int nwrite = 0, port;
>> +
>> +  if (minor == 0)
>> +    port = syscon_uart_index;
>> +  else
>> +    port = minor - 1;
>>
>>     while (nwrite<  len) {
>> -    console_outbyte_polled( minor, *buf++ );
>> +    console_outbyte_polled(port, *buf++);
>>       nwrite++;
>>     }
>>     return nwrite;
>>   }
>>
>> +int console_inbyte_nonblocking(int minor)
>> +{
>> +  int port;
>> +
>> +  if (minor == 0)
>> +    port = syscon_uart_index;
>> +  else
>> +    port = minor - 1;
>> +
>> +  return apbuart_inbyte_nonblocking(port);
>> +}
>>
>>   /*
>>    *  Console Device Driver Entry Points
>> @@ -85,45 +110,47 @@ rtems_device_driver console_initialize(
>>   )
>>   {
>>     rtems_status_code status;
>> -  int i, uart0;
>> +  int i;
>>     char console_name[16];
>>
>>     rtems_termios_initialize();
>>
>> -  /* default console to zero and override if multiprocessing */
>> -  uart0 = 0;
>> -  #if defined(RTEMS_MULTIPROCESSING)
>> -    if (rtems_configuration_get_user_multiprocessing_table() != NULL)
>> -      uart0 =  LEON3_Cpu_Index;
>> -  #endif
>> +  /* Update syscon_uart_index to index used as /dev/console
>> +   * Let user select System console by setting syscon_uart_index. If the
>> +   * BSP is to provide the default UART (syscon_uart_index==0):
>> +   *   non-MP: APBUART[0] is system console
>> +   *   MP: LEON CPU index select UART
>> +   */
>> +  if (syscon_uart_index == 0) {
>> +#if defined(RTEMS_MULTIPROCESSING)
>> +    syscon_uart_index = LEON3_Cpu_Index;
>> +#else
>> +    syscon_uart_index = 0;
>> +#endif
>> +  } else {
>> +    syscon_uart_index = syscon_uart_index - 1; /* User selected sys-console */
>> +  }
>>
>> -  /*  Register Device Names */
>> -  if (uarts&&  (uart0<  uarts)) {
>> +  /*  Register Device Names
>> +   *
>> +   *  0 /dev/console   - APBUART[USER-SELECTED, DEFAULT=APBUART[0]]
>> +   *  1 /dev/console_a - APBUART[0] (by default not present because is console)
>> +   *  2 /dev/console_b - APBUART[1]
>> +   *  ...
>> +   *
>> +   * On a MP system one should not open UARTs that other OS instances use.
>> +   */
>> +  if (syscon_uart_index<  uarts) {
>>       status = rtems_io_register_name( "/dev/console", major, 0 );
>>       if (status != RTEMS_SUCCESSFUL)
>>         rtems_fatal_error_occurred(status);
>> -
>> -    strcpy(console_name,"/dev/console_a");
>> -    for (i = uart0+1; i<  uarts; i++) {
>> -      console_name[13]++;
>> -      status = rtems_io_register_name( console_name, major, i);
>> -    }
>>     }
>> -
>> -  /*
>> -   *  Initialize Hardware if ONLY CPU or first CPU in MP system
>> -   */
>> -
>> -  #if defined(RTEMS_MULTIPROCESSING)
>> -    if (rtems_configuration_get_user_multiprocessing_table()->node == 1)
>> -  #endif
>> -  {
>> -    for (i = uart0; i<  uarts; i++)
>> -    {
>> -      LEON3_Console_Uart[i]->ctrl |=
>> -        LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
>> -      LEON3_Console_Uart[i]->status = 0;
>> -    }
>> +  strcpy(console_name,"/dev/console_a");
>> +  for (i = 0; i<  uarts; i++) {
>> +    if (i == syscon_uart_index)
>> +      continue; /* skip UART that is registered as /dev/console */
>> +    console_name[13] = 'a' + i;
>> +    status = rtems_io_register_name( console_name, major, i+1);
>>     }
>>
>>     return RTEMS_SUCCESSFUL;
>> @@ -136,6 +163,7 @@ rtems_device_driver console_open(
>>   )
>>   {
>>     rtems_status_code sc;
>> +  int port;
>>
>>     static const rtems_termios_callbacks pollCallbacks = {
>>       NULL,                        /* firstOpen */
>> @@ -148,13 +176,23 @@ rtems_device_driver console_open(
>>       0                            /* outputUsesInterrupts */
>>     };
>>
>> -
>> -  assert( minor<= LEON3_APBUARTS );
>> -  if ( minor>  LEON3_APBUARTS )
>> +  assert(minor<= uarts);
>> +  if (minor>  uarts || minor == (syscon_uart_index + 1))
>>       return RTEMS_INVALID_NUMBER;
>>
>>     sc = rtems_termios_open (major, minor, arg,&pollCallbacks);
>> -
>> +  if (sc != RTEMS_SUCCESSFUL)
>> +    return sc;
>> +
>> +  if (minor == 0)
>> +    port = syscon_uart_index;
>> +  else
>> +    port = minor - 1;
>> +
>> +  /* Initialize UART on opening */
>> +  LEON3_Console_Uart[port]->ctrl |= LEON_REG_UART_CTRL_RE |
>> +                                     LEON_REG_UART_CTRL_TE;
>> +  LEON3_Console_Uart[port]->status = 0;
>>
>>     return RTEMS_SUCCESSFUL;
>>   }
>> diff --git a/c/src/lib/libbsp/sparc/leon3/console/debugputs.c b/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
>> index 2cd0d13..cf3f280 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
>> +++ b/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
>> @@ -7,8 +7,8 @@
>>    *  On-Line Applications Research Corporation (OAR).
>>    *
>>    *  Modified for LEON3 BSP.
>> - *  COPYRIGHT (c) 2004.
>> - *  Gaisler Research.
>> + *  COPYRIGHT (c) 2011.
>> + *  Aeroflex Gaisler.
>>    *
>>    *  The license and distribution terms for this file may be
>>    *  found in the file LICENSE in this distribution or at
>> @@ -29,6 +29,15 @@ extern int uarts;
>>
>>   static int isinit = 0;
>>
>> +/* Let user override which on-chip APBUART will be debug UART
>> + * 0 = Default APBUART. On MP system CPU0=APBUART0, CPU1=APBUART1...
>> + * 1 = APBUART[0]
>> + * 2 = APBUART[1]
>> + * 3 = APBUART[2]
>> + * ...
>> + */
>> +int debug_uart_index __attribute__((weak)) = 0;
>> +
>>   /*
>>    *  Scan for UARTS in configuration
>>    */
>> @@ -47,11 +56,27 @@ int scan_uarts(void)
>>         LEON3_Console_Uart[i] = (volatile LEON3_UART_Regs_Map *)apbuarts[i].start;
>>       }
>>
>> -    /* initialize uart 0 if present for printk */
>> -    if ( uarts ) {
>> -      LEON3_Console_Uart[0]->ctrl |=
>> -        LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
>> -      LEON3_Console_Uart[0]->status = 0;
>> +    /* Update debug_uart_index to index used as debug console.
>> +     * Let user select Debug console by setting debug_uart_index. If the
>> +     * BSP is to provide the default UART (debug_uart_index==0):
>> +     *   non-MP: APBUART[0] is debug console
>> +     *   MP: LEON CPU index select UART
>> +     */
>> +    if (debug_uart_index == 0) {
>> +#if defined(RTEMS_MULTIPROCESSING)
>> +      debug_uart_index = LEON3_Cpu_Index;
>> +#else
>> +      debug_uart_index = 0;
>> +#endif
>> +    } else {
>> +      debug_uart_index = debug_uart_index - 1; /* User selected dbg-console */
>> +    }
>> +
>> +    /* initialize debug uart if present for printk */
>> +    if (debug_uart_index<  uarts) {
>> +      LEON3_Console_Uart[debug_uart_index]->ctrl |= LEON_REG_UART_CTRL_RE |
>> +                                                    LEON_REG_UART_CTRL_TE;
>> +      LEON3_Console_Uart[debug_uart_index]->status = 0;
>>       }
>>       isinit = 1;
>>     }
>> @@ -70,10 +95,10 @@ void console_outbyte_polled(
>>   )
>>   {
>>     if ((port>= 0)&&  (port<  uarts)) {
>> -    int u = LEON3_Cpu_Index+port;
>> -    while ( (LEON3_Console_Uart[u]->status&  LEON_REG_UART_STATUS_THE) == 0 );
>> -    LEON3_Console_Uart[u]->data = (unsigned int) ch;
>> -  }
>> +    return;
>> +
>> +  while ( (LEON3_Console_Uart[port]->status&  LEON_REG_UART_STATUS_THE) == 0 );
>> +  LEON3_Console_Uart[port]->data = (unsigned int) ch;
>>   }
>>
>>   /*
>> @@ -81,26 +106,27 @@ void console_outbyte_polled(
>>    *
>>    *  This routine polls for a character.
>>    */
>> -int console_inbyte_nonblocking( int port )
>> +int apbuart_inbyte_nonblocking(int port)
>>   {
>>     if ((port>= 0)&&  (port<  uarts)) {
>> -    int u = LEON3_Cpu_Index+port;
>> -    if (LEON3_Console_Uart[u]->status&  LEON_REG_UART_STATUS_ERR)
>> -      LEON3_Console_Uart[u]->status = ~LEON_REG_UART_STATUS_ERR;
>> -
>> -    if ((LEON3_Console_Uart[u]->status&  LEON_REG_UART_STATUS_DR) == 0)
>> -      return -1;
>> -    return (int) LEON3_Console_Uart[u]->data;
>> -  } else {
>>       assert( 0 );
>> +    return -1;
>>     }
>> -  return -1;
>> +
>> +  /* Clear errors */
>> +  if (LEON3_Console_Uart[port]->status&  LEON_REG_UART_STATUS_ERR)
>> +    LEON3_Console_Uart[port]->status = ~LEON_REG_UART_STATUS_ERR;
>> +
>> +  if ((LEON3_Console_Uart[port]->status&  LEON_REG_UART_STATUS_DR) == 0)
>> +    return -1;
>> +  else
>> +    return (int) LEON3_Console_Uart[port]->data;
>>   }
>>
>>   /* putchar/getchar for printk */
>>   static void bsp_out_char(char c)
>>   {
>> -  console_outbyte_polled(0, c);
>> +  console_outbyte_polled(debug_uart_index, c);
>>   }
>>
>>   /*
>> @@ -115,7 +141,8 @@ static int bsp_in_char(void)
>>   {
>>     int tmp;
>>
>> -  while ((tmp = console_inbyte_nonblocking(0))<  0);
>> +  while ((tmp = apbuart_inbyte_nonblocking(debug_uart_index))<  0)
>> +    ;
>>     return tmp;
>>   }
>>
>
>
> -- 
> Joel Sherrill, Ph.D.             Director of Research&   Development
> joel.sherrill at OARcorp.com         On-Line Applications Research
> Ask me about RTEMS: a free RTOS  Huntsville AL 35805
>      Support Available             (256) 722-9985
>


-- 
Joel Sherrill, Ph.D.             Director of Research&   Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
     Support Available             (256) 722-9985


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20120405/4828c88a/attachment-0001.html>


More information about the devel mailing list