source: rtems/bsps/riscv/riscv/console/console-config.c @ 7fe4855

5
Last change on this file since 7fe4855 was 7fe4855, checked in by Sebastian Huber <sebastian.huber@…>, on 07/19/18 at 11:58:12

bsp/riscv: Fix HTIF warnings

Update #3433.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <info@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <rtems/bspIo.h>
16#include <rtems/console.h>
17#include <rtems/sysinit.h>
18#include <rtems/termiostypes.h>
19
20#include <bsp.h>
21#include <bsp/fatal.h>
22#include <bsp/fdt.h>
23#include <bsp/irq.h>
24
25#include <dev/serial/htif.h>
26#include <libchip/ns16550.h>
27
28#include <libfdt.h>
29
30#if RISCV_ENABLE_HTIF_SUPPORT != 0
31static htif_console_context htif_console_instance;
32#endif
33
34#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
35static ns16550_context ns16550_instances[RISCV_CONSOLE_MAX_NS16550_DEVICES];
36#endif
37
38static struct {
39  rtems_termios_device_context *context;
40  void (*putchar)(rtems_termios_device_context *base, char c);
41  int (*getchar)(rtems_termios_device_context *base);
42} riscv_console;
43
44static void riscv_output_char(char c)
45{
46  (*riscv_console.putchar)(riscv_console.context, c);
47}
48
49static int riscv_get_console_node(const void *fdt)
50{
51  const char *stdout_path;
52  int node;
53
54  node = fdt_path_offset(fdt, "/chosen");
55
56  stdout_path = fdt_getprop(fdt, node, "stdout-path", NULL);
57  if (stdout_path == NULL) {
58    stdout_path = "";
59  }
60
61  return fdt_path_offset(fdt, stdout_path);
62}
63
64#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
65static uint8_t get_register(uintptr_t addr, uint8_t i)
66{
67  volatile uint8_t *reg;
68
69  reg = (uint8_t *) addr;
70  return reg[i];
71}
72
73static void set_register(uintptr_t addr, uint8_t i, uint8_t val)
74{
75  volatile uint8_t *reg;
76
77  reg = (uint8_t *)addr;
78  reg[i] = val;
79}
80#endif
81
82static void riscv_console_probe(void)
83{
84  const void *fdt;
85  int node;
86  int console_node;
87#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
88  size_t ns16550_devices;
89#endif
90
91  fdt = bsp_fdt_get();
92  console_node = riscv_get_console_node(fdt);
93#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
94  ns16550_devices = 0;
95#endif
96
97  node = fdt_next_node(fdt, -1, NULL);
98
99  while (node >= 0) {
100#if RISCV_ENABLE_HTIF_SUPPORT != 0
101    if (fdt_node_check_compatible(fdt, node, "ucb,htif0") == 0) {
102      htif_console_context_init(&htif_console_instance.base, node);
103
104      riscv_console.context = &htif_console_instance.base;
105      riscv_console.putchar = htif_console_putchar;
106      riscv_console.getchar = htif_console_getchar;
107    };
108#endif
109
110#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
111    if (fdt_node_check_compatible(fdt, node, "ns16550a") == 0) {
112      if (ns16550_devices < RISCV_CONSOLE_MAX_NS16550_DEVICES) {
113        ns16550_context *ctx;
114        fdt32_t *val;
115        int len;
116
117        ctx = &ns16550_instances[ns16550_devices];
118        ctx->get_reg = get_register;
119        ctx->set_reg = set_register;
120        ctx->initial_baud = BSP_CONSOLE_BAUD;
121
122        val = (fdt32_t *) fdt_getprop(fdt, node, "reg", &len);
123
124        if (val == NULL || (len != 8 && len != 16)) {
125          bsp_fatal(RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE);
126        }
127
128        if (len == 16) {
129          ctx->port = fdt32_to_cpu(val[1]);
130        } else {
131          ctx->port = fdt32_to_cpu(val[0]);
132        }
133
134        val = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
135
136        if (val == NULL || len != 4) {
137          bsp_fatal(RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE);
138        }
139
140        ctx->clock = fdt32_to_cpu(val[0]);
141
142        if (node == console_node) {
143          riscv_console.context = &ctx->base;
144          riscv_console.putchar = ns16550_polled_putchar;
145          riscv_console.getchar = ns16550_polled_getchar;
146        }
147
148        rtems_termios_device_context_initialize(&ctx->base, "NS16550");
149        ns16550_probe(&ctx->base);
150
151        ++ns16550_devices;
152      }
153    }
154#endif
155
156    node = fdt_next_node(fdt, node, NULL);
157  }
158
159  BSP_output_char = riscv_output_char;
160}
161
162static void riscv_output_char_init(char c)
163{
164  riscv_console_probe();
165  riscv_output_char(c);
166}
167
168BSP_output_char_function_type BSP_output_char = riscv_output_char_init;
169
170BSP_polling_getchar_function_type BSP_poll_char = NULL;
171
172rtems_status_code console_initialize(
173  rtems_device_major_number major,
174  rtems_device_minor_number minor,
175  void *arg
176)
177{
178#if RISCV_ENABLE_HTIF_SUPPORT != 0
179  rtems_termios_device_context *base;
180  char htif_path[] = "/dev/ttyShtif";
181#endif
182#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
183  char path[] = "/dev/ttyS?";
184  size_t i;
185#endif
186
187  rtems_termios_initialize();
188
189#if RISCV_ENABLE_HTIF_SUPPORT != 0
190  base = &htif_console_instance.base;
191  rtems_termios_device_install(htif_path, &htif_console_handler, NULL, base);
192
193  if (base == riscv_console.context) {
194    link(htif_path, CONSOLE_DEVICE_NAME);
195  }
196#endif
197
198#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
199  for (i = 0; i < RISCV_CONSOLE_MAX_NS16550_DEVICES; ++i) {
200    ns16550_context *ctx;
201
202    ctx = &ns16550_instances[i];
203    path[sizeof(path) - 2] = (char) ('0' + i);
204
205    rtems_termios_device_install(
206      path,
207      &ns16550_handler_polled,
208      NULL,
209      &ctx->base
210    );
211
212    if (&ctx->base == riscv_console.context) {
213      link(path, CONSOLE_DEVICE_NAME);
214    }
215  }
216#endif
217
218  return RTEMS_SUCCESSFUL;
219}
220
221RTEMS_SYSINIT_ITEM(
222  riscv_console_probe,
223  RTEMS_SYSINIT_BSP_START,
224  RTEMS_SYSINIT_ORDER_LAST
225);
Note: See TracBrowser for help on using the repository browser.