source: rtems/c/src/lib/libbsp/sparc/leon3/console/console.c @ 4b557617

4.115
Last change on this file since 4b557617 was 4b557617, checked in by Daniel Hellstrom <daniel@…>, on 04/05/12 at 15:23:18

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@…>

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 *  This file contains the TTY driver for the serial ports on the LEON.
3 *
4 *  This driver uses the termios pseudo driver.
5 *
6 *  COPYRIGHT (c) 1989-1998.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  Modified for LEON3 BSP.
10 *  COPYRIGHT (c) 2004.
11 *  Gaisler Research.
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 *
17 *  $Id$
18 */
19
20#include <bsp.h>
21#include <rtems/libio.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <rtems/bspIo.h>
25#include <amba.h>
26
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
36/*
37 *  Should we use a polled or interrupt drived console?
38 *
39 *  NOTE: This is defined in the custom/leon.cfg file.
40 */
41
42/*
43 *  console_outbyte_polled
44 *
45 *  This routine transmits a character using polling.
46 */
47
48void console_outbyte_polled(
49  int  port,
50  char ch
51);
52
53/* body is in debugputs.c */
54
55/*
56 *  apbuart_inbyte_nonblocking
57 *
58 *  This routine polls for a character.
59 */
60
61int apbuart_inbyte_nonblocking(int port);
62
63/* body is in debugputs.c */
64
65
66/*
67 *  Console Termios Support Entry Points
68 *
69 */
70
71ssize_t console_write_support (int minor, const char *buf, size_t len)
72{
73  int nwrite = 0, port;
74
75  if (minor == 0)
76    port = syscon_uart_index;
77  else
78    port = minor - 1;
79
80  while (nwrite < len) {
81    console_outbyte_polled(port, *buf++);
82    nwrite++;
83  }
84  return nwrite;
85}
86
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}
98
99/*
100 *  Console Device Driver Entry Points
101 *
102 */
103int uarts = 0;
104volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
105
106rtems_device_driver console_initialize(
107  rtems_device_major_number  major,
108  rtems_device_minor_number  minor,
109  void                      *arg
110)
111{
112  rtems_status_code status;
113  int i;
114  char console_name[16];
115
116  rtems_termios_initialize();
117
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) {
144    status = rtems_io_register_name( "/dev/console", major, 0 );
145    if (status != RTEMS_SUCCESSFUL)
146      rtems_fatal_error_occurred(status);
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);
154  }
155
156  return RTEMS_SUCCESSFUL;
157}
158
159rtems_device_driver console_open(
160  rtems_device_major_number major,
161  rtems_device_minor_number minor,
162  void                    * arg
163)
164{
165  rtems_status_code sc;
166  int port;
167
168  static const rtems_termios_callbacks pollCallbacks = {
169    NULL,                        /* firstOpen */
170    NULL,                        /* lastClose */
171    console_inbyte_nonblocking,  /* pollRead */
172    console_write_support,       /* write */
173    NULL,                        /* setAttributes */
174    NULL,                        /* stopRemoteTx */
175    NULL,                        /* startRemoteTx */
176    0                            /* outputUsesInterrupts */
177  };
178
179  assert(minor <= uarts);
180  if (minor > uarts || minor == (syscon_uart_index + 1))
181    return RTEMS_INVALID_NUMBER;
182
183  sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
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;
196
197  return RTEMS_SUCCESSFUL;
198}
199
200rtems_device_driver console_close(
201  rtems_device_major_number major,
202  rtems_device_minor_number minor,
203  void                    * arg
204)
205{
206  return rtems_termios_close (arg);
207}
208
209rtems_device_driver console_read(
210  rtems_device_major_number major,
211  rtems_device_minor_number minor,
212  void                    * arg
213)
214{
215  return rtems_termios_read (arg);
216}
217
218rtems_device_driver console_write(
219  rtems_device_major_number major,
220  rtems_device_minor_number minor,
221  void                    * arg
222)
223{
224  return rtems_termios_write (arg);
225}
226
227rtems_device_driver console_control(
228  rtems_device_major_number major,
229  rtems_device_minor_number minor,
230  void                    * arg
231)
232{
233  return rtems_termios_ioctl (arg);
234}
235
Note: See TracBrowser for help on using the repository browser.