<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
This looks OK to apply to me.<br>
<br>
Very BSP specific and obviously dealing with a confusing<br>
hardware situation. :)<br>
<br>
Would you mind adding the console naming information<br>
to the Wiki for Leon3?<br>
<br>
<meta http-equiv="content-type" content="text/html;
charset=ISO-8859-1">
<a href="http://wiki.rtems.org/wiki/index.php/Leon3">http://wiki.rtems.org/wiki/index.php/Leon3</a><br>
<br>
It also probably needs updates for features, etc.<br>
<br>
On 04/05/2012 10:23 AM, Daniel Hellstrom wrote:
<blockquote
cite="mid:1333639401-32493-4-git-send-email-daniel@gaisler.com"
type="cite">
<pre wrap="">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 <a class="moz-txt-link-rfc2396E" href="mailto:daniel@gaisler.com"><daniel@gaisler.com></a>
---
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;
}
</pre>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--
Joel Sherrill, Ph.D. Director of Research& Development
<a class="moz-txt-link-abbreviated" href="mailto:joel.sherrill@OARcorp.com">joel.sherrill@OARcorp.com</a> On-Line Applications Research
Ask me about RTEMS: a free RTOS Huntsville AL 35805
Support Available (256) 722-9985
</pre>
</body>
</html>