source: rtems/c/src/lib/libbsp/powerpc/qoriq/console/console-config.c @ 134fe569

5
Last change on this file since 134fe569 was 134fe569, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/17 at 08:11:32

bsp/qoriq: Add byte channel console driver

Update #3085.

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