[PATCH 28] LEON3: cleanup console UART indexing handling
Joel Sherrill
joel.sherrill at OARcorp.com
Thu Apr 5 15:28:12 UTC 2012
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20120405/df9eb919/attachment-0001.html>
More information about the devel
mailing list