diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2012-04-05 10:23:18 -0500 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@oarcorp.com> | 2012-04-05 14:33:48 -0500 |
commit | 4b557617fdd3448f1c40798e3a075a5d8ce9a5c6 (patch) | |
tree | 9f7a9021037a20a4438cb47991df8d519d4e7c0d /c/src/lib/libbsp | |
parent | Add MIPS/Malta BSP. (diff) | |
download | rtems-4b557617fdd3448f1c40798e3a075a5d8ce9a5c6.tar.bz2 |
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_['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@gaisler.com>
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/console/console.c | 114 | ||||
-rw-r--r-- | 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 fee8721dee..a07fb154b9 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 2cd0d136e1..cf3f280520 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; } |