forked from Imagelibrary/rtems
@@ -140,7 +140,9 @@ typedef enum {
|
||||
IMX_FATAL_GENERIC_TIMER_FREQUENCY = BSP_FATAL_CODE_BLOCK(12),
|
||||
|
||||
/* RISC-V fatal codes */
|
||||
RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE = BSP_FATAL_CODE_BLOCK(13)
|
||||
RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE = BSP_FATAL_CODE_BLOCK(13),
|
||||
RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE,
|
||||
RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE
|
||||
} bsp_fatal_code;
|
||||
|
||||
RTEMS_NO_RETURN static inline void
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
#include <rtems/termiostypes.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/fdt.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
#include <dev/serial/htif.h>
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
@@ -29,6 +31,10 @@
|
||||
static htif_console_context htif_console_instance;
|
||||
#endif
|
||||
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
static ns16550_context ns16550_instances[RISCV_CONSOLE_MAX_NS16550_DEVICES];
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
rtems_termios_device_context *context;
|
||||
void (*putchar)(rtems_termios_device_context *base, char c);
|
||||
@@ -55,14 +61,38 @@ static int riscv_get_console_node(const void *fdt)
|
||||
return fdt_path_offset(fdt, stdout_path);
|
||||
}
|
||||
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
static uint8_t get_register(uintptr_t addr, uint8_t i)
|
||||
{
|
||||
volatile uint8_t *reg;
|
||||
|
||||
reg = (uint8_t *) addr;
|
||||
return reg[i];
|
||||
}
|
||||
|
||||
static void set_register(uintptr_t addr, uint8_t i, uint8_t val)
|
||||
{
|
||||
volatile uint8_t *reg;
|
||||
|
||||
reg = (uint8_t *)addr;
|
||||
reg[i] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void riscv_console_probe(void)
|
||||
{
|
||||
const void *fdt;
|
||||
int node;
|
||||
int console_node;
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
size_t ns16550_devices;
|
||||
#endif
|
||||
|
||||
fdt = bsp_fdt_get();
|
||||
console_node = riscv_get_console_node(fdt);
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
ns16550_devices = 0;
|
||||
#endif
|
||||
|
||||
node = fdt_next_node(fdt, -1, NULL);
|
||||
|
||||
@@ -77,6 +107,52 @@ static void riscv_console_probe(void)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
if (fdt_node_check_compatible(fdt, node, "ns16550a") == 0) {
|
||||
if (ns16550_devices < RISCV_CONSOLE_MAX_NS16550_DEVICES) {
|
||||
ns16550_context *ctx;
|
||||
fdt32_t *val;
|
||||
int len;
|
||||
|
||||
ctx = &ns16550_instances[ns16550_devices];
|
||||
ctx->get_reg = get_register;
|
||||
ctx->set_reg = set_register;
|
||||
ctx->initial_baud = BSP_CONSOLE_BAUD;
|
||||
|
||||
val = (fdt32_t *) fdt_getprop(fdt, node, "reg", &len);
|
||||
|
||||
if (val == NULL || (len != 8 && len != 16)) {
|
||||
bsp_fatal(RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE);
|
||||
}
|
||||
|
||||
if (len == 16) {
|
||||
ctx->port = fdt32_to_cpu(val[1]);
|
||||
} else {
|
||||
ctx->port = fdt32_to_cpu(val[0]);
|
||||
}
|
||||
|
||||
val = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
|
||||
|
||||
if (val == NULL || len != 4) {
|
||||
bsp_fatal(RISCV_FATAL_NO_NS16550_CLOCK_FREQUENCY_IN_DEVICE_TREE);
|
||||
}
|
||||
|
||||
ctx->clock = fdt32_to_cpu(val[0]);
|
||||
|
||||
if (node == console_node) {
|
||||
riscv_console.context = &ctx->base;
|
||||
riscv_console.putchar = ns16550_polled_putchar;
|
||||
riscv_console.getchar = ns16550_polled_getchar;
|
||||
}
|
||||
|
||||
rtems_termios_device_context_initialize(&ctx->base, "NS16550");
|
||||
ns16550_probe(&ctx->base);
|
||||
|
||||
++ns16550_devices;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
node = fdt_next_node(fdt, node, NULL);
|
||||
}
|
||||
|
||||
@@ -101,6 +177,10 @@ rtems_status_code console_initialize(
|
||||
{
|
||||
rtems_termios_device_context *base;
|
||||
char htif_path[] = "/dev/ttyShtif";
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
char path[] = "/dev/ttyS?";
|
||||
size_t i;
|
||||
#endif
|
||||
|
||||
rtems_termios_initialize();
|
||||
|
||||
@@ -113,6 +193,26 @@ rtems_status_code console_initialize(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
|
||||
for (i = 0; i < RISCV_CONSOLE_MAX_NS16550_DEVICES; ++i) {
|
||||
ns16550_context *ctx;
|
||||
|
||||
ctx = &ns16550_instances[i];
|
||||
path[sizeof(path) - 2] = (char) ('0' + i);
|
||||
|
||||
rtems_termios_device_install(
|
||||
path,
|
||||
&ns16550_handler_polled,
|
||||
NULL,
|
||||
&ctx->base
|
||||
);
|
||||
|
||||
if (&ctx->base == riscv_console.context) {
|
||||
link(path, CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,15 @@ RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_READ_ONLY],[place the FDT blob into the read-on
|
||||
RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[*],[1])
|
||||
RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_COPY_TO_READ_ONLY_LOAD_AREA],[copy the FDT blob into the read-only load area via bsp_fdt_copy()])
|
||||
|
||||
RTEMS_BSPOPTS_SET([BSP_CONSOLE_BAUD],[*],[115200])
|
||||
RTEMS_BSPOPTS_HELP([BSP_CONSOLE_BAUD],[default baud for console driver devices (default 115200)])
|
||||
|
||||
RTEMS_BSPOPTS_SET([RISCV_ENABLE_HTIF_SUPPORT],[*],[1])
|
||||
RTEMS_BSPOPTS_HELP([RISCV_ENABLE_HTIF_SUPPORT],[enables the HTIF support if defined to a non-zero value, otherwise it is disabled (enabled by default)])
|
||||
|
||||
RTEMS_BSPOPTS_SET([RISCV_CONSOLE_MAX_NS16550_DEVICES],[*],[2])
|
||||
RTEMS_BSPOPTS_HELP([RISCV_CONSOLE_MAX_NS16550_DEVICES],[maximum number of NS16550 devices supported by the console driver (2 by default)])
|
||||
|
||||
RTEMS_BSP_CLEANUP_OPTIONS
|
||||
|
||||
case "${RTEMS_BSP}" in
|
||||
|
||||
Reference in New Issue
Block a user