File indexing completed on 2025-05-11 08:23:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <string.h>
0037
0038 #include <libfdt.h>
0039
0040 #include <rtems/bspIo.h>
0041
0042 #include <libchip/ns16550.h>
0043
0044 #include <asm/epapr_hcalls.h>
0045
0046 #include <bsp.h>
0047 #include <bsp/fdt.h>
0048 #include <bsp/irq.h>
0049 #include <bsp/qoriq.h>
0050 #include <bsp/intercom.h>
0051 #include <bsp/uart-bridge.h>
0052 #include <bsp/console-termios.h>
0053
0054 static void output_char(char c);
0055
0056 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0057 typedef struct {
0058 rtems_termios_device_context base;
0059 uint32_t handle;
0060 } qoriq_bc_context;
0061
0062 static bool qoriq_bc_probe(rtems_termios_device_context *base)
0063 {
0064 qoriq_bc_context *ctx;
0065 const void *fdt;
0066 int node;
0067 const uint32_t *handle;
0068 int len;
0069
0070 fdt = bsp_fdt_get();
0071
0072 node = fdt_node_offset_by_compatible(fdt, -1, "epapr,hv-byte-channel");
0073 if (node < 0) {
0074 return false;
0075 }
0076
0077 handle = fdt_getprop(fdt, node, "hv-handle", &len);
0078 if (handle == NULL || len != 4) {
0079 return false;
0080 }
0081
0082 ctx = (qoriq_bc_context *) base;
0083 ctx->handle = fdt32_to_cpu(*handle);
0084
0085 BSP_output_char = output_char;
0086 return true;
0087 }
0088
0089 static int qoriq_bc_read_polled(rtems_termios_device_context *base)
0090 {
0091 qoriq_bc_context *ctx;
0092 char buf[EV_BYTE_CHANNEL_MAX_BYTES];
0093 unsigned int count;
0094 unsigned int status;
0095
0096 ctx = (qoriq_bc_context *) base;
0097 count = 1;
0098 status = ev_byte_channel_receive(ctx->handle, &count, buf);
0099
0100 if (status != EV_SUCCESS || count == 0) {
0101 return -1;
0102 }
0103
0104 return (unsigned char) buf[0];
0105 }
0106
0107 static void qoriq_bc_write_polled(
0108 rtems_termios_device_context *base,
0109 const char *buf,
0110 size_t len
0111 )
0112 {
0113 qoriq_bc_context *ctx;
0114 uint32_t handle;
0115
0116 ctx = (qoriq_bc_context *) base;
0117 handle = ctx->handle;
0118
0119 while (len > 0) {
0120 unsigned int count;
0121 unsigned int status;
0122 char buf2[EV_BYTE_CHANNEL_MAX_BYTES];
0123 const char *out;
0124
0125 if (len < EV_BYTE_CHANNEL_MAX_BYTES) {
0126 count = len;
0127 out = memcpy(buf2, buf, len);
0128 } else {
0129 count = EV_BYTE_CHANNEL_MAX_BYTES;
0130 out = buf;
0131 }
0132
0133 status = ev_byte_channel_send(handle, &count, out);
0134
0135 if (status == EV_SUCCESS) {
0136 len -= count;
0137 buf += count;
0138 }
0139 }
0140 }
0141
0142 static const rtems_termios_device_handler qoriq_bc_handler_polled = {
0143 .poll_read = qoriq_bc_read_polled,
0144 .write = qoriq_bc_write_polled,
0145 .mode = TERMIOS_POLLED
0146 };
0147
0148 static qoriq_bc_context qoriq_bc_context_0 = {
0149 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("BC 0"),
0150 };
0151 #endif
0152
0153 #if (QORIQ_UART_0_ENABLE + QORIQ_UART_BRIDGE_0_ENABLE == 2) \
0154 || (QORIQ_UART_1_ENABLE + QORIQ_UART_BRIDGE_1_ENABLE == 2)
0155 #define BRIDGE_MASTER
0156 #elif QORIQ_UART_BRIDGE_0_ENABLE || QORIQ_UART_BRIDGE_1_ENABLE
0157 #define BRIDGE_SLAVE
0158 #endif
0159
0160 #ifdef BSP_USE_UART_INTERRUPTS
0161 #define DEVICE_FNS &ns16550_handler_interrupt
0162 #else
0163 #define DEVICE_FNS &ns16550_handler_polled
0164 #endif
0165
0166 #if QORIQ_UART_0_ENABLE || QORIQ_UART_1_ENABLE
0167 static bool uart_probe(rtems_termios_device_context *base)
0168 {
0169 ns16550_context *ctx = (ns16550_context *) base;
0170
0171 ctx->clock = BSP_bus_frequency;
0172
0173 return ns16550_probe(base);
0174 }
0175
0176 static uint8_t get_register(uintptr_t addr, uint8_t i)
0177 {
0178 volatile uint8_t *reg = (uint8_t *) addr;
0179
0180 return reg [i];
0181 }
0182
0183 static void set_register(uintptr_t addr, uint8_t i, uint8_t val)
0184 {
0185 volatile uint8_t *reg = (uint8_t *) addr;
0186
0187 reg [i] = val;
0188 }
0189 #endif
0190
0191 #if QORIQ_UART_0_ENABLE
0192 static ns16550_context qoriq_uart_context_0 = {
0193 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 0"),
0194 .get_reg = get_register,
0195 .set_reg = set_register,
0196 .port = (uintptr_t) &qoriq.uart_0,
0197 .irq = QORIQ_IRQ_DUART_1,
0198 .initial_baud = BSP_CONSOLE_BAUD
0199 };
0200 #endif
0201
0202 #if QORIQ_UART_1_ENABLE
0203 static ns16550_context qoriq_uart_context_1 = {
0204 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART 1"),
0205 .get_reg = get_register,
0206 .set_reg = set_register,
0207 .port = (uintptr_t) &qoriq.uart_1,
0208 .irq = QORIQ_IRQ_DUART_1,
0209 .initial_baud = BSP_CONSOLE_BAUD
0210 };
0211 #endif
0212
0213 #ifdef BRIDGE_MASTER
0214 #define BRIDGE_PROBE qoriq_uart_bridge_master_probe
0215 #define BRIDGE_FNS &qoriq_uart_bridge_master
0216 #if QORIQ_UART_BRIDGE_0_ENABLE
0217 static uart_bridge_master_context bridge_0_context = {
0218 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
0219 .device_path = "/dev/ttyS0",
0220 .type = INTERCOM_TYPE_UART_0,
0221 .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
0222 bridge_0_context.transmit_fifo
0223 )
0224 };
0225 #define BRIDGE_0_CONTEXT &bridge_0_context.base
0226 #endif
0227 #if QORIQ_UART_BRIDGE_1_ENABLE
0228 static uart_bridge_master_context bridge_1_context = {
0229 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
0230 .device_path = "/dev/ttyS1",
0231 .type = INTERCOM_TYPE_UART_1,
0232 .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
0233 bridge_1_context.transmit_fifo
0234 )
0235 };
0236 #define BRIDGE_1_CONTEXT &bridge_1_context.base
0237 #endif
0238 #endif
0239
0240 #ifdef BRIDGE_SLAVE
0241 #define BRIDGE_PROBE console_device_probe_default
0242 #define BRIDGE_FNS &qoriq_uart_bridge_slave
0243 #if QORIQ_UART_BRIDGE_0_ENABLE
0244 static uart_bridge_slave_context bridge_0_context = {
0245 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 0"),
0246 .type = INTERCOM_TYPE_UART_0,
0247 .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
0248 bridge_0_context.transmit_fifo
0249 )
0250 };
0251 #define BRIDGE_0_CONTEXT &bridge_0_context.base
0252 #endif
0253 #if QORIQ_UART_BRIDGE_1_ENABLE
0254 static uart_bridge_slave_context bridge_1_context = {
0255 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("UART Bridge 1"),
0256 .type = INTERCOM_TYPE_UART_1,
0257 .transmit_fifo = RTEMS_CHAIN_INITIALIZER_EMPTY(
0258 bridge_1_context.transmit_fifo
0259 )
0260 };
0261 #define BRIDGE_1_CONTEXT &bridge_1_context.base
0262 #endif
0263 #endif
0264
0265 const console_device console_device_table[] = {
0266 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0267 {
0268 .device_file = "/dev/ttyBC0",
0269 .probe = qoriq_bc_probe,
0270 .handler = &qoriq_bc_handler_polled,
0271 .context = &qoriq_bc_context_0.base
0272 },
0273 #endif
0274 #if QORIQ_UART_0_ENABLE
0275 {
0276 .device_file = "/dev/ttyS0",
0277 .probe = uart_probe,
0278 .handler = DEVICE_FNS,
0279 .context = &qoriq_uart_context_0.base
0280 },
0281 #endif
0282 #if QORIQ_UART_1_ENABLE
0283 {
0284 .device_file = "/dev/ttyS1",
0285 .probe = uart_probe,
0286 .handler = DEVICE_FNS,
0287 .context = &qoriq_uart_context_1.base
0288 },
0289 #endif
0290 #if QORIQ_UART_BRIDGE_0_ENABLE
0291 {
0292 #if QORIQ_UART_1_ENABLE
0293 .device_file = "/dev/ttyB0",
0294 #else
0295 .device_file = "/dev/ttyS0",
0296 #endif
0297 .probe = BRIDGE_PROBE,
0298 .handler = BRIDGE_FNS,
0299 .context = BRIDGE_0_CONTEXT
0300 },
0301 #endif
0302 #if QORIQ_UART_BRIDGE_1_ENABLE
0303 {
0304 #if QORIQ_UART_1_ENABLE
0305 .device_file = "/dev/ttyB1",
0306 #else
0307 .device_file = "/dev/ttyS1",
0308 #endif
0309 .probe = BRIDGE_PROBE,
0310 .handler = BRIDGE_FNS,
0311 .context = BRIDGE_1_CONTEXT
0312 }
0313 #endif
0314 };
0315
0316 const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
0317
0318 static void output_char(char c)
0319 {
0320 rtems_termios_device_context *base = console_device_table[0].context;
0321
0322 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0323 qoriq_bc_write_polled(base, &c, 1);
0324 #else
0325 ns16550_polled_putchar(base, c);
0326 #endif
0327 }
0328
0329 #ifdef QORIQ_IS_HYPERVISOR_GUEST
0330 static void qoriq_bc_output_char_init(char c)
0331 {
0332 rtems_termios_device_context *base = console_device_table[0].context;
0333
0334 qoriq_bc_probe(base);
0335 output_char(c);
0336 }
0337
0338 BSP_output_char_function_type BSP_output_char = qoriq_bc_output_char_init;
0339 #else
0340 BSP_output_char_function_type BSP_output_char = output_char;
0341 #endif
0342
0343 BSP_polling_getchar_function_type BSP_poll_char = NULL;