File indexing completed on 2025-05-11 08:23:49
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
0037 #include <unistd.h>
0038 #include <string.h>
0039 #include <stdio.h>
0040
0041 #include <sys/param.h>
0042 #include <bsp/console-termios.h>
0043 #include <bsp/fatal.h>
0044 #include <bspopts.h>
0045 #include <dev/serial/uartlite.h>
0046
0047 #ifdef BSP_MICROBLAZE_FPGA_USE_FDT
0048 #include <bsp/fdt.h>
0049 #include <libfdt.h>
0050 #endif
0051
0052 #include <rtems/console.h>
0053
0054 #ifndef BSP_MICROBLAZE_FPGA_USE_FDT
0055 static uart_lite_context uart_lite_instances[] = {
0056 {
0057 .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "UARTLITE" ),
0058 .initial_baud = 115200,
0059 .address = BSP_MICROBLAZE_FPGA_UART_BASE,
0060 #if BSP_MICROBLAZE_FPGA_USE_UART
0061 .enabled = 1,
0062 #endif
0063 #ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
0064 .irq = BSP_MICROBLAZE_FPGA_UART_IRQ
0065 #endif
0066 }
0067 };
0068
0069 const console_device console_device_table[] = {
0070 {
0071 .device_file = "/dev/ttyS0",
0072 .handler = µblaze_uart_fns,
0073 .context = &uart_lite_instances[0].base
0074 }
0075 };
0076
0077 const size_t console_device_count = RTEMS_ARRAY_SIZE( console_device_table );
0078 #else
0079 static uart_lite_context uart_lite_instances[BSP_MICROBLAZE_FPGA_MAX_UARTS];
0080 console_device *dynamic_console_device_table;
0081 size_t dynamic_console_device_count;
0082
0083
0084 #define console_device_table dynamic_console_device_table
0085 #define console_device_count dynamic_console_device_count
0086 #endif
0087
0088 #ifdef BSP_MICROBLAZE_FPGA_USE_FDT
0089 static int microblaze_fpga_get_stdout_node(const void *fdt)
0090 {
0091 int node;
0092 int len;
0093 int offset;
0094 const char *console;
0095 const char *q;
0096
0097 node = fdt_path_offset( fdt, "/chosen" );
0098 if ( node < 0 ) {
0099 return 0;
0100 }
0101
0102 console = fdt_getprop( fdt, node, "stdout-path", NULL );
0103 if ( console == NULL ) {
0104 return 0;
0105 }
0106
0107 q = strchr(console, ':');
0108 if ( !q ) {
0109 return 0;
0110 }
0111
0112 len = q - console;
0113
0114
0115 offset = fdt_path_offset_namelen( fdt, console, len );
0116 if (offset < 0) {
0117 return 0;
0118 }
0119
0120 return offset;
0121 }
0122
0123 static void initialize_uart_arrays(uint32_t max_uarts) {
0124 dynamic_console_device_table = calloc(max_uarts, sizeof(console_device));
0125 dynamic_console_device_count = max_uarts;
0126
0127 for (uint32_t i = 0; i < max_uarts; i++) {
0128 rtems_termios_device_context_initialize(&uart_lite_instances[i].base, "UARTLITE");
0129 uart_lite_instances[i].initial_baud = 115200;
0130
0131 dynamic_console_device_table[i].device_file = malloc(11);
0132 snprintf((char *)console_device_table[i].device_file, 11, "/dev/ttyS%u", i);
0133 dynamic_console_device_table[i].handler = µblaze_uart_fns;
0134 dynamic_console_device_table[i].context = &uart_lite_instances[i].base;
0135 }
0136 }
0137 #endif
0138
0139 rtems_device_driver console_initialize(
0140 rtems_device_major_number major,
0141 rtems_device_minor_number minor,
0142 void *arg
0143 )
0144 {
0145 uint32_t port;
0146 uint32_t stdout_port = BSP_MICROBLAZE_FPGA_CONSOLE_UART;
0147
0148 #ifdef BSP_MICROBLAZE_FPGA_USE_FDT
0149 initialize_uart_arrays(BSP_MICROBLAZE_FPGA_MAX_UARTS);
0150
0151 const char compatible[] = "xlnx,xps-uartlite-1.00.a";
0152 const void *fdt = bsp_fdt_get();
0153 int len;
0154 int stdout_node = microblaze_fpga_get_stdout_node(fdt);
0155 int node = fdt_node_offset_by_compatible( fdt, -1, compatible);
0156
0157 while ( node != -FDT_ERR_NOTFOUND ) {
0158 const uint32_t *prop;
0159 const void *status;
0160 uint32_t disabled = 0;
0161 port = console_device_count;
0162
0163
0164 status = fdt_getprop( fdt, node, "status", &len );
0165 if ( status != NULL ) {
0166 if ( strncmp( status, "disabled", MIN( 9, len) ) == 0 ) {
0167 disabled = 1;
0168 }
0169 }
0170
0171 if ( !disabled ) {
0172
0173 prop = fdt_getprop( fdt, node, "port-number", NULL );
0174 if ( prop != NULL ) {
0175 port = fdt32_to_cpu( prop[0] );
0176 }
0177
0178 if ( port < console_device_count ) {
0179 prop = fdt_getprop( fdt, node, "reg", NULL );
0180 if ( prop != NULL ) {
0181 uint32_t address = fdt32_to_cpu( prop[0] );
0182 uart_lite_instances[ port ].address = address;
0183 uart_lite_instances[ port ].enabled = 1;
0184 if ( node == stdout_node ) {
0185 stdout_port = port;
0186 }
0187 }
0188
0189 #ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
0190 prop = fdt_getprop( fdt, node, "interrupts", NULL );
0191 if ( prop != NULL ) {
0192 uint32_t irq = fdt32_to_cpu( prop[0] );
0193 uart_lite_instances[ port ].irq = irq;
0194 }
0195 #endif
0196 }
0197 }
0198
0199 node = fdt_node_offset_by_compatible( fdt, node, compatible );
0200
0201 if ( disabled || ( port >= console_device_count ) )
0202 continue;
0203 }
0204 #endif
0205
0206 rtems_termios_initialize();
0207
0208 for ( port = 0; port < console_device_count; port++ ) {
0209 const console_device *ctx = &console_device_table[ port ];
0210 rtems_status_code sc;
0211
0212 if ( !uart_lite_instances[ port ].enabled )
0213 continue;
0214
0215 sc = rtems_termios_device_install(
0216 ctx->device_file,
0217 ctx->handler,
0218 ctx->flow,
0219 ctx->context
0220 );
0221 if ( sc != RTEMS_SUCCESSFUL ) {
0222 bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_0 );
0223 }
0224
0225 if ( port == stdout_port ) {
0226 if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) {
0227 bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 );
0228 }
0229 }
0230 }
0231
0232 return RTEMS_SUCCESSFUL;
0233 }