source: rtems/bsps/powerpc/qoriq/console/console-config.c @ 8f8ccee

5
Last change on this file since 8f8ccee was d7d66d7, checked in by Sebastian Huber <sebastian.huber@…>, on 04/19/18 at 04:28:01

bsps: Move console drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief Console configuration.
7 */
8
9/*
10 * Copyright (c) 2010, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <string.h>
24
25#include <libfdt.h>
26
27#include <rtems/bspIo.h>
28
29#include <libchip/ns16550.h>
30
31#include <asm/epapr_hcalls.h>
32
33#include <bsp.h>
34#include <bsp/fdt.h>
35#include <bsp/irq.h>
36#include <bsp/qoriq.h>
37#include <bsp/intercom.h>
38#include <bsp/uart-bridge.h>
39#include <bsp/console-termios.h>
40
41static void output_char(char c);
42
43#ifdef QORIQ_IS_HYPERVISOR_GUEST
44typedef struct {
45  rtems_termios_device_context base;
46  uint32_t handle;
47} qoriq_bc_context;
48
49static bool qoriq_bc_probe(rtems_termios_device_context *base)
50{
51  qoriq_bc_context *ctx;
52  const void *fdt;
53  int node;
54  const uint32_t *handle;
55  int len;
56
57  fdt = bsp_fdt_get();
58
59  node = fdt_node_offset_by_compatible(fdt, -1, "epapr,hv-byte-channel");
60  if (node < 0) {
61    return false;
62  }
63
64  handle = fdt_getprop(fdt, node, "hv-handle", &len);
65  if (handle == NULL || len != 4) {
66    return false;
67  }
68
69  ctx = (qoriq_bc_context *) base;
70  ctx->handle = fdt32_to_cpu(*handle);
71
72  BSP_output_char = output_char;
73  return true;
74}
75
76static int qoriq_bc_read_polled(rtems_termios_device_context *base)
77{
78  qoriq_bc_context *ctx;
79  char buf[EV_BYTE_CHANNEL_MAX_BYTES];
80  unsigned int count;
81  unsigned int status;
82
83  ctx = (qoriq_bc_context *) base;
84  count = 1;
85  status = ev_byte_channel_receive(ctx->handle, &count, buf);
86
87  if (status != EV_SUCCESS || count == 0) {
88    return -1;
89  }
90
91  return (unsigned char) buf[0];
92}
93
94static void qoriq_bc_write_polled(
95  rtems_termios_device_context *base,
96  const char *buf,
97  size_t len
98)
99{
100  qoriq_bc_context *ctx;
101  uint32_t handle;
102
103  ctx = (qoriq_bc_context *) base;
104  handle = ctx->handle;
105
106  while (len > 0) {
107    unsigned int count;
108    unsigned int status;
109    char buf2[EV_BYTE_CHANNEL_MAX_BYTES];
110    const char *out;
111
112    if (len < EV_BYTE_CHANNEL_MAX_BYTES) {
113      count = len;
114      out = memcpy(buf2, buf, len);
115    } else {
116      count = EV_BYTE_CHANNEL_MAX_BYTES;
117      out = buf;
118    }
119
120    status = ev_byte_channel_send(handle, &count, out);
121
122    if (status == EV_SUCCESS) {
123      len -= count;
124      buf += count;
125    }
126  }
127}
128
129static const rtems_termios_device_handler qoriq_bc_handler_polled = {
130  .poll_read = qoriq_bc_read_polled,
131  .write = qoriq_bc_write_polled,
132  .mode = TERMIOS_POLLED
133};
134
135static qoriq_bc_context qoriq_bc_context_0 = {
136  .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("BC 0"),
137};
138#endif /* QORIQ_IS_HYPERVISOR_GUEST */
139
140#if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \
141  || (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2)
142  #define BRIDGE_MASTER
143#elif QORIQ_UART_BRIDGE_0_ENABLE || QORIQ_UART_BRIDGE_1_ENABLE
144  #define BRIDGE_SLAVE
145#endif
146
147#ifdef BSP_USE_UART_INTERRUPTS
148  #define DEVICE_FNS &ns16550_handler_interrupt
149#else
150  #define DEVICE_FNS &ns16550_handler_polled
151#endif
152
153#if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE
154  static bool uart_probe(rtems_termios_device_context *base)
155  {
156    ns16550_context *ctx = (ns16550_context *) base;
157
158    ctx->clock = BSP_bus_frequency;
159
160    return ns16550_probe(base);
161  }
162
163  static uint8_t get_register(uintptr_t addr, uint8_t i)
164  {
165    volatile uint8_t *reg = (uint8_t *) addr;
166
167    return reg [i];
168  }
169
170  static void set_register(uintptr_t addr, uint8_t i, uint8_t val)
171  {
172    volatile uint8_t *reg = (uint8_t *) addr;
173
174    reg [i] = val;
175  }
176#endif
177
178#if QORIQ_UART_0_ENABLE
179static ns16550_context qoriq_uart_context_0 = {
180  .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
181  .get_reg = get_register,
182  .set_reg = set_register,
183  .port = (uintptr_t) &qoriq.uart_0,
184  .irq = QORIQ_IRQ_DUART_1,
185  .initial_baud = BSP_CONSOLE_BAUD
186};
187#endif
188
189#if QORIQ_UART_1_ENABLE
190static ns16550_context qoriq_uart_context_1 = {
191  .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
192  .get_reg = get_register,
193  .set_reg = set_register,
194  .port = (uintptr_t) &qoriq.uart_1,
195  .irq = QORIQ_IRQ_DUART_1,
196  .initial_baud = BSP_CONSOLE_BAUD
197};
198#endif
199
200#ifdef BRIDGE_MASTER
201  #define BRIDGE_PROBE qoriq_uart_bridge_master_probe
202  #define BRIDGE_FNS &qoriq_uart_bridge_master
203  #if QORIQ_UART_BRIDGE_0_ENABLE
204    static uart_bridge_master_context bridge_0_context = {
205      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
206      .device_path = "/dev/ttyS0",
207      .type = INTERCOM_TYPE_UART_0,
208      .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
209        bridge_0_context.transmit_fifo
210      )
211    };
212    #define BRIDGE_0_CONTEXT &bridge_0_context.base
213  #endif
214  #if QORIQ_UART_BRIDGE_1_ENABLE
215    static uart_bridge_master_context bridge_1_context = {
216      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
217      .device_path = "/dev/ttyS1",
218      .type = INTERCOM_TYPE_UART_1,
219      .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
220        bridge_1_context.transmit_fifo
221      )
222    };
223    #define BRIDGE_1_CONTEXT &bridge_1_context.base
224  #endif
225#endif
226
227#ifdef BRIDGE_SLAVE
228  #define BRIDGE_PROBE console_device_probe_default
229  #define BRIDGE_FNS &qoriq_uart_bridge_slave
230  #if QORIQ_UART_BRIDGE_0_ENABLE
231    static uart_bridge_slave_context bridge_0_context = {
232      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
233      .type = INTERCOM_TYPE_UART_0,
234      .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
235        bridge_0_context.transmit_fifo
236      )
237    };
238    #define BRIDGE_0_CONTEXT &bridge_0_context.base
239  #endif
240  #if QORIQ_UART_BRIDGE_1_ENABLE
241    static uart_bridge_slave_context bridge_1_context = {
242      .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
243      .type = INTERCOM_TYPE_UART_1,
244      .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
245        bridge_1_context.transmit_fifo
246      )
247    };
248    #define BRIDGE_1_CONTEXT &bridge_1_context.base
249  #endif
250#endif
251
252const console_device console_device_table[] = {
253  #ifdef QORIQ_IS_HYPERVISOR_GUEST
254    {
255      .device_file = "/dev/ttyBC0",
256      .probe = qoriq_bc_probe,
257      .handler = &qoriq_bc_handler_polled,
258      .context = &qoriq_bc_context_0.base
259    },
260  #endif
261  #if QORIQ_UART_0_ENABLE
262    {
263      .device_file = "/dev/ttyS0",
264      .probe = uart_probe,
265      .handler = DEVICE_FNS,
266      .context = &qoriq_uart_context_0.base
267    },
268  #endif
269  #if QORIQ_UART_1_ENABLE
270    {
271      .device_file = "/dev/ttyS1",
272      .probe = uart_probe,
273      .handler = DEVICE_FNS,
274      .context = &qoriq_uart_context_1.base
275    },
276  #endif
277  #if QORIQ_UART_BRIDGE_0_ENABLE
278    {
279      #if QORIQ_UART_1_ENABLE
280        .device_file = "/dev/ttyB0",
281      #else
282        .device_file = "/dev/ttyS0",
283      #endif
284      .probe = BRIDGE_PROBE,
285      .handler = BRIDGE_FNS,
286      .context = BRIDGE_0_CONTEXT
287    },
288  #endif
289  #if QORIQ_UART_BRIDGE_1_ENABLE
290    {
291      #if QORIQ_UART_1_ENABLE
292        .device_file = "/dev/ttyB1",
293      #else
294        .device_file = "/dev/ttyS1",
295      #endif
296      .probe = BRIDGE_PROBE,
297      .handler = BRIDGE_FNS,
298      .context = BRIDGE_1_CONTEXT
299    }
300  #endif
301};
302
303const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
304
305static void output_char(char c)
306{
307  rtems_termios_device_context *base = console_device_table[0].context;
308
309#ifdef QORIQ_IS_HYPERVISOR_GUEST
310  qoriq_bc_write_polled(base, &c, 1);
311#else
312  ns16550_polled_putchar(base, c);
313#endif
314}
315
316#ifdef QORIQ_IS_HYPERVISOR_GUEST
317static void qoriq_bc_output_char_init(char c)
318{
319  rtems_termios_device_context *base = console_device_table[0].context;
320
321  qoriq_bc_probe(base);
322  output_char(c);
323}
324
325BSP_output_char_function_type BSP_output_char = qoriq_bc_output_char_init;
326#else
327BSP_output_char_function_type BSP_output_char = output_char;
328#endif
329
330BSP_polling_getchar_function_type BSP_poll_char = NULL;
Note: See TracBrowser for help on using the repository browser.