mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
bsps/microblaze: Add support for multiple UARTs
This commit is contained in:
committed by
Joel Sherrill
parent
1fbfc4eeac
commit
c627a13239
@@ -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;
|
||||
|
||||
|
||||
@@ -34,39 +34,200 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <bsp/console-termios.h>
|
||||
#include <bsp/microblaze-fdt-support.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bspopts.h>
|
||||
#include <dev/serial/uartlite.h>
|
||||
|
||||
#include <bspopts.h>
|
||||
#ifdef BSP_MICROBLAZE_FPGA_USE_FDT
|
||||
#include <bsp/fdt.h>
|
||||
#include <libfdt.h>
|
||||
#endif
|
||||
|
||||
uart_lite_context microblaze_qemu_uart_context = {
|
||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "UARTLITE" ),
|
||||
.initial_baud = 115200
|
||||
#include <rtems/console.h>
|
||||
|
||||
#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
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
microblaze_qemu_uart_context.address = mblaze_uart_base;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
21
spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml
Normal file
21
spec/build/bsps/microblaze/microblaze_fpga/optmaxuarts.yml
Normal file
@@ -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
|
||||
20
spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml
Normal file
20
spec/build/bsps/microblaze/microblaze_fpga/optuartirq.yml
Normal file
@@ -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
|
||||
17
spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml
Normal file
17
spec/build/bsps/microblaze/microblaze_fpga/optuseuart.yml
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user