summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorPragnesh Patel <pragnesh.patel@sifive.com>2019-10-22 10:20:05 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-10-23 08:11:50 +0200
commita7f5e42cc5234f239a01b8f69847ebb018710948 (patch)
tree75d1abe5128bc54b678580c7d2d03b6823568e70 /bsps
parentlibdebugger/arm: Clean up the building on arm variants. (diff)
downloadrtems-a7f5e42cc5234f239a01b8f69847ebb018710948.tar.bz2
riscv: add freedom E310 Arty A7 bsp
Added support for Sifive Freedom FE310 soc on Arty A7 FPGA board. Update #3785. Signed-off-by: Pragnesh Patel <pragnesh.patel@sifive.com>
Diffstat (limited to 'bsps')
-rw-r--r--bsps/include/bsp/fatal.h3
-rw-r--r--bsps/riscv/riscv/clock/clockdrv.c16
-rw-r--r--bsps/riscv/riscv/config/frdme310arty.cfg9
-rw-r--r--bsps/riscv/riscv/console/console-config.c57
-rw-r--r--bsps/riscv/riscv/console/fe310-uart.c118
-rw-r--r--bsps/riscv/riscv/include/bsp/fe310-uart.h61
-rw-r--r--bsps/riscv/riscv/include/bsp/riscv.h4
-rw-r--r--bsps/riscv/riscv/start/bspstart.c52
8 files changed, 314 insertions, 6 deletions
diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h
index fae5461699..3f8e1eb591 100644
--- a/bsps/include/bsp/fatal.h
+++ b/bsps/include/bsp/fatal.h
@@ -152,7 +152,8 @@ typedef enum {
RISCV_FATAL_INVALID_PLIC_NDEV_IN_DEVICE_TREE,
RISCV_FATAL_TOO_LARGE_PLIC_NDEV_IN_DEVICE_TREE,
RISCV_FATAL_INVALID_INTERRUPT_AFFINITY,
- RISCV_FATAL_NO_NS16550_INTERRUPTS_IN_DEVICE_TREE
+ RISCV_FATAL_NO_NS16550_INTERRUPTS_IN_DEVICE_TREE,
+ RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE
} bsp_fatal_code;
RTEMS_NO_RETURN static inline void
diff --git a/bsps/riscv/riscv/clock/clockdrv.c b/bsps/riscv/riscv/clock/clockdrv.c
index 7e6034d4d1..d085b6bd95 100644
--- a/bsps/riscv/riscv/clock/clockdrv.c
+++ b/bsps/riscv/riscv/clock/clockdrv.c
@@ -130,15 +130,21 @@ static uint32_t riscv_clock_get_timecount(struct timecounter *base)
static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
{
int node;
- const uint32_t *val;
- int len;
+ const fdt32_t *val;
+ int len=0;
node = fdt_path_offset(fdt, "/cpus");
- val = fdt_getprop(fdt, node, "timebase-frequency", &len);
+
+ val = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
+
if (val == NULL || len < 4) {
- bsp_fatal(RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE);
- }
+ int cpu0 = fdt_subnode_offset(fdt, node, "cpu@0");
+ val = (fdt32_t *) fdt_getprop(fdt, cpu0, "timebase-frequency", &len);
+ if (val == NULL || len < 4) {
+ bsp_fatal(RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE);
+ }
+ }
return fdt32_to_cpu(*val);
}
diff --git a/bsps/riscv/riscv/config/frdme310arty.cfg b/bsps/riscv/riscv/config/frdme310arty.cfg
new file mode 100644
index 0000000000..e19e431b53
--- /dev/null
+++ b/bsps/riscv/riscv/config/frdme310arty.cfg
@@ -0,0 +1,9 @@
+include $(RTEMS_ROOT)/make/custom/default.cfg
+
+RTEMS_CPU = riscv
+
+CPU_CFLAGS = -march=rv32imac -mabi=ilp32
+
+LDFLAGS = -Wl,--gc-sections
+
+CFLAGS_OPTIMIZE_V ?= -O2 -g -ffunction-sections -fdata-sections
diff --git a/bsps/riscv/riscv/console/console-config.c b/bsps/riscv/riscv/console/console-config.c
index 464b4b0e26..3cd1d89e08 100644
--- a/bsps/riscv/riscv/console/console-config.c
+++ b/bsps/riscv/riscv/console/console-config.c
@@ -28,6 +28,11 @@
#include <libfdt.h>
#include <string.h>
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+#include <bsp/fe310-uart.h>
+fe310_uart_context driver_context;
+#endif
+
#if RISCV_ENABLE_HTIF_SUPPORT != 0
static htif_console_context htif_console_instance;
#endif
@@ -59,7 +64,18 @@ static int riscv_get_console_node(const void *fdt)
stdout_path = "";
}
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+ int root;
+ int soc;
+ root = fdt_path_offset(fdt, "/");
+ soc = fdt_subnode_offset(fdt, root, "soc");
+
+ int offset=fdt_subnode_offset(fdt, soc,stdout_path);
+
+ return offset;
+#else
return fdt_path_offset(fdt, stdout_path);
+#endif
}
#if RISCV_CONSOLE_MAX_NS16550_DEVICES > 0
@@ -193,6 +209,27 @@ static void riscv_console_probe(void)
}
#endif
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+ if (RISCV_CONSOLE_IS_COMPATIBLE(compat, compat_len, "sifive,uart0")) {
+ fe310_uart_context *ctx ;
+
+ ctx=&driver_context;
+ ctx->regs = (uintptr_t) riscv_fdt_get_address(fdt, node);
+ if (ctx->regs == 0)
+ {
+ bsp_fatal(RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE);
+ }
+
+ if (node == console_node) {
+ riscv_console.context = &ctx->base;
+ riscv_console.putchar = fe310_console_putchar;
+ riscv_console.getchar = fe310_uart_read;
+ }
+
+ rtems_termios_device_context_initialize(&ctx->base, "FE310UART");
+ }
+#endif
+
node = fdt_next_node(fdt, node, NULL);
}
@@ -224,6 +261,10 @@ rtems_status_code console_initialize(
size_t i;
#endif
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+ char path[] = "/dev/ttyS0";
+#endif
+
rtems_termios_initialize();
#if RISCV_ENABLE_HTIF_SUPPORT != 0
@@ -255,6 +296,22 @@ rtems_status_code console_initialize(
}
#endif
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+ fe310_uart_context * ctx = &driver_context;
+
+ rtems_termios_device_install(
+ path,
+ &fe310_uart_handler,
+ NULL,
+ &ctx->base
+ );
+
+ if (&ctx->base == riscv_console.context) {
+ link(path, CONSOLE_DEVICE_NAME);
+ }
+
+#endif
+
return RTEMS_SUCCESSFUL;
}
diff --git a/bsps/riscv/riscv/console/fe310-uart.c b/bsps/riscv/riscv/console/fe310-uart.c
new file mode 100644
index 0000000000..a8e87f452c
--- /dev/null
+++ b/bsps/riscv/riscv/console/fe310-uart.c
@@ -0,0 +1,118 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Pragnesh Patel <pragnesh.patel@sifive.com>
+ * Copyright (c) 2019 Sachin Ghadi <sachin.ghadi@sifive.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bsp/riscv.h>
+#include <bsp/fe310-uart.h>
+
+#include <assert.h>
+
+static void irq_handler(void *arg)
+{
+ /*TODO*/
+}
+
+int fe310_uart_read(rtems_termios_device_context *base)
+{
+ fe310_uart_context * ctx = (fe310_uart_context*) base;
+ size_t i;
+
+ if (((ctx->regs->rxdata) & TXRXREADY) != 0) {
+ return -1;
+ } else {
+ return ctx->regs->rxdata;
+ }
+}
+
+static ssize_t fe310_uart_write (
+ rtems_termios_device_context *base,
+ const char *buf,
+ size_t n
+)
+{
+ fe310_uart_context * ctx = (fe310_uart_context*) base;
+ size_t i;
+
+ rtems_status_code sc;
+
+ (ctx->regs)->div = riscv_get_core_frequency()/ 115200 - 1;
+ (ctx->regs)->txctrl |= 1;
+ (ctx->regs)->rxctrl |= 1;
+
+ for (i = 0; i < n; ++i) {
+ while (((ctx->regs->txdata) & TXRXREADY) != 0) {
+ ;
+ }
+ ctx->regs->txdata = buf[i];
+ }
+ return n;
+}
+
+void fe310_console_putchar(rtems_termios_device_context * context,char c)
+{
+ fe310_uart_write ( context, &c,1);
+}
+
+void console_context_init(
+ rtems_termios_device_context *base,
+ int device_tree_node
+)
+{
+ /*TODO*/
+}
+
+static bool fe310_uart_first_open (
+ rtems_termios_tty *tty,
+ rtems_termios_device_context *base,
+ struct termios *term,
+ rtems_libio_open_close_args_t *args
+)
+{
+ fe310_uart_context * ctx;
+ rtems_status_code sc;
+
+ /* Configure GPIO to be UART */
+
+ sc = rtems_termios_set_initial_baud (tty, B115200);
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ return false;
+ }
+
+ /* Set up a baud rate and enable tx and rx */
+ ctx = (fe310_uart_context *) base;
+ (ctx->regs)->div = riscv_get_core_frequency()/ 115200 - 1;
+ (ctx->regs)->txctrl |= 1;
+ (ctx->regs)->rxctrl |= 1;
+ return true;
+};
+
+const rtems_termios_device_handler fe310_uart_handler = {
+ .first_open = fe310_uart_first_open,
+ .write = fe310_uart_write,
+ .poll_read = fe310_uart_read,
+ .mode = TERMIOS_POLLED
+};
diff --git a/bsps/riscv/riscv/include/bsp/fe310-uart.h b/bsps/riscv/riscv/include/bsp/fe310-uart.h
new file mode 100644
index 0000000000..c6c6fcb876
--- /dev/null
+++ b/bsps/riscv/riscv/include/bsp/fe310-uart.h
@@ -0,0 +1,61 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2019 Pragnesh Patel <pragnesh.patel@sifive.com>
+ * Copyright (c) 2019 Sachin Ghadi <sachin.ghadi@sifive.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FE310_UART_H
+#define FE310_UART_H
+
+#define TXRXREADY (1 << 31)
+
+#include <rtems/termiostypes.h>
+#include <rtems/irq.h>
+
+typedef struct {
+ uint32_t txdata;
+ uint32_t rxdata;
+ uint32_t txctrl;
+ uint32_t rxctrl;
+ uint32_t ie;
+ uint32_t ip;
+ uint32_t div;
+} fe310_uart_t;
+
+/* Low-level driver specific data structure */
+typedef struct {
+ rtems_termios_device_context base;
+ const char *device_name;
+ volatile fe310_uart_t *regs;
+} fe310_uart_context;
+
+int fe310_uart_read(rtems_termios_device_context *base);
+void fe310_console_putchar(rtems_termios_device_context * context,char c);
+
+extern const rtems_termios_device_handler fe310_uart_handler;
+
+extern fe310_uart_context driver_context;
+
+#endif /* FE310_UART_H */
diff --git a/bsps/riscv/riscv/include/bsp/riscv.h b/bsps/riscv/riscv/include/bsp/riscv.h
index 374d5f7a77..f2f1a597ca 100644
--- a/bsps/riscv/riscv/include/bsp/riscv.h
+++ b/bsps/riscv/riscv/include/bsp/riscv.h
@@ -38,6 +38,10 @@ extern volatile RISCV_CLINT_regs *riscv_clint;
void *riscv_fdt_get_address(const void *fdt, int node);
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+uint32_t riscv_get_core_frequency(void);
+#endif
+
#ifdef RTEMS_SMP
extern uint32_t riscv_hart_count;
#else
diff --git a/bsps/riscv/riscv/start/bspstart.c b/bsps/riscv/riscv/start/bspstart.c
index d4c4e1ff7f..a462bbe6e1 100644
--- a/bsps/riscv/riscv/start/bspstart.c
+++ b/bsps/riscv/riscv/start/bspstart.c
@@ -30,6 +30,11 @@
#include <bsp/riscv.h>
#include <libfdt.h>
+#include <string.h>
+
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+unsigned int riscv_core_freq;
+#endif
void *riscv_fdt_get_address(const void *fdt, int node)
{
@@ -161,8 +166,55 @@ uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle)
return UINT32_MAX;
}
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+static uint32_t get_core_frequency(void)
+{
+ uint32_t node;
+ const char *fdt=bsp_fdt_get();
+
+ char *tlclk;
+ uint32_t len;
+
+ do
+ {
+ node=fdt_node_offset_by_compatible(fdt, -1,"fixed-clock");
+ uint32_t *val=NULL;
+ if (node>0)
+ {
+ tlclk = fdt_getprop(fdt, node, "clock-output-names", &len);
+
+ if (strcmp(tlclk,"tlclk") == 0)
+ {
+ val = fdt_getprop(fdt, node, "clock-frequency", &len);
+ if(val !=NULL)
+ {
+ riscv_core_freq=fdt32_to_cpu(*val);
+ break;
+ }
+ }
+ }else
+ {
+ bsp_fatal(RISCV_FATAL_NO_TLCLOCK_FREQUENCY_IN_DEVICE_TREE);
+ }
+
+ } while (node > 0);
+
+ return riscv_core_freq;
+}
+
+inline uint32_t riscv_get_core_frequency(void)
+{
+ return riscv_core_freq;
+}
+#endif
+
void bsp_start(void)
{
riscv_find_harts();
bsp_interrupt_initialize();
+
+#if RISCV_ENABLE_FRDME310ARTY_SUPPORT != 0
+ riscv_core_freq=get_core_frequency();
+#endif
+
}