From c627a13239d8568a63cb192ed4bc8bb75a746399 Mon Sep 17 00:00:00 2001 From: "Maldonado, Sergio E. (GSFC-580.0)" Date: Mon, 27 Feb 2023 22:44:51 -0600 Subject: bsps/microblaze: Add support for multiple UARTs --- bsps/microblaze/include/dev/serial/uartlite.h | 2 + .../microblaze_fpga/console/console-io.c | 205 ++++++++++++++++++--- bsps/microblaze/shared/dev/serial/uartlite.c | 8 +- spec/build/bsps/microblaze/microblaze_fpga/grp.yml | 10 + spec/build/bsps/microblaze/microblaze_fpga/obj.yml | 1 - .../microblaze/microblaze_fpga/optconsoleuart.yml | 21 +++ .../microblaze/microblaze_fpga/optmaxuarts.yml | 21 +++ .../bsps/microblaze/microblaze_fpga/optuartirq.yml | 20 ++ .../bsps/microblaze/microblaze_fpga/optuseuart.yml | 17 ++ 9 files changed, 275 insertions(+), 30 deletions(-) create mode 100644 spec/build/bsps/microblaze/microblaze_fpga/optconsoleuart.yml create mode 100644 spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml create mode 100644 spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml create mode 100644 spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml diff --git a/bsps/microblaze/include/dev/serial/uartlite.h b/bsps/microblaze/include/dev/serial/uartlite.h index 2fda3796b3..009f416508 100644 --- a/bsps/microblaze/include/dev/serial/uartlite.h +++ b/bsps/microblaze/include/dev/serial/uartlite.h @@ -49,8 +49,10 @@ typedef struct { rtems_termios_device_context base; uintptr_t address; uint32_t initial_baud; + uint32_t enabled; #ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS bool transmitting; + uint32_t irq; #endif } uart_lite_context; diff --git a/bsps/microblaze/microblaze_fpga/console/console-io.c b/bsps/microblaze/microblaze_fpga/console/console-io.c index 81c4e73690..a07c85642f 100644 --- a/bsps/microblaze/microblaze_fpga/console/console-io.c +++ b/bsps/microblaze/microblaze_fpga/console/console-io.c @@ -34,39 +34,200 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include -uart_lite_context microblaze_qemu_uart_context = { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "UARTLITE" ), - .initial_baud = 115200 -}; - -static bool fill_uart_base(rtems_termios_device_context *context) -{ - uint32_t mblaze_uart_base; - - mblaze_uart_base = try_get_prop_from_device_tree( - "xlnx,xps-uartlite-1.00.a", - "reg", - BSP_MICROBLAZE_FPGA_UART_BASE - ); +#ifdef BSP_MICROBLAZE_FPGA_USE_FDT +#include +#include +#endif - microblaze_qemu_uart_context.address = mblaze_uart_base; +#include - return true; -} +#ifndef BSP_MICROBLAZE_FPGA_USE_FDT +static uart_lite_context uart_lite_instances[] = { + { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "UARTLITE" ), + .initial_baud = 115200, + .address = BSP_MICROBLAZE_FPGA_UART_BASE, +#if BSP_MICROBLAZE_FPGA_USE_UART + .enabled = 1, +#endif +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + .irq = BSP_MICROBLAZE_FPGA_UART_IRQ +#endif + } +}; const console_device console_device_table[] = { { .device_file = "/dev/ttyS0", - .probe = fill_uart_base, .handler = µblaze_uart_fns, - .context = µblaze_qemu_uart_context.base + .context = &uart_lite_instances[0].base } }; const size_t console_device_count = RTEMS_ARRAY_SIZE( console_device_table ); +#else +static uart_lite_context uart_lite_instances[BSP_MICROBLAZE_FPGA_MAX_UARTS]; +console_device *dynamic_console_device_table; +size_t dynamic_console_device_count; + +/* Override the console_device_table and console_device_count */ +#define console_device_table dynamic_console_device_table +#define console_device_count dynamic_console_device_count +#endif /* BSP_MICROBLAZE_FPGA_USE_FDT */ + +#ifdef BSP_MICROBLAZE_FPGA_USE_FDT +static int microblaze_fpga_get_stdout_node(const void *fdt) +{ + int node; + int len; + int offset; + const char *console; + const char *q; + + node = fdt_path_offset( fdt, "/chosen" ); + if ( node < 0 ) { + return 0; + } + + console = fdt_getprop( fdt, node, "stdout-path", NULL ); + if ( console == NULL ) { + return 0; + } + + q = strchr(console, ':'); + if ( !q ) { + return 0; + } + + len = q - console; + + /* Get the node specified by stdout-path */ + offset = fdt_path_offset_namelen( fdt, console, len ); + if (offset < 0) { + return 0; + } + + return offset; +} + +static void initialize_uart_arrays(uint32_t max_uarts) { + dynamic_console_device_table = calloc(max_uarts, sizeof(console_device)); + dynamic_console_device_count = max_uarts; + + for (uint32_t i = 0; i < max_uarts; i++) { + rtems_termios_device_context_initialize(&uart_lite_instances[i].base, "UARTLITE"); + uart_lite_instances[i].initial_baud = 115200; + + dynamic_console_device_table[i].device_file = malloc(11); + snprintf((char *)console_device_table[i].device_file, 11, "/dev/ttyS%u", i); + dynamic_console_device_table[i].handler = µblaze_uart_fns; + dynamic_console_device_table[i].context = &uart_lite_instances[i].base; + } +} +#endif + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + uint32_t port; + uint32_t stdout_port = BSP_MICROBLAZE_FPGA_CONSOLE_UART; + +#ifdef BSP_MICROBLAZE_FPGA_USE_FDT + initialize_uart_arrays(BSP_MICROBLAZE_FPGA_MAX_UARTS); + + const char compatible[] = "xlnx,xps-uartlite-1.00.a"; + const void *fdt = bsp_fdt_get(); + int len; + int stdout_node = microblaze_fpga_get_stdout_node(fdt); + int node = fdt_node_offset_by_compatible( fdt, -1, compatible); + + while ( node != -FDT_ERR_NOTFOUND ) { + const uint32_t *prop; + const void *status; + uint32_t disabled = 0; + port = console_device_count; + + /* check if node device status has been set to disabled */ + status = fdt_getprop( fdt, node, "status", &len ); + if ( status != NULL ) { + if ( strncmp( status, "disabled", MIN( 9, len) ) == 0 ) { + disabled = 1; + } + } + + if ( !disabled ) { + /* use port number property as the device table index */ + prop = fdt_getprop( fdt, node, "port-number", NULL ); + if ( prop != NULL ) { + port = fdt32_to_cpu( prop[0] ); + } + + if ( port < console_device_count ) { + prop = fdt_getprop( fdt, node, "reg", NULL ); + if ( prop != NULL ) { + uint32_t address = fdt32_to_cpu( prop[0] ); + uart_lite_instances[ port ].address = address; + uart_lite_instances[ port ].enabled = 1; + if ( node == stdout_node ) { + stdout_port = port; + } + } + +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + prop = fdt_getprop( fdt, node, "interrupts", NULL ); + if ( prop != NULL ) { + uint32_t irq = fdt32_to_cpu( prop[0] ); + uart_lite_instances[ port ].irq = irq; + } +#endif + } + } + + node = fdt_node_offset_by_compatible( fdt, node, compatible ); + + if ( disabled || ( port >= console_device_count ) ) + continue; + } +#endif /* BSP_MICROBLAZE_FPGA_USE_FDT */ + + rtems_termios_initialize(); + + for ( port = 0; port < console_device_count; port++ ) { + const console_device *ctx = &console_device_table[ port ]; + rtems_status_code sc; + + if ( !uart_lite_instances[ port ].enabled ) + continue; + + sc = rtems_termios_device_install( + ctx->device_file, + ctx->handler, + ctx->flow, + ctx->context + ); + if ( sc != RTEMS_SUCCESSFUL ) { + bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_0 ); + } + + if ( port == stdout_port ) { + if ( link( ctx->device_file, CONSOLE_DEVICE_NAME ) != 0 ) { + bsp_fatal( BSP_FATAL_CONSOLE_INSTALL_1 ); + } + } + } + + return RTEMS_SUCCESSFUL; +} diff --git a/bsps/microblaze/shared/dev/serial/uartlite.c b/bsps/microblaze/shared/dev/serial/uartlite.c index 953c630759..e2007ee24a 100644 --- a/bsps/microblaze/shared/dev/serial/uartlite.c +++ b/bsps/microblaze/shared/dev/serial/uartlite.c @@ -71,14 +71,8 @@ static bool uart_first_open( #ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS XUartLite_EnableIntr( ctx->address ); - uint32_t uart_irq_num = try_get_prop_from_device_tree( - "xlnx,xps-uartlite-1.00.a", - "interrupts", - 1 - ); - sc = rtems_interrupt_handler_install( - uart_irq_num, + ctx->irq, "UART", RTEMS_INTERRUPT_SHARED, microblaze_uart_interrupt, diff --git a/spec/build/bsps/microblaze/microblaze_fpga/grp.yml b/spec/build/bsps/microblaze/microblaze_fpga/grp.yml index aa88821458..4f854de2cd 100644 --- a/spec/build/bsps/microblaze/microblaze_fpga/grp.yml +++ b/spec/build/bsps/microblaze/microblaze_fpga/grp.yml @@ -54,6 +54,8 @@ links: uid: opticachesize - role: build-dependency uid: optintcbaseaddress +- role: build-dependency + uid: optmaxuarts - role: build-dependency uid: optramlen - role: build-dependency @@ -66,6 +68,14 @@ links: uid: opttimerfrequency - role: build-dependency uid: optuartlitebaseaddress +- role: build-dependency + uid: optuseuart +- role: build-dependency + uid: optuartirq +- role: build-dependency + uid: optuartirq +- role: build-dependency + uid: optconsoleuart - role: build-dependency uid: optusefdt - role: build-dependency diff --git a/spec/build/bsps/microblaze/microblaze_fpga/obj.yml b/spec/build/bsps/microblaze/microblaze_fpga/obj.yml index 67afbb7c7e..52ba596768 100644 --- a/spec/build/bsps/microblaze/microblaze_fpga/obj.yml +++ b/spec/build/bsps/microblaze/microblaze_fpga/obj.yml @@ -47,7 +47,6 @@ source: - bsps/shared/dev/cpucounter/cpucounterfrequency.c - bsps/shared/dev/cpucounter/cpucounterread.c - bsps/shared/dev/getentropy/getentropy-cpucounter.c -- bsps/shared/dev/serial/console-termios-init.c - bsps/shared/dev/serial/console-termios.c - bsps/shared/irq/irq-default-handler.c - bsps/shared/start/bspfatal-default.c diff --git a/spec/build/bsps/microblaze/microblaze_fpga/optconsoleuart.yml b/spec/build/bsps/microblaze/microblaze_fpga/optconsoleuart.yml new file mode 100644 index 0000000000..8cc8e18062 --- /dev/null +++ b/spec/build/bsps/microblaze/microblaze_fpga/optconsoleuart.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +actions: +- get-integer: null +- assert-uint32: null +- env-assign: null +- format-and-define: null +build-type: option +copyrights: +- Copyright (C) 2023 On-Line Applications Research Corporation (OAR) +default: +- enabled-by: true + value: 0 +default-by-variant: [] +description: | + default uart console device port number +enabled-by: true +format: '{}' +links: [] +name: BSP_MICROBLAZE_FPGA_CONSOLE_UART +type: build diff --git a/spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml b/spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml new file mode 100644 index 0000000000..3b639a5922 --- /dev/null +++ b/spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +actions: +- get-integer: null +- assert-uint32: null +- env-assign: null +- format-and-define: null +build-type: option +copyrights: +- Copyright (C) 2023 On-Line Applications Research Corporation (OAR) +default: +- enabled-by: true + value: 1 +default-by-variant: [] +description: | + maximum number of UART devices +enabled-by: true +format: '{}' +links: [] +name: BSP_MICROBLAZE_FPGA_MAX_UARTS +type: build diff --git a/spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml b/spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml new file mode 100644 index 0000000000..054388bf8a --- /dev/null +++ b/spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml @@ -0,0 +1,20 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-integer: null +- assert-uint32: null +- env-assign: null +- format-and-define: null +build-type: option +copyrights: +- Copyright (C) 2023 On-Line Applications Research Corporation (OAR) +default: +- enabled-by: true + value: 3 +default-by-variant: [] +description: | + irq number of the AXI UART Lite +enabled-by: true +format: '{:#010x}' +links: [] +name: BSP_MICROBLAZE_FPGA_UART_IRQ +type: build diff --git a/spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml b/spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml new file mode 100644 index 0000000000..c3ddd11b78 --- /dev/null +++ b/spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-boolean: null +- define-condition: null +build-type: option +copyrights: +- Copyright (C) 2023 On-Line Applications Research Corporation (OAR) +default: +- enabled-by: true + value: true +default-by-variant: [] +description: | + define if UART is used +enabled-by: true +links: [] +name: BSP_MICROBLAZE_FPGA_USE_UART +type: build -- cgit v1.2.3