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;
|
rtems_termios_device_context base;
|
||||||
uintptr_t address;
|
uintptr_t address;
|
||||||
uint32_t initial_baud;
|
uint32_t initial_baud;
|
||||||
|
uint32_t enabled;
|
||||||
#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
|
#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
|
||||||
bool transmitting;
|
bool transmitting;
|
||||||
|
uint32_t irq;
|
||||||
#endif
|
#endif
|
||||||
} uart_lite_context;
|
} uart_lite_context;
|
||||||
|
|
||||||
|
|||||||
@@ -34,39 +34,200 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
#include <bsp/console-termios.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 <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 = {
|
#include <rtems/console.h>
|
||||||
.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "UARTLITE" ),
|
|
||||||
.initial_baud = 115200
|
#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[] = {
|
const console_device console_device_table[] = {
|
||||||
{
|
{
|
||||||
.device_file = "/dev/ttyS0",
|
.device_file = "/dev/ttyS0",
|
||||||
.probe = fill_uart_base,
|
|
||||||
.handler = µblaze_uart_fns,
|
.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 );
|
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
|
#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
|
||||||
XUartLite_EnableIntr( ctx->address );
|
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(
|
sc = rtems_interrupt_handler_install(
|
||||||
uart_irq_num,
|
ctx->irq,
|
||||||
"UART",
|
"UART",
|
||||||
RTEMS_INTERRUPT_SHARED,
|
RTEMS_INTERRUPT_SHARED,
|
||||||
microblaze_uart_interrupt,
|
microblaze_uart_interrupt,
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ links:
|
|||||||
uid: opticachesize
|
uid: opticachesize
|
||||||
- role: build-dependency
|
- role: build-dependency
|
||||||
uid: optintcbaseaddress
|
uid: optintcbaseaddress
|
||||||
|
- role: build-dependency
|
||||||
|
uid: optmaxuarts
|
||||||
- role: build-dependency
|
- role: build-dependency
|
||||||
uid: optramlen
|
uid: optramlen
|
||||||
- role: build-dependency
|
- role: build-dependency
|
||||||
@@ -66,6 +68,14 @@ links:
|
|||||||
uid: opttimerfrequency
|
uid: opttimerfrequency
|
||||||
- role: build-dependency
|
- role: build-dependency
|
||||||
uid: optuartlitebaseaddress
|
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
|
- role: build-dependency
|
||||||
uid: optusefdt
|
uid: optusefdt
|
||||||
- role: build-dependency
|
- role: build-dependency
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ source:
|
|||||||
- bsps/shared/dev/cpucounter/cpucounterfrequency.c
|
- bsps/shared/dev/cpucounter/cpucounterfrequency.c
|
||||||
- bsps/shared/dev/cpucounter/cpucounterread.c
|
- bsps/shared/dev/cpucounter/cpucounterread.c
|
||||||
- bsps/shared/dev/getentropy/getentropy-cpucounter.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/dev/serial/console-termios.c
|
||||||
- bsps/shared/irq/irq-default-handler.c
|
- bsps/shared/irq/irq-default-handler.c
|
||||||
- bsps/shared/start/bspfatal-default.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