[PATCH] riscv: add freedom E310 Arty A7 bsp

Pragnesh Patel pragnesh.patel at sifive.com
Tue Aug 27 12:45:13 UTC 2019


Update #3785.

Signed-off-by: Pragnesh Patel <pragnesh.patel at sifive.com>
---
 bsps/include/bsp/fatal.h                           |   6 +-
 bsps/riscv/frdme310arty/btimer/btimer.c            | 108 ++++++
 bsps/riscv/frdme310arty/clock/clockdrv.c           | 266 +++++++++++++++
 bsps/riscv/frdme310arty/config/frdme310arty.cfg    |  11 +
 bsps/riscv/frdme310arty/console/console-config.c   | 146 ++++++++
 bsps/riscv/frdme310arty/console/uart.c             | 100 ++++++
 bsps/riscv/frdme310arty/dts/frdme310arty.dts       | 130 +++++++
 .../frdme310arty/dts/frdme310arty_dtb_array.c      | 259 ++++++++++++++
 bsps/riscv/frdme310arty/headers.am                 |  15 +
 bsps/riscv/frdme310arty/include/bsp.h              |  57 ++++
 bsps/riscv/frdme310arty/include/bsp/fe310_uart.h   |  42 +++
 bsps/riscv/frdme310arty/include/bsp/irq.h          |  73 ++++
 bsps/riscv/frdme310arty/include/bsp/riscv.h        |  60 ++++
 bsps/riscv/frdme310arty/include/tm27.h             | 334 ++++++++++++++++++
 bsps/riscv/frdme310arty/start/bsp_fatal_halt.c     |  53 +++
 bsps/riscv/frdme310arty/start/bsp_specs            |   9 +
 bsps/riscv/frdme310arty/start/bspstart.c           | 240 +++++++++++++
 bsps/riscv/frdme310arty/start/linkcmds.in          |  49 +++
 bsps/riscv/frdme310arty/start/start.S              | 147 ++++++++
 bsps/riscv/shared/irq/irq.c                        | 379 +++++++++++++++++++++
 c/src/lib/libbsp/riscv/acinclude.m4                |   2 +
 c/src/lib/libbsp/riscv/frdme310arty/Makefile.am    |  75 ++++
 c/src/lib/libbsp/riscv/frdme310arty/configure.ac   |  68 ++++
 23 files changed, 2628 insertions(+), 1 deletion(-)
 create mode 100644 bsps/riscv/frdme310arty/btimer/btimer.c
 create mode 100644 bsps/riscv/frdme310arty/clock/clockdrv.c
 create mode 100644 bsps/riscv/frdme310arty/config/frdme310arty.cfg
 create mode 100644 bsps/riscv/frdme310arty/console/console-config.c
 create mode 100644 bsps/riscv/frdme310arty/console/uart.c
 create mode 100644 bsps/riscv/frdme310arty/dts/frdme310arty.dts
 create mode 100644 bsps/riscv/frdme310arty/dts/frdme310arty_dtb_array.c
 create mode 100644 bsps/riscv/frdme310arty/headers.am
 create mode 100644 bsps/riscv/frdme310arty/include/bsp.h
 create mode 100644 bsps/riscv/frdme310arty/include/bsp/fe310_uart.h
 create mode 100644 bsps/riscv/frdme310arty/include/bsp/irq.h
 create mode 100644 bsps/riscv/frdme310arty/include/bsp/riscv.h
 create mode 100644 bsps/riscv/frdme310arty/include/tm27.h
 create mode 100644 bsps/riscv/frdme310arty/start/bsp_fatal_halt.c
 create mode 100644 bsps/riscv/frdme310arty/start/bsp_specs
 create mode 100644 bsps/riscv/frdme310arty/start/bspstart.c
 create mode 100644 bsps/riscv/frdme310arty/start/linkcmds.in
 create mode 100644 bsps/riscv/frdme310arty/start/start.S
 create mode 100644 bsps/riscv/shared/irq/irq.c
 create mode 100644 c/src/lib/libbsp/riscv/frdme310arty/Makefile.am
 create mode 100644 c/src/lib/libbsp/riscv/frdme310arty/configure.ac

diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h
index fae5461..5193943 100644
--- a/bsps/include/bsp/fatal.h
+++ b/bsps/include/bsp/fatal.h
@@ -152,7 +152,11 @@ 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,
+  /*SIFIVE FRDM310 codes*/
+  FRDM310_RISCV_FATAL_NO_NODE_IN_DEVICE_TREE,
+  FRDM310_RISCV_FATAL_NO_L2C_REG_IN_DEVICE_TREE,
+  FRDM310_RISCV_FATAL_TM27_IRQ_INSTALL
 } bsp_fatal_code;
 
 RTEMS_NO_RETURN static inline void
diff --git a/bsps/riscv/frdme310arty/btimer/btimer.c b/bsps/riscv/frdme310arty/btimer/btimer.c
new file mode 100644
index 0000000..4904725
--- /dev/null
+++ b/bsps/riscv/frdme310arty/btimer/btimer.c
@@ -0,0 +1,108 @@
+/**
+ * @file
+ * @brief Freedom E310 Timer driver
+ *
+ */
+
+/*
+ *  Copyright (c) 2019 by Sachin Ghadi <sachin.ghadi at sifive.com>
+ *  Copyright (c) 2019 by Pragnesh Patel <pragnesh.patel at sifive.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/btimer.h>
+#include <bsp/riscv.h>
+
+bool benchmark_timer_find_average_overhead;
+
+#define CONFIG_BTIMER_RISCV_GET_MCYCLES
+
+#ifdef CONFIG_BTIMER_RISCV_GET_MCYCLES
+uint64_t	Begin_Time;
+uint64_t	End_Time;
+#else
+long      	Begin_Time;
+long       	End_Time;
+
+#endif
+
+#define read_csr(reg) ({ unsigned long __tmp; \
+		asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+		__tmp; })
+
+
+static unsigned long get_cpu_freq()
+{
+	return riscv_get_core_frequency();
+}
+
+static unsigned long get_timer_freq()
+{
+	return get_cpu_freq();
+}
+
+static uint64_t get_timer_value()
+{
+#if __riscv_xlen == 32
+	while (1) {
+		uint32_t hi = read_csr(mcycleh);
+		uint32_t lo = read_csr(mcycle);
+		if (hi == read_csr(mcycleh))
+			return ((uint64_t)hi << 32) | lo;
+	}
+#else
+	return read_csr(mcycle);
+#endif
+}
+
+/*Returns time in microseconds*/
+static long time(void)
+{
+	return (get_timer_value()*1000000) / get_timer_freq();
+}
+
+static void benchmark_timer1_interrupt_handler(void)
+{
+/* TODO */
+}
+
+/* Start eCore tiemr 1 usef for profiling and timing analysis */
+void benchmark_timer_initialize( void )
+{
+	/* Install interrupt handler for timer 1 */
+#ifdef CONFIG_BTIMER_RISCV_GET_MCYCLES
+	Begin_Time = get_timer_value();
+#else
+	Begin_Time =time();
+#endif
+}
+
+/* This value is in microseconds. */
+#define LEAST_VALID       1  /* Don't trust a clicks value lower than this */
+
+benchmark_timer_t benchmark_timer_read( void )
+{
+	uint32_t total;
+#ifdef CONFIG_BTIMER_RISCV_GET_MCYCLES
+	End_Time = get_timer_value();
+	total = (uint32_t)(End_Time - Begin_Time);
+#else
+	End_Time=time();
+	total = (End_Time - Begin_Time);
+#endif
+
+	return total;
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(
+		bool find_flag
+)
+{
+	benchmark_timer_find_average_overhead = find_flag;
+}
diff --git a/bsps/riscv/frdme310arty/clock/clockdrv.c b/bsps/riscv/frdme310arty/clock/clockdrv.c
new file mode 100644
index 0000000..e65b8a2
--- /dev/null
+++ b/bsps/riscv/frdme310arty/clock/clockdrv.c
@@ -0,0 +1,266 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_clock
+ *
+ * @brief riscv clock support.
+ */
+
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ * COPYRIGHT (c) 2015 Hesham Alatary <hesham at alumni.york.ac.uk>
+ *
+ * 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 AUTHOR 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 AUTHOR 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/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq.h>
+#include <bsp/riscv.h>
+
+#include <rtems/sysinit.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/cpuimpl.h>
+#include <rtems/score/riscv-utility.h>
+
+#include <libfdt.h>
+
+extern volatile RISCV_CLINT_regs *riscv_clint;
+
+/* This is defined in dev/clock/clockimpl.h */
+void Clock_isr(void *arg);
+
+typedef struct {
+  struct timecounter base;
+  volatile RISCV_CLINT_regs *clint;
+  uint32_t interval;
+} riscv_timecounter;
+
+static riscv_timecounter riscv_clock_tc;
+
+static rtems_timecounter_simple riscv_simple_tc;
+
+static void riscv_clock_write_mtimecmp(
+  volatile RISCV_CLINT_timer_reg *mtimecmp,
+  uint64_t value
+)
+{
+#if __riscv_xlen == 32
+  mtimecmp->val_32[0] = 0xffffffff;
+  mtimecmp->val_32[1] = (uint32_t) (value >> 32);
+  mtimecmp->val_32[0] = (uint32_t) value;
+#elif __riscv_xlen == 64
+  mtimecmp->val_64 = value;
+#endif
+}
+
+static uint64_t riscv_clock_read_mtime(volatile RISCV_CLINT_timer_reg *mtime)
+{
+#if __riscv_xlen == 32
+  uint32_t low;
+  uint32_t high_0;
+  uint32_t high_1;
+
+  do {
+    high_0 = mtime->val_32[1];
+    low = mtime->val_32[0];
+    high_1 = mtime->val_32[1];
+  } while (high_0 != high_1);
+
+  return (((uint64_t) high_0) << 32) | low;
+#elif __riscv_xlen == 64
+  return mtime->val_64;
+#endif
+}
+
+static void riscv_clock_at_tick(riscv_timecounter *tc)
+{
+  volatile RISCV_CLINT_regs *clint;
+  uint64_t value;
+
+  clint = tc->clint;
+
+  value = clint->mtimecmp[0].val_64;
+  value += tc->interval;
+
+  riscv_clock_write_mtimecmp(&clint->mtimecmp[0], value);
+}
+
+
+static void riscv_clock_handler_install(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_interrupt_handler_install(
+    RISCV_INTERRUPT_VECTOR_TIMER,
+    "Clock",
+    RTEMS_INTERRUPT_UNIQUE,
+    (rtems_interrupt_handler) Clock_isr,
+    NULL
+  );
+  if (sc != RTEMS_SUCCESSFUL) {
+    bsp_fatal(RISCV_FATAL_CLOCK_IRQ_INSTALL);
+  }
+}
+
+static uint32_t riscv_clock_get_timecount(struct timecounter *base)
+{
+	return riscv_clint->mtime.val_32[0];
+}
+
+CPU_Counter_ticks _CPU_Counter_read( void )
+{
+  return riscv_clock_get_timecount(NULL);
+}
+
+static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
+{
+  int node;
+  fdt32_t *val;
+  int len=0;
+
+  node = fdt_path_offset(fdt, "/cpus");
+
+  int cpu0 = fdt_subnode_offset(fdt, node, "cpu at 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);
+}
+
+static bool riscv_tc_is_pending(rtems_timecounter_simple *tc)
+{
+  return (((read_csr(mip) >>IRQ_M_TIMER)&1) != 0);
+}
+
+static uint32_t riscv_tc_get_timecount_simple(struct timecounter *tc)
+{
+
+ return rtems_timecounter_simple_upcounter_get(
+    tc,
+	riscv_clock_get_timecount,
+	riscv_tc_is_pending
+  );
+
+}
+
+static void riscv_tc_tick()
+{
+  return rtems_timecounter_simple_upcounter_get(
+	&riscv_simple_tc,
+	riscv_clock_get_timecount,
+	riscv_tc_is_pending
+  );
+}
+
+static void riscv_clock_initialize(void)
+{
+  const char *fdt;
+  riscv_timecounter *tc;
+  volatile RISCV_CLINT_regs *clint;
+  uint32_t tb_freq;
+  uint64_t us_per_tick;
+  uint32_t interval;
+
+
+  fdt = bsp_fdt_get();
+  tb_freq = riscv_clock_get_timebase_frequency(fdt);
+  us_per_tick = rtems_configuration_get_microseconds_per_tick();
+  interval = (uint32_t) ((tb_freq * us_per_tick) / 1000000);
+
+
+  if(!riscv_clint)
+  {
+	  fdt = bsp_fdt_get();
+	  int node=fdt_node_offset_by_compatible(fdt, -1, "riscv,clint0");
+	  riscv_clint=riscv_fdt_get_address(fdt, node);
+	  if (riscv_clint == NULL)
+	  {
+		  bsp_fatal(RISCV_FATAL_NO_CLINT_REG_IN_DEVICE_TREE);
+	  }
+  }
+  clint = riscv_clint;
+  tc = &riscv_clock_tc;
+
+  tc->clint = clint;
+  tc->interval = interval;
+
+  riscv_clock_write_mtimecmp(
+    &clint->mtimecmp[0],
+    riscv_clock_read_mtime(&clint->mtime) + interval
+  );
+
+
+
+  /* Initialize timecounter */
+  tc->base.tc_get_timecount = riscv_clock_get_timecount;
+  tc->base.tc_counter_mask = 0xffffffff;
+  tc->base.tc_frequency = tb_freq;
+  tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+  rtems_timecounter_install(&tc->base);
+
+  rtems_counter_initialize_converter(tb_freq);
+
+   rtems_timecounter_simple_install(
+      &riscv_simple_tc,
+	  tb_freq,
+	  interval,
+	  riscv_tc_get_timecount_simple
+    );
+
+   /* Enable mtimer interrupts */
+     set_csr(mie, MIP_MTIP);
+}
+
+volatile uint32_t _RISCV_Counter_register;
+
+static void riscv_counter_initialize(void)
+{
+  _RISCV_Counter_mutable = &riscv_clint->mtime.val_32[0];
+}
+
+uint32_t _CPU_Counter_frequency( void )
+{
+  return riscv_clock_get_timebase_frequency(bsp_fdt_get());
+}
+
+RTEMS_SYSINIT_ITEM(
+  riscv_counter_initialize,
+  RTEMS_SYSINIT_CPU_COUNTER,
+  RTEMS_SYSINIT_ORDER_FIRST
+);
+
+
+
+//#define Clock_driver_timecounter_tick() riscv_tc_tick()
+
+#define Clock_driver_support_at_tick() riscv_clock_at_tick(&riscv_clock_tc)
+
+#define Clock_driver_support_initialize_hardware() riscv_clock_initialize()
+
+#define Clock_driver_support_install_isr(isr) riscv_clock_handler_install()
+
+
+#include "../../../shared/dev/clock/clockimpl.h"
diff --git a/bsps/riscv/frdme310arty/config/frdme310arty.cfg b/bsps/riscv/frdme310arty/config/frdme310arty.cfg
new file mode 100644
index 0000000..91688f8
--- /dev/null
+++ b/bsps/riscv/frdme310arty/config/frdme310arty.cfg
@@ -0,0 +1,11 @@
+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/frdme310arty/console/console-config.c b/bsps/riscv/frdme310arty/console/console-config.c
new file mode 100644
index 0000000..88261ca
--- /dev/null
+++ b/bsps/riscv/frdme310arty/console/console-config.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <info at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems/bspIo.h>
+#include <rtems/console.h>
+#include <rtems/sysinit.h>
+#include <rtems/termiostypes.h>
+
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq.h>
+#include <bsp/riscv.h>
+#include <bsp/fe310_uart.h>
+
+#include <libfdt.h>
+#include <string.h>
+
+
+fe310_uart_context driver_context = {
+		.base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER("FE310_UART0"),
+		.device_name = "/dev/console",
+		.regs = NULL,
+};
+
+static struct {
+	rtems_termios_device_context *context;
+	void (*putchar)(rtems_termios_device_context *base, char c);
+	int (*getchar)(rtems_termios_device_context *base);
+} riscv_console;
+
+static void fe310_output_char(char c)
+{
+	(*riscv_console.putchar)(riscv_console.context, c);
+}
+
+static int riscv_get_console_node(const void *fdt)
+{
+	const char *stdout_path;
+	int node;
+
+	node = fdt_path_offset(fdt, "/chosen");
+
+	stdout_path = fdt_getprop(fdt, node, "stdout-path", NULL);
+	if (stdout_path == NULL) {
+		stdout_path = "";
+		return -1;
+	}
+
+	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;
+}
+
+static void fe310_console_probe(void)
+{
+	const void *fdt;
+	int node;
+	int console_node;
+
+	fdt = bsp_fdt_get();
+	console_node = riscv_get_console_node(fdt);
+
+	const char *compat;
+	int compat_len;
+
+	compat = fdt_getprop(fdt, console_node, "compatible", &compat_len);
+	if (compat == NULL)
+	{
+		compat_len = 0;
+	}
+
+	fe310_uart_context *ctx ;
+	ctx=&driver_context;
+	ctx->regs = (uintptr_t) riscv_fdt_get_address(fdt, console_node);
+	if (ctx->regs == 0)
+	{
+		bsp_fatal(RISCV_FATAL_NO_NS16550_REG_IN_DEVICE_TREE);
+	}
+
+	rtems_termios_device_context_initialize(&ctx->base, "FE310UART");
+
+	riscv_console.context=&driver_context;
+	riscv_console.putchar=fe310_console_putchar;
+	riscv_console.getchar=fe310_uart_read;
+
+	BSP_output_char = fe310_output_char;
+}
+
+static void riscv_output_char_init(char c)
+{
+	fe310_console_probe();
+	fe310_output_char(c);
+}
+
+BSP_output_char_function_type BSP_output_char = riscv_output_char_init;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+rtems_status_code console_initialize(
+		rtems_device_major_number major,
+		rtems_device_minor_number minor,
+		void *arg
+)
+{
+
+	rtems_status_code sc;
+	const rtems_termios_device_handler *handler = &fe310_uart_handler;
+
+	rtems_termios_initialize();
+	fe310_uart_context * ctx = &driver_context;
+
+	sc=rtems_termios_device_install(
+			ctx->device_name,
+			handler,
+			NULL,
+			&ctx->base
+	);
+
+	if ( sc != RTEMS_SUCCESSFUL ) {
+		bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV);
+	}
+
+	return RTEMS_SUCCESSFUL;
+
+}
+
+RTEMS_SYSINIT_ITEM(
+		fe310_console_probe,
+		RTEMS_SYSINIT_BSP_START,
+		RTEMS_SYSINIT_ORDER_LAST
+);
diff --git a/bsps/riscv/frdme310arty/console/uart.c b/bsps/riscv/frdme310arty/console/uart.c
new file mode 100644
index 0000000..05b9975
--- /dev/null
+++ b/bsps/riscv/frdme310arty/console/uart.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019 Sachin Ghadi <sachin.ghadi at sifive.com>
+ * Copyright (c) 2019 Pragnesh Patel <pragnesh.patel at sifive.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+
+#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/frdme310arty/dts/frdme310arty.dts b/bsps/riscv/frdme310arty/dts/frdme310arty.dts
new file mode 100644
index 0000000..a7a216d
--- /dev/null
+++ b/bsps/riscv/frdme310arty/dts/frdme310arty.dts
@@ -0,0 +1,130 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "SiFive,FE310G-dev", "fe310-dev", "sifive-dev";
+	model = "SiFive,FE310G";
+	L20: chosen {
+		stdout-path = "serial at 20000000";
+	};
+	L17: cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		L6: cpu at 0 {
+			clocks = <&refclk>;
+			compatible = "sifive,rocket0", "riscv";
+			device_type = "cpu";
+			i-cache-block-size = <64>;
+			i-cache-sets = <128>;
+			i-cache-size = <16384>;
+			next-level-cache = <&L12>;
+			reg = <0>;
+			riscv,isa = "rv32imac";
+			sifive,dtim = <&L5>;
+			sifive,itim = <&L4>;
+			status = "okay";
+			timebase-frequency = <1000000>;
+			L3: interrupt-controller {
+				#interrupt-cells = <1>;
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+			};
+		};
+	};
+	L16: soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "SiFive,FE310G-soc", "fe310-soc", "sifive-soc", "simple-bus";
+		ranges;
+    L19: tlclk {
+			#clock-cells = <0>;
+			clock-frequency = <32500000>;
+			clock-output-names = "tlclk";
+			compatible = "fixed-clock";
+		};
+		refclk: refclk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <66666666>;
+			clock-output-names = "refclk";
+		};
+		L1: clint at 2000000 {
+			compatible = "riscv,clint0";
+			interrupts-extended = <&L3 3 &L3 7>;
+			reg = <0x2000000 0x10000>;
+			reg-names = "control";
+		};
+		L2: debug-controller at 0 {
+			compatible = "sifive,debug-013", "riscv,debug-013";
+			interrupts-extended = <&L3 65535>;
+			reg = <0x0 0x1000>;
+			reg-names = "control";
+		};
+		L5: dtim at 80000000 {
+			compatible = "sifive,dtim0";
+			reg = <0x80000000 0x10000>;
+			reg-names = "mem";
+		};
+		L8: error-device at 3000 {
+			compatible = "sifive,error0";
+			reg = <0x3000 0x1000>;
+			reg-names = "mem";
+		};
+		L9: global-external-interrupts {
+			interrupt-parent = <&L0>;
+			interrupts = <1 2 3 4>;
+		};
+		L13: gpio at 20002000 {
+			compatible = "sifive,gpio0";
+			interrupt-parent = <&L0>;
+			interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>;
+			reg = <0x20002000 0x1000>;
+			reg-names = "control";
+		};
+		L0: interrupt-controller at c000000 {
+			#interrupt-cells = <1>;
+			compatible = "riscv,plic0";
+			interrupt-controller;
+			interrupts-extended = <&L3 11>;
+			reg = <0xc000000 0x4000000>;
+			reg-names = "control";
+			riscv,max-priority = <7>;
+			riscv,ndev = <26>;
+		};
+		L4: itim at 8000000 {
+			compatible = "sifive,itim0";
+			reg = <0x8000000 0x4000>;
+			reg-names = "mem";
+		};
+		L10: local-external-interrupts-0 {
+			interrupt-parent = <&L3>;
+			interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
+		};
+		L14: pwm at 20005000 {
+			compatible = "sifive,pwm0";
+			interrupt-parent = <&L0>;
+			interrupts = <23 24 25 26>;
+			reg = <0x20005000 0x1000>;
+			reg-names = "control";
+		};
+		L11: serial at 20000000 {
+			compatible = "sifive,uart0";
+			interrupt-parent = <&L0>;
+			interrupts = <5>;
+			reg = <0x20000000 0x1000>;
+			reg-names = "control";
+		};
+		L12: spi at 20004000 {
+			compatible = "sifive,spi0";
+			interrupt-parent = <&L0>;
+			interrupts = <6>;
+			reg = <0x20004000 0x1000 0x40000000 0x20000000>;
+			reg-names = "control", "mem";
+		};
+		L7: teststatus at 4000 {
+			compatible = "sifive,test0";
+			reg = <0x4000 0x1000>;
+		};
+	};
+};
diff --git a/bsps/riscv/frdme310arty/dts/frdme310arty_dtb_array.c b/bsps/riscv/frdme310arty/dts/frdme310arty_dtb_array.c
new file mode 100644
index 0000000..b2a0fe8
--- /dev/null
+++ b/bsps/riscv/frdme310arty/dts/frdme310arty_dtb_array.c
@@ -0,0 +1,259 @@
+unsigned char frdme310arty_dtb[] = {
+  0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x38,
+  0x00, 0x00, 0x0a, 0x74, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8c,
+  0x00, 0x00, 0x0a, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x1b,
+  0x53, 0x69, 0x46, 0x69, 0x76, 0x65, 0x2c, 0x46, 0x45, 0x33, 0x31, 0x30,
+  0x47, 0x2d, 0x64, 0x65, 0x76, 0x00, 0x66, 0x65, 0x33, 0x31, 0x30, 0x2d,
+  0x64, 0x65, 0x76, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2d, 0x64,
+  0x65, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0x00, 0x26, 0x53, 0x69, 0x46, 0x69, 0x76, 0x65, 0x2c, 0x46,
+  0x45, 0x33, 0x31, 0x30, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+  0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x73, 0x65, 0x72, 0x69,
+  0x61, 0x6c, 0x40, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x73,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x40, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x38,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15,
+  0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x72,
+  0x6f, 0x63, 0x6b, 0x65, 0x74, 0x30, 0x00, 0x72, 0x69, 0x73, 0x63, 0x76,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x3f, 0x63, 0x70, 0x75, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x5e,
+  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x89,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09,
+  0x00, 0x00, 0x00, 0x8d, 0x72, 0x76, 0x33, 0x32, 0x69, 0x6d, 0x61, 0x63,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xaf,
+  0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x0f, 0x42, 0x40,
+  0x00, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70,
+  0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63,
+  0x76, 0x2c, 0x63, 0x70, 0x75, 0x2d, 0x69, 0x6e, 0x74, 0x63, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xef,
+  0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+  0x73, 0x6f, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x1b,
+  0x53, 0x69, 0x46, 0x69, 0x76, 0x65, 0x2c, 0x46, 0x45, 0x33, 0x31, 0x30,
+  0x47, 0x2d, 0x73, 0x6f, 0x63, 0x00, 0x66, 0x65, 0x33, 0x31, 0x30, 0x2d,
+  0x73, 0x6f, 0x63, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2d, 0x73,
+  0x6f, 0x63, 0x00, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62, 0x75,
+  0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x01, 0x74, 0x6c, 0x63, 0x6c,
+  0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x11, 0x01, 0xef, 0xe9, 0x20,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21,
+  0x74, 0x6c, 0x63, 0x6c, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x66, 0x69, 0x78, 0x65,
+  0x64, 0x2d, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x01, 0x72, 0x65, 0x66, 0x63, 0x6c, 0x6b, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x04,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0x00, 0x00, 0x1b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x2d, 0x63, 0x6c,
+  0x6f, 0x63, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x01, 0x11, 0x03, 0xf9, 0x40, 0xaa, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x21, 0x72, 0x65, 0x66, 0x63,
+  0x6c, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x63, 0x6c, 0x69, 0x6e,
+  0x74, 0x40, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1b,
+  0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x63, 0x6c, 0x69, 0x6e, 0x74, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x01, 0x48, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x64, 0x65, 0x62, 0x75,
+  0x67, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
+  0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x21,
+  0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x64,
+  0x65, 0x62, 0x75, 0x67, 0x2d, 0x30, 0x31, 0x33, 0x00, 0x72, 0x69, 0x73,
+  0x63, 0x76, 0x2c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2d, 0x30, 0x31, 0x33,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0xff, 0xff,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x48, 0x63, 0x6f, 0x6e, 0x74,
+  0x72, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+  0x64, 0x74, 0x69, 0x6d, 0x40, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d,
+  0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x64,
+  0x74, 0x69, 0x6d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89, 0x80, 0x00, 0x00, 0x00,
+  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x01, 0x48, 0x6d, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf5,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
+  0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
+  0x40, 0x33, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
+  0x76, 0x65, 0x2c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x30, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89,
+  0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x48, 0x6d, 0x65, 0x6d, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x67, 0x6c, 0x6f, 0x62,
+  0x61, 0x6c, 0x2d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d,
+  0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x73, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52,
+  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x01, 0x67, 0x70, 0x69, 0x6f, 0x40, 0x32, 0x30, 0x30,
+  0x30, 0x32, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
+  0x76, 0x65, 0x2c, 0x67, 0x70, 0x69, 0x6f, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52,
+  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e,
+  0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11,
+  0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14,
+  0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x20, 0x00,
+  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x01, 0x48, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x69, 0x6e, 0x74, 0x65,
+  0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
+  0x6c, 0x6c, 0x65, 0x72, 0x40, 0x63, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63,
+  0x76, 0x2c, 0x70, 0x6c, 0x69, 0x63, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x05,
+  0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x89, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x48,
+  0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x07,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x81,
+  0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x06,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x69, 0x74, 0x69, 0x6d,
+  0x40, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1b,
+  0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x69, 0x74, 0x69, 0x6d, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x89, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x48,
+  0x6d, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x6c, 0x6f, 0x63, 0x61,
+  0x6c, 0x2d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d, 0x69,
+  0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x73, 0x2d, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52,
+  0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40,
+  0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11,
+  0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14,
+  0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,
+  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a,
+  0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d,
+  0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x01, 0x70, 0x77, 0x6d, 0x40, 0x32, 0x30, 0x30, 0x30,
+  0x35, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
+  0x76, 0x65, 0x2c, 0x70, 0x77, 0x6d, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52, 0x00, 0x00, 0x00, 0x06,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x63,
+  0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19,
+  0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x48,
+  0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x01, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40, 0x32,
+  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
+  0x76, 0x65, 0x2c, 0x75, 0x61, 0x72, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52,
+  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
+  0x00, 0x00, 0x01, 0x48, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x73, 0x70, 0x69, 0x40,
+  0x32, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1b,
+  0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x73, 0x70, 0x69, 0x30, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x52,
+  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x40, 0x00,
+  0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x48,
+  0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00, 0x6d, 0x65, 0x6d, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xef,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
+  0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x01, 0x74, 0x65, 0x73, 0x74, 0x73, 0x74, 0x61, 0x74,
+  0x75, 0x73, 0x40, 0x34, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
+  0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
+  0x76, 0x65, 0x2c, 0x74, 0x65, 0x73, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x89,
+  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09,
+  0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2d, 0x63, 0x65, 0x6c,
+  0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x63, 0x65, 0x6c,
+  0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c,
+  0x65, 0x00, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x73, 0x74, 0x64, 0x6f,
+  0x75, 0x74, 0x2d, 0x70, 0x61, 0x74, 0x68, 0x00, 0x63, 0x6c, 0x6f, 0x63,
+  0x6b, 0x73, 0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x79,
+  0x70, 0x65, 0x00, 0x69, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x62,
+  0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x69, 0x2d,
+  0x63, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x73, 0x65, 0x74, 0x73, 0x00, 0x69,
+  0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x00,
+  0x6e, 0x65, 0x78, 0x74, 0x2d, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x2d, 0x63,
+  0x61, 0x63, 0x68, 0x65, 0x00, 0x72, 0x65, 0x67, 0x00, 0x72, 0x69, 0x73,
+  0x63, 0x76, 0x2c, 0x69, 0x73, 0x61, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76,
+  0x65, 0x2c, 0x64, 0x74, 0x69, 0x6d, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76,
+  0x65, 0x2c, 0x69, 0x74, 0x69, 0x6d, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75,
+  0x73, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x61, 0x73, 0x65, 0x2d, 0x66,
+  0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x00, 0x23, 0x69, 0x6e,
+  0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x65, 0x6c, 0x6c,
+  0x73, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d,
+  0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00, 0x6c,
+  0x69, 0x6e, 0x75, 0x78, 0x2c, 0x70, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65,
+  0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x23, 0x63, 0x6c, 0x6f,
+  0x63, 0x6b, 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x63, 0x6c, 0x6f,
+  0x63, 0x6b, 0x2d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+  0x00, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75,
+  0x74, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x00, 0x69, 0x6e, 0x74, 0x65,
+  0x72, 0x72, 0x75, 0x70, 0x74, 0x73, 0x2d, 0x65, 0x78, 0x74, 0x65, 0x6e,
+  0x64, 0x65, 0x64, 0x00, 0x72, 0x65, 0x67, 0x2d, 0x6e, 0x61, 0x6d, 0x65,
+  0x73, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d,
+  0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72,
+  0x72, 0x75, 0x70, 0x74, 0x73, 0x00, 0x72, 0x69, 0x73, 0x63, 0x76, 0x2c,
+  0x6d, 0x61, 0x78, 0x2d, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
+  0x00, 0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x6e, 0x64, 0x65, 0x76, 0x00
+};
+unsigned int frdme310arty_dtb_len = 3072;
diff --git a/bsps/riscv/frdme310arty/headers.am b/bsps/riscv/frdme310arty/headers.am
new file mode 100644
index 0000000..aa32a2f
--- /dev/null
+++ b/bsps/riscv/frdme310arty/headers.am
@@ -0,0 +1,15 @@
+## This file was generated by "./boostrap -H".
+
+include_HEADERS =
+include_HEADERS += ../../../../../../bsps/riscv/frdme310arty/include/bsp.h
+include_HEADERS += include/bspopts.h
+include_HEADERS += ../../../../../../bsps/riscv/frdme310arty/include/tm27.h
+
+include_bspdir = $(includedir)/bsp
+include_bsp_HEADERS =
+include_bsp_HEADERS += ../../../../../../bsps/riscv/frdme310arty/include/bsp/irq.h
+include_bsp_HEADERS += ../../../../../../bsps/riscv/frdme310arty/include/bsp/riscv.h
+
+include_dev_serialdir = $(includedir)/dev/serial
+include_dev_serial_HEADERS =
+#include_dev_serial_HEADERS += ../../../../../../bsps/riscv/frdme310arty/include/dev/serial/htif.h
diff --git a/bsps/riscv/frdme310arty/include/bsp.h b/bsps/riscv/frdme310arty/include/bsp.h
new file mode 100644
index 0000000..3cd8981
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/bsp.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham at alumni.york.ac.uk>
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 AUTHOR 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 AUTHOR 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 LIBBSP_RISCV_GENERIC_H
+#define LIBBSP_RISCV_GENERIC_H
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/console.h>
+
+#include <bspopts.h>
+#include <bsp/default-initial-extension.h>
+
+#include <rtems/devnull.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BSP_FEATURE_IRQ_EXTENSION
+
+#if BSP_START_COPY_FDT_FROM_U_BOOT
+#define BSP_FDT_IS_SUPPORTED
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBBSP_RISCV_GENERIC_H */
diff --git a/bsps/riscv/frdme310arty/include/bsp/fe310_uart.h b/bsps/riscv/frdme310arty/include/bsp/fe310_uart.h
new file mode 100644
index 0000000..065e12a
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/bsp/fe310_uart.h
@@ -0,0 +1,42 @@
+ /*
+  * Copyright (c) 2019 Sachin Ghadi <sachin.ghadi at sifive.com>
+  * Copyright (c) 2019 Pragnesh Patel <pragnesh.patel at sifive.com>
+  *
+  * The license and distribution terms for this file may be
+  * found in the file LICENSE in this distribution or at
+  * http://www.rtems.org/license/LICENSE.
+  */
+
+#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/frdme310arty/include/bsp/irq.h b/bsps/riscv/frdme310arty/include/bsp/irq.h
new file mode 100644
index 0000000..cf88443
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/bsp/irq.h
@@ -0,0 +1,73 @@
+/**
+ * @file
+ *
+ * @ingroup RISCV_IRQ
+ *
+ * @brief Interrupt definitions.
+ */
+
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham at alumni.york.ac.uk>
+ *
+ * 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 AUTHOR 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 AUTHOR 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 LIBBSP_GENERIC_RISCV_IRQ_H
+#define LIBBSP_GENERIC_RISCV_IRQ_H
+
+#ifndef ASM
+
+#include <bsp.h>
+#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
+#include <rtems/score/processormask.h>
+
+#define RISCV_INTERRUPT_VECTOR_SOFTWARE 0
+
+#define RISCV_INTERRUPT_VECTOR_TIMER 1
+
+#define RISCV_INTERRUPT_VECTOR_EXTERNAL(x) ((x) + 2)
+
+#define RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(x) ((x) >= 2)
+
+#define RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(x) ((x) - 2)
+
+#define BSP_INTERRUPT_VECTOR_MIN 0
+
+#define BSP_INTERRUPT_VECTOR_MAX RISCV_INTERRUPT_VECTOR_EXTERNAL(RISCV_MAXIMUM_EXTERNAL_INTERRUPTS - 1)
+
+void bsp_interrupt_set_affinity(
+  rtems_vector_number vector,
+  const Processor_mask *affinity
+);
+
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
+);
+
+#endif /* ASM */
+
+#endif /* LIBBSP_GENERIC_RISCV_IRQ_H */
diff --git a/bsps/riscv/frdme310arty/include/bsp/riscv.h b/bsps/riscv/frdme310arty/include/bsp/riscv.h
new file mode 100644
index 0000000..05a0b74
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/bsp/riscv.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * 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 AUTHOR 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 AUTHOR 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 BSP_RISCV_H
+#define BSP_RISCV_H
+
+#include <bsp.h>
+
+#include <rtems/score/cpuimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern volatile RISCV_CLINT_regs *riscv_clint;
+extern uint32_t frdme310arty_l2c_base;
+extern unsigned int riscv_core_freq;
+
+void *riscv_fdt_get_address(const void *fdt, int node);
+uint32_t riscv_get_core_frequency(void);
+
+#ifdef RTEMS_SMP
+extern uint32_t riscv_hart_count;
+#else
+#define riscv_hart_count 1
+#endif
+
+uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle);
+
+#if RISCV_ENABLE_HTIF_SUPPORT != 0
+void htif_poweroff(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_RISCV_H */
diff --git a/bsps/riscv/frdme310arty/include/tm27.h b/bsps/riscv/frdme310arty/include/tm27.h
new file mode 100644
index 0000000..d42fecb
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/tm27.h
@@ -0,0 +1,334 @@
+#include <bsp/irq.h>
+#include <rtems/score/riscv-utility.h>
+#include <libfdt.h>
+#include <bsp/riscv.h>
+#include <bsp/fatal.h>
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+uint32_t is_lower=0;
+#define GPIO_IRQ
+
+
+
+#ifdef GPIO_IRQ
+#define PLIC_CTRL_ADDR  0x0C000000
+// 32 bits per source
+#define PLIC_PRIORITY_OFFSET            0x0000
+#define PLIC_PRIORITY_SHIFT_PER_SOURCE  2
+// 1 bit per source (1 address)
+#define PLIC_PENDING_OFFSET             0x1000
+#define PLIC_PENDING_SHIFT_PER_SOURCE   0
+
+//0x80 per target
+#define PLIC_ENABLE_OFFSET              0x2000
+#define PLIC_ENABLE_SHIFT_PER_TARGET    7
+
+
+#define PLIC_THRESHOLD_OFFSET           0x200000
+
+#define PLIC_CLAIM_OFFSET               0x200004
+#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
+#define PLIC_CLAIM_SHIFT_PER_TARGET     12
+
+#define PLIC_MAX_SOURCE                 1023
+#define PLIC_SOURCE_MASK                0x3FF
+
+#define PLIC_MAX_TARGET                 15871
+#define PLIC_TARGET_MASK                0x3FFF
+
+
+#define GPIO_CTRL_ADDR 	0x10070000
+
+#define GPIO_INPUT_VAL  (0x00)
+#define GPIO_INPUT_EN   (0x04)
+#define GPIO_OUTPUT_EN  (0x08)
+#define GPIO_OUTPUT_VAL (0x0C)
+#define GPIO_PULLUP_EN  (0x10)
+#define GPIO_DRIVE      (0x14)
+#define GPIO_RISE_IE    (0x18)
+#define GPIO_RISE_IP    (0x1C)
+#define GPIO_FALL_IE    (0x20)
+#define GPIO_FALL_IP    (0x24)
+#define GPIO_HIGH_IE    (0x28)
+#define GPIO_HIGH_IP    (0x2C)
+#define GPIO_LOW_IE     (0x30)
+#define GPIO_LOW_IP     (0x34)
+#define GPIO_IOF_EN     (0x38)
+#define GPIO_IOF_SEL    (0x3C)
+#define GPIO_OUTPUT_XOR (0x40)
+
+// Helper functions
+#define _REG32(p, i) 		(*(volatile uint32_t *) ((p) + (i)))
+#define _REG32P(p, i) 		((volatile uint32_t *) ((p) + (i)))
+#define GPIO_REG(offset) 	_REG32(GPIO_CTRL_ADDR, offset)
+#define PIN_0_OFFSET 0
+
+#define PLIC_NUM_INTERRUPTS 1
+#define PLIC_NUM_PRIORITIES 7
+
+typedef struct __plic_instance_t
+{
+  uintptr_t base_addr;
+  uint32_t num_sources;
+  uint32_t num_priorities;
+} plic_instance_t;
+
+plic_instance_t g_plic;
+typedef uint32_t plic_source;
+typedef uint32_t plic_priority;
+typedef uint32_t plic_threshold;
+
+#define PMOD_JB_IO_1  8
+
+void volatile_memzero(uint8_t * base, unsigned int size)
+{
+  volatile uint8_t * ptr;
+  for (ptr = base; ptr < (base + size); ptr++){
+    *ptr = 0;
+  }
+}
+
+void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){
+
+  unsigned long hart_id = read_csr(mhartid);
+  volatile uint8_t * current_ptr = (volatile uint8_t *)(this_plic->base_addr +
+                                                        PLIC_ENABLE_OFFSET +
+                                                        (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
+                                                        (source >> 3));
+  uint8_t current = *current_ptr;
+  current = current | ( 1 << (source & 0x7));
+  *current_ptr = current;
+
+}
+
+void PLIC_disable_interrupt (plic_instance_t * this_plic, plic_source source){
+
+  unsigned long hart_id = read_csr(mhartid);
+  volatile uint8_t * current_ptr = (volatile uint8_t *) (this_plic->base_addr +
+                                                         PLIC_ENABLE_OFFSET +
+                                                         (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
+                                                         (source >> 3));
+  uint8_t current = *current_ptr;
+  current = current & ~(( 1 << (source & 0x7)));
+  *current_ptr = current;
+
+}
+
+void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_priority priority){
+
+  if (this_plic->num_priorities > 0) {
+    volatile plic_priority * priority_ptr = (volatile plic_priority *)
+      (this_plic->base_addr +
+       PLIC_PRIORITY_OFFSET +
+       (source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
+    *priority_ptr = priority;
+  }
+}
+
+plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){
+
+  unsigned long hart_id = read_csr(mhartid);
+
+  volatile plic_source * claim_addr = (volatile plic_source * )
+    (this_plic->base_addr +
+     PLIC_CLAIM_OFFSET +
+     (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
+
+  return  *claim_addr;
+
+}
+
+void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){
+
+  unsigned long hart_id = read_csr(mhartid);
+  volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr +
+                                                                PLIC_CLAIM_OFFSET +
+                                                                (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
+  *claim_addr = source;
+
+}
+
+void PLIC_init (
+                plic_instance_t * this_plic,
+                uintptr_t         base_addr,
+                uint32_t num_sources,
+                uint32_t num_priorities
+                )
+{
+
+  this_plic->base_addr = base_addr;
+  this_plic->num_sources = num_sources;
+  this_plic->num_priorities = num_priorities;
+
+  // Disable all interrupts (don't assume that these registers are reset).
+  unsigned long hart_id = read_csr(mhartid);
+
+  volatile_memzero((uint8_t*) (this_plic->base_addr +
+                               PLIC_ENABLE_OFFSET +
+                               (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)),
+							   (num_sources + 8) / 8);
+
+  // Set all priorities to 0 (equal priority -- don't assume that these are reset).
+  volatile_memzero ((uint8_t *)(this_plic->base_addr +
+                                PLIC_PRIORITY_OFFSET),
+								(num_sources + 1) << PLIC_PRIORITY_SHIFT_PER_SOURCE);
+
+  // Set the threshold to 0.
+  volatile plic_threshold* threshold = (plic_threshold*)
+    (this_plic->base_addr +
+     PLIC_THRESHOLD_OFFSET +
+     (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
+
+  *threshold = 0;
+
+}
+#else
+#define CLINT_CTRL_ADDR 	0x02000000
+#define CLINT_MSIP 			0x0000
+#define CLINT_MSIP_size   	0x4
+#define CLINT_MTIMECMP 		0x4000
+#define CLINT_MTIMECMP_size 0x8
+#define CLINT_MTIME 		0xBFF8
+#define CLINT_MTIME_size 	0x8
+#define RTC_FREQ 			1000
+
+static void set_timer() {
+  static uint64_t then = 0;
+
+  volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
+  volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+/*  if(then != 0)  {
+    //next timer irq is 1 second from previous
+    then += 1*RTC_FREQ;
+  } else{ //first time setting the timer
+    uint64_t now = *mtime;
+    then = now + 1*RTC_FREQ;
+ } */
+	uint64_t now = *mtime;
+    then = now + 1*RTC_FREQ;
+    *mtimecmp = then;
+
+  set_csr(mie, MIP_MTIP);
+}
+
+#endif
+
+static void Install_tm27_vector(void (*handler)(rtems_vector_number))
+{
+	//Register a SW Interrupt and set the MSIP bit the mie CSR in Install_tm27_vector().
+	//
+	rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+	sc = rtems_interrupt_handler_install(
+			RISCV_INTERRUPT_VECTOR_SOFTWARE,
+			"SW",
+			RTEMS_INTERRUPT_SHARED,
+			(rtems_interrupt_handler) handler,
+			NULL
+	);
+
+#ifdef GPIO_IRQ
+	sc = rtems_interrupt_handler_install(
+				RISCV_INTERRUPT_VECTOR_EXTERNAL(8),
+				"GPIO",
+				RTEMS_INTERRUPT_SHARED,
+				(rtems_interrupt_handler) handler,
+				NULL
+		);
+#else
+	sc = rtems_interrupt_handler_install(
+					RISCV_INTERRUPT_VECTOR_TIMER,
+					"TIMER",
+					RTEMS_INTERRUPT_SHARED,
+					(rtems_interrupt_handler) handler,
+					NULL
+			);
+#endif
+
+    if (sc != RTEMS_SUCCESSFUL) {
+      bsp_fatal(FRDM310_RISCV_FATAL_TM27_IRQ_INSTALL);
+  }
+
+
+}
+
+static void Cause_tm27_intr(void)
+{
+
+	if(is_lower)
+	{
+
+#ifdef GPIO_IRQ
+		/*Generate high priority GPIO external interrupt*/
+		GPIO_REG(GPIO_LOW_IE) 		|=  ((0x1<< PIN_0_OFFSET));
+		PLIC_enable_interrupt (&g_plic, PMOD_JB_IO_1);
+		PLIC_set_priority(&g_plic, PMOD_JB_IO_1, 7);
+		set_csr(mie, MIP_MEIP);
+		set_csr(mstatus, MSTATUS_MIE);
+#else
+		set_csr(mie, MIP_MSIP);
+		volatile uint32_t *msip = (volatile uint32_t *)(&((_Per_CPU_Get())->cpu_per_cpu.clint_msip[0]));
+		*msip = 1;
+
+#endif
+
+	}else
+	{
+#ifdef GPIO_IRQ
+		set_csr(mie, MIP_MSIP);
+		volatile uint32_t *msip = (volatile uint32_t *)(&((_Per_CPU_Get())->cpu_per_cpu.clint_msip[0]));
+		*msip = 1;
+#else
+		//Generate software interrupt
+		set_timer();
+#endif
+	}
+
+}
+
+static void Clear_tm27_intr(void)
+{
+
+	if(is_lower)
+	{
+#ifdef GPIO_IRQ
+
+		plic_source int_num  = PLIC_claim_interrupt(&g_plic);
+		PLIC_complete_interrupt(&g_plic, int_num);
+		GPIO_REG(GPIO_LOW_IE) 	&=  ~((0x1<< PIN_0_OFFSET));
+#endif
+
+	}
+	else
+	{
+#ifdef GPIO_IRQ
+		volatile uint32_t *msip = (volatile uint32_t *)(&((_Per_CPU_Get())->cpu_per_cpu.clint_msip[0]));
+		*msip = 0;
+		clear_csr(mie, MIP_MSIP);
+#else
+		clear_csr(mie, MIP_MTIP);
+#endif
+	}
+
+}
+
+static void Lower_tm27_intr(void)
+{
+#ifdef GPIO_IRQ
+	/*Enable high priority GPIO external interrupt*/
+	GPIO_REG(GPIO_IOF_EN )    	&=  ~(1 <<  PIN_0_OFFSET);
+	GPIO_REG(GPIO_OUTPUT_EN)    &= ~((0x1<< PIN_0_OFFSET)) ;
+	GPIO_REG(GPIO_INPUT_EN)   	|=  ((0x1<< PIN_0_OFFSET));
+    //GPIO_REG(GPIO_PULLUP_EN)  	|=  (1<<PIN_0_OFFSET);
+
+	PLIC_init(&g_plic,
+				PLIC_CTRL_ADDR,
+				PLIC_NUM_INTERRUPTS,
+				PLIC_NUM_PRIORITIES);
+#endif
+
+	is_lower=1;
+}
+
+
diff --git a/bsps/riscv/frdme310arty/start/bsp_fatal_halt.c b/bsps/riscv/frdme310arty/start/bsp_fatal_halt.c
new file mode 100644
index 0000000..bb0f4bf
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/bsp_fatal_halt.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham at alumni.york.ac.uk>
+ *
+ * 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 AUTHOR 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 AUTHOR 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/fdt.h>
+
+#include <libfdt.h>
+
+void _CPU_Fatal_halt(uint32_t source, uint32_t error)
+{
+  const char *fdt;
+  int node;
+  volatile uintptr_t *sifive_test;
+
+
+  fdt = bsp_fdt_get();
+  node = fdt_node_offset_by_compatible(fdt, -1, "sifive,test0");
+  sifive_test = riscv_fdt_get_address(fdt, node);
+  //sifive_test=0x4000;
+
+  while (true)
+  {
+    if (sifive_test != NULL)
+    {
+      *sifive_test = 0x5555;
+    }
+  }
+}
diff --git a/bsps/riscv/frdme310arty/start/bsp_specs b/bsps/riscv/frdme310arty/start/bsp_specs
new file mode 100644
index 0000000..87638cc
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/bsp_specs
@@ -0,0 +1,9 @@
+%rename endfile old_endfile
+%rename startfile old_startfile
+
+*startfile:
+%{!qrtems: %(old_startfile)} \
+%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}}
+
+*endfile:
+%{!qrtems: %(old_endfile)} %{qrtems: crtend.o%s crtn.o%s}
diff --git a/bsps/riscv/frdme310arty/start/bspstart.c b/bsps/riscv/frdme310arty/start/bspstart.c
new file mode 100644
index 0000000..4ff95e8
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/bspstart.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * 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 AUTHOR 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 AUTHOR 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/bootcard.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq-generic.h>
+#include <bsp/riscv.h>
+
+#include <libfdt.h>
+
+unsigned int riscv_core_freq;
+
+uint32_t riscv_get_node_byname(const void *fdt,const char *nodename)
+{
+	int len;
+	int root;
+	int soc;
+	int offset=0;
+	int subnode=0;
+
+	root = fdt_path_offset(fdt, "/");
+	soc = fdt_subnode_offset(fdt, root, "soc");
+
+	offset=soc;
+
+	subnode= fdt_first_subnode(fdt, offset);
+	char *rcvdname=fdt_get_name(fdt, subnode, &len);
+
+	if (memcmp(rcvdname, nodename, strlen(nodename)) == 0)
+	{
+		return subnode;
+	}
+	else
+	{
+		offset=subnode;
+		while(subnode != -1)
+		{
+			subnode=fdt_next_subnode(fdt,offset);
+			char *rcvdname=fdt_get_name(fdt, subnode, &len);
+			offset=subnode;
+
+			if (memcmp(rcvdname, nodename, strlen(nodename)) == 0)
+				break;
+		}
+	}
+	return offset;
+}
+
+void *riscv_fdt_get_address(const void *fdt, int node)
+{
+  int parent;
+  int ac;
+  int len;
+  const uint32_t *reg;
+  uint64_t addr;
+
+  parent = fdt_parent_offset(fdt, node);
+  if (parent < 0) {
+    return NULL;
+  }
+
+  ac = fdt_address_cells(fdt, parent);
+  if (ac != 1 && ac != 2) {
+    return NULL;
+  }
+
+  reg = fdt_getprop(fdt, node, "reg", &len);
+  if (reg == NULL || len < ac) {
+    return NULL;
+  }
+
+  addr = 0;
+
+  while (ac > 0) {
+    addr = (addr << 32) | fdt32_to_cpu(*reg);
+    ++reg;
+    --ac;
+  }
+
+#if __riscv_xlen < 64
+  if (addr > 0xffffffff) {
+    return NULL;
+  }
+#endif
+
+  return (void *)(uintptr_t) addr;
+}
+
+#ifdef RTEMS_SMP
+uint32_t riscv_hart_count;
+
+static uint32_t riscv_hart_phandles[CPU_MAXIMUM_PROCESSORS];
+#else
+static uint32_t riscv_hart_phandles[1];
+#endif
+
+static void riscv_find_harts(void)
+{
+  const void *fdt;
+  int node;
+  uint32_t max_hart_index;
+
+  fdt = bsp_fdt_get();
+  max_hart_index = 0;
+  node = -1;
+
+  while ((node = fdt_node_offset_by_compatible(fdt, node, "riscv")) >= 0) {
+    int subnode;
+    const uint32_t *val;
+    int len;
+    uint32_t phandle;
+    uint32_t hart_index;
+
+    val = fdt_getprop(fdt, node, "reg", &len);
+    if (val == NULL || len != 4) {
+      bsp_fatal(RISCV_FATAL_INVALID_HART_REG_IN_DEVICE_TREE);
+    }
+
+    hart_index = fdt32_to_cpu(val[0]);
+
+    if (hart_index >= RTEMS_ARRAY_SIZE(riscv_hart_phandles)) {
+      continue;
+    }
+
+    if (hart_index > max_hart_index) {
+      max_hart_index = hart_index;
+    }
+
+    phandle = 0;
+
+    fdt_for_each_subnode(subnode, fdt, node) {
+      int propoff;
+      bool interrupt_controller;
+      uint32_t potential_phandle;
+
+      interrupt_controller = false;
+      potential_phandle = 0;
+
+      fdt_for_each_property_offset(propoff, fdt, subnode) {
+        const char *name;
+
+        val = fdt_getprop_by_offset(fdt, propoff, &name, &len);
+        if (val != NULL) {
+          if (strcmp(name, "interrupt-controller") == 0) {
+            interrupt_controller = true;
+          } else if (len == 4 && strcmp(name, "phandle") == 0) {
+            potential_phandle = fdt32_to_cpu(val[0]);
+          }
+        }
+      }
+
+      if (interrupt_controller) {
+        phandle = potential_phandle;
+        break;
+      }
+    }
+
+    riscv_hart_phandles[hart_index] = phandle;
+  }
+
+#ifdef RTEMS_SMP
+  riscv_hart_count = max_hart_index + 1;
+#endif
+}
+
+uint32_t riscv_get_hart_index_by_phandle(uint32_t phandle)
+{
+  uint32_t hart_index;
+
+  for (hart_index = 0; hart_index < riscv_hart_count; ++hart_index) {
+    if (riscv_hart_phandles[hart_index] == phandle) {
+      return hart_index;
+    }
+  }
+
+  return UINT32_MAX;
+}
+
+
+static uint32_t get_core_frequency(void)
+{
+	uint32_t node;
+	const char *fdt=bsp_fdt_get();
+	uint32_t len;
+	node=fdt_node_offset_by_compatible(fdt, -1,"fixed-clock");
+	uint32_t *val=NULL;
+	if(node>0)
+	{
+		val = fdt_getprop(fdt, node, "clock-frequency", &len);
+		if(val !=NULL)
+		{
+			riscv_core_freq=fdt32_to_cpu(*val);
+		}
+	}else
+	{
+		bsp_fatal(FRDM310_RISCV_FATAL_NO_NODE_IN_DEVICE_TREE);
+	}
+	return riscv_core_freq;
+}
+
+inline uint32_t riscv_get_core_frequency(void)
+{
+	return riscv_core_freq;
+}
+
+
+void bsp_start(void)
+{
+	const char *fdt=bsp_fdt_get();
+	int node;
+
+	riscv_find_harts();
+	bsp_interrupt_initialize();
+
+	riscv_core_freq=get_core_frequency();
+
+}
diff --git a/bsps/riscv/frdme310arty/start/linkcmds.in b/bsps/riscv/frdme310arty/start/linkcmds.in
new file mode 100644
index 0000000..d027a09
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/linkcmds.in
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 University of York.
+ * Hesham ALMatary <hmka501 at york.ac.uk>
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+MEMORY
+{
+  RAM    : ORIGIN = 0x80000000, 	LENGTH = 256M
+}
+
+REGION_ALIAS ("REGION_START", RAM);
+REGION_ALIAS ("REGION_TEXT", RAM);
+REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT", RAM);
+REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
+REGION_ALIAS ("REGION_RODATA", RAM);
+REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
+REGION_ALIAS ("REGION_DATA", RAM);
+REGION_ALIAS ("REGION_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_FAST_DATA", RAM);
+REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
+REGION_ALIAS ("REGION_RTEMSSTACK", RAM);
+REGION_ALIAS ("REGION_BSS", RAM);
+REGION_ALIAS ("REGION_WORK", RAM);
+REGION_ALIAS ("REGION_DTB", RAM);
+REGION_ALIAS ("REGION_DTB_LOAD", RAM);
+
+INCLUDE linkcmds.base
diff --git a/bsps/riscv/frdme310arty/start/start.S b/bsps/riscv/frdme310arty/start/start.S
new file mode 100644
index 0000000..76b1115
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/start.S
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham at alumni.york.ac.uk>
+ *
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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 <rtems/asm.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/riscv-utility.h>
+#include <bsp/linker-symbols.h>
+#include <bspopts.h>
+
+PUBLIC(_start)
+
+	.section	.bsp_start_text, "wax", @progbits
+	.align	2
+
+TYPE_FUNC(_start)
+SYM(_start):
+	/* Load global pointer */
+	.option	push
+	.option	norelax
+	LADDR	gp, __global_pointer$
+	.option	pop
+
+	/* Init FPU */
+#ifdef __riscv_flen
+	li	t0, MSTATUS_FS
+	csrs	mstatus, t0
+	csrw	fcsr, zero
+#endif
+
+	/* Set exception handler */
+	LADDR	t0, _RISCV_Exception_handler
+	csrw	mtvec, t0
+
+	/* Load stack pointer and branch to secondary processor start if necessary */
+#ifdef RTEMS_SMP
+	LADDR	sp, _ISR_Stack_area_begin
+	LADDR	t2, _ISR_Stack_size
+	csrr	s0, mhartid
+	LADDR	t0, _Per_CPU_Information
+	slli	t1, s0, PER_CPU_CONTROL_SIZE_LOG2
+	add	s1, t0, t1
+	csrw	mscratch, s1
+	bnez	s0, .Lstart_on_secondary_processor
+	add	sp, sp, t2
+#else
+	LADDR	sp, _ISR_Stack_area_end
+#endif
+
+#ifdef BSP_START_COPY_FDT_FROM_U_BOOT
+	LADDR 	a1, frdme310arty_dtb
+	mv	a0, a1
+	call	bsp_fdt_copy
+#endif
+
+	/* Clear .bss */
+	LADDR	a0, bsp_section_bss_begin
+	li	a1, 0
+	LADDR	a2, bsp_section_bss_size
+	call	memset
+
+#ifdef RTEMS_SMP
+	/* Give go to secondary processors */
+	LADDR	t0, .Lsecondary_processor_go
+	fence	iorw,ow
+	amoswap.w	zero, zero, 0(t0)
+#endif
+
+	j	boot_card
+
+#ifdef RTEMS_SMP
+
+.Lstart_on_secondary_processor:
+
+	/* Adjust stack pointer */
+#ifdef __riscv_mul
+	addi	t0, s0, 1
+	mul	t2, t2, t0
+#else
+	mv	t0, s0
+	mv	t3, t2
+
+.Ladd_more:
+
+	add	t2, t2, t3
+	addi	t0, t0, -1
+	bnez	t0, .Ladd_more
+#endif
+	add	sp, sp, t2
+
+	/* Wait for go issued by the boot processor (mhartid == 0) */
+	LADDR	t0, .Lsecondary_processor_go
+
+.Lwait_for_go_again:
+
+	lw	t1, 0(t0)
+	fence	iorw, iorw
+	bnez	t1, .Lwait_for_go_again
+
+	mv	a0, s1
+	call	bsp_start_on_secondary_processor
+
+#if __riscv_xlen == 32
+	.align	2
+#elif __riscv_xlen == 64
+	.align	3
+#endif
+
+.Lsecondary_processor_go:
+
+	/*
+	 * These are ebreak instructions, just in case we end up here executing
+	 * code.
+	 */
+	.word	0x00100073
+#if __riscv_xlen == 64
+	.word	0x00100073
+#endif
+
+#endif /* RTEMS_SMP */
diff --git a/bsps/riscv/shared/irq/irq.c b/bsps/riscv/shared/irq/irq.c
new file mode 100644
index 0000000..ffd9bbe
--- /dev/null
+++ b/bsps/riscv/shared/irq/irq.c
@@ -0,0 +1,379 @@
+/**
+ * @file
+ *
+ * @ingroup riscv_interrupt
+ *
+ * @brief Interrupt support.
+ */
+
+/*
+ * Copyright (c) 2018 embedded brains GmbH
+ *
+ * Copyright (c) 2015 University of York.
+ * Hesham Almatary <hesham at alumni.york.ac.uk>
+ *
+ * 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 AUTHOR 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 AUTHOR 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/irq.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/irq-generic.h>
+#include <bsp/riscv.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/riscv-utility.h>
+#include <rtems/score/smpimpl.h>
+
+#include <libfdt.h>
+
+volatile RISCV_CLINT_regs *riscv_clint;
+
+/*
+ * The lovely PLIC has an interrupt enable bit per hart for each interrupt
+ * source.  This makes the interrupt enable/disable a bit difficult.  We have
+ * to store the interrupt distribution in software.  To keep it simple, we
+ * support only a one-to-one and one-to-all interrupt to processor
+ * distribution.  For a one-to-one distribution, the array member must point to
+ * the enable register block of the corresponding.  For a one-to-all
+ * distribution, the array member must be NULL.  The array index is the
+ * external interrupt index minus one (external interrupt index zero is a
+ * special value, see PLIC documentation).
+ */
+static volatile uint32_t *
+riscv_plic_irq_to_cpu[RISCV_MAXIMUM_EXTERNAL_INTERRUPTS];
+
+RTEMS_INTERRUPT_LOCK_DEFINE(static, riscv_plic_lock, "PLIC")
+
+void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
+{
+  /*
+   * Get rid of the most significant bit which indicates if the exception was
+   * caused by an interrupt or not.
+   */
+  mcause <<= 1;
+
+  if (mcause == (RISCV_INTERRUPT_TIMER_MACHINE << 1)) {
+    bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_TIMER);
+  } else if (mcause == (RISCV_INTERRUPT_EXTERNAL_MACHINE << 1)) {
+    volatile RISCV_PLIC_hart_regs *plic_hart_regs;
+    uint32_t interrupt_index;
+
+    plic_hart_regs = cpu_self->cpu_per_cpu.plic_hart_regs;
+
+    while ((interrupt_index = plic_hart_regs->claim_complete) != 0) {
+      bsp_interrupt_handler_dispatch(
+        RISCV_INTERRUPT_VECTOR_EXTERNAL(interrupt_index)
+      );
+
+      plic_hart_regs->claim_complete = interrupt_index;
+
+      /*
+       * FIXME: It is not clear which fence is necessary here or if a fence is
+       * necessary at all.  The goal is that the complete signal is somehow
+       * recognized by the PLIC before the next claim is issued.
+       */
+      __asm__ volatile ("fence o, i" : : : "memory");
+    }
+  } else if (mcause == (RISCV_INTERRUPT_SOFTWARE_MACHINE << 1)) {
+#ifdef RTEMS_SMP
+    /*
+     * Clear the software interrupt on this processor.  Synchronization of
+     * inter-processor interrupts is done via Per_CPU_Control::message in
+     * _SMP_Inter_processor_interrupt_handler().
+     */
+    *cpu_self->cpu_per_cpu.clint_msip = 0;
+
+    _SMP_Inter_processor_interrupt_handler(cpu_self);
+#else
+    bsp_interrupt_handler_dispatch(RISCV_INTERRUPT_VECTOR_SOFTWARE);
+#endif
+  } else {
+    bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
+  }
+}
+
+static void riscv_clint_init(const void *fdt)
+{
+  volatile RISCV_CLINT_regs *clint;
+  int node;
+  const uint32_t *val;
+  int len;
+  int i;
+
+  node = fdt_node_offset_by_compatible(fdt, -1, "riscv,clint0");
+
+  clint = riscv_fdt_get_address(fdt, node);
+  if (clint == NULL) {
+    bsp_fatal(RISCV_FATAL_NO_CLINT_REG_IN_DEVICE_TREE);
+  }
+
+  riscv_clint = clint;
+
+  val = fdt_getprop(fdt, node, "interrupts-extended", &len);
+
+  for (i = 0; i < len; i += 16) {
+    uint32_t hart_index;
+    Per_CPU_Control *cpu;
+
+    hart_index = riscv_get_hart_index_by_phandle(fdt32_to_cpu(val[i / 4]));
+    if (hart_index >= rtems_configuration_get_maximum_processors()) {
+      continue;
+    }
+
+    cpu = _Per_CPU_Get_by_index(hart_index);
+    cpu->cpu_per_cpu.clint_msip = &clint->msip[i / 16];
+    cpu->cpu_per_cpu.clint_mtimecmp = &clint->mtimecmp[i / 16];
+  }
+}
+
+static void riscv_plic_init(const void *fdt)
+{
+  volatile RISCV_PLIC_regs *plic;
+  int node;
+  int i;
+  const uint32_t *val;
+  int len;
+  uint32_t interrupt_index;
+  uint32_t ndev;
+  Per_CPU_Control *cpu;
+
+  node = fdt_node_offset_by_compatible(fdt, -1, "riscv,plic0");
+
+  plic = riscv_fdt_get_address(fdt, node);
+  if (plic == NULL) {
+#if RISCV_ENABLE_HTIF_SUPPORT != 0
+    /* Spike platform has HTIF and does not have a PLIC */
+    return;
+#else
+    bsp_fatal(RISCV_FATAL_NO_PLIC_REG_IN_DEVICE_TREE);
+#endif
+  }
+
+  val = fdt_getprop(fdt, node, "riscv,ndev", &len);
+  if (val == NULL || len != 4) {
+    bsp_fatal(RISCV_FATAL_INVALID_PLIC_NDEV_IN_DEVICE_TREE);
+  }
+
+  ndev = fdt32_to_cpu(val[0]);
+  if (ndev > RISCV_MAXIMUM_EXTERNAL_INTERRUPTS) {
+    bsp_fatal(RISCV_FATAL_TOO_LARGE_PLIC_NDEV_IN_DEVICE_TREE);
+  }
+
+  val = fdt_getprop(fdt, node, "interrupts-extended", &len);
+
+  for (i = 0; i < len; i += 8) {
+    uint32_t hart_index;
+
+    hart_index = riscv_get_hart_index_by_phandle(fdt32_to_cpu(val[i / 4]));
+    if (hart_index >= rtems_configuration_get_maximum_processors()) {
+      continue;
+    }
+
+    interrupt_index = fdt32_to_cpu(val[i / 4 + 1]);
+    if (interrupt_index != RISCV_INTERRUPT_EXTERNAL_MACHINE) {
+      continue;
+    }
+
+    plic->harts[i / 8].priority_threshold = 0;
+
+    cpu = _Per_CPU_Get_by_index(hart_index);
+    cpu->cpu_per_cpu.plic_hart_regs = &plic->harts[i / 8];
+    cpu->cpu_per_cpu.plic_m_ie = &plic->enable[i / 8][0];
+  }
+
+  cpu = _Per_CPU_Get_by_index(0);
+
+  for (interrupt_index = 1; interrupt_index <= ndev; ++interrupt_index) {
+    plic->priority[interrupt_index] = 1;
+    riscv_plic_irq_to_cpu[interrupt_index - 1] = cpu->cpu_per_cpu.plic_m_ie;
+  }
+
+  /*
+   * External M-mode interrupts on secondary processors are enabled in
+   * bsp_start_on_secondary_processor().
+   */
+  set_csr(mie, MIP_MEIP);
+}
+
+rtems_status_code bsp_interrupt_facility_initialize(void)
+{
+  const void *fdt;
+
+  fdt = bsp_fdt_get();
+  riscv_clint_init(fdt);
+  riscv_plic_init(fdt);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+void bsp_interrupt_vector_enable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
+    uint32_t interrupt_index;
+    volatile uint32_t *enable;
+    uint32_t group;
+    uint32_t bit;
+    rtems_interrupt_lock_context lock_context;
+
+    interrupt_index = RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
+    enable = riscv_plic_irq_to_cpu[interrupt_index - 1];
+    group = interrupt_index / 32;
+    bit = UINT32_C(1) << (interrupt_index % 32);
+
+    rtems_interrupt_lock_acquire(&riscv_plic_lock, &lock_context);
+
+    if (enable != NULL) {
+      enable[group] |= bit;
+    } else {
+      uint32_t cpu_max;
+      uint32_t cpu_index;
+
+      cpu_max = _SMP_Get_processor_maximum();
+
+      for (cpu_index = 0; cpu_index < cpu_max; ++cpu_index) {
+        Per_CPU_Control *cpu;
+
+        cpu = _Per_CPU_Get_by_index(cpu_index);
+        enable = cpu->cpu_per_cpu.plic_m_ie;
+
+        if (enable != NULL) {
+          enable[group] |= bit;
+        }
+      }
+    }
+
+    rtems_interrupt_lock_release(&riscv_plic_lock, &lock_context);
+  }
+}
+
+void bsp_interrupt_vector_disable(rtems_vector_number vector)
+{
+  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
+
+  if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
+    uint32_t interrupt_index;
+    volatile uint32_t *enable;
+    uint32_t group;
+    uint32_t bit;
+    rtems_interrupt_lock_context lock_context;
+
+    interrupt_index = RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
+    enable = riscv_plic_irq_to_cpu[interrupt_index - 1];
+    group = interrupt_index / 32;
+    bit = UINT32_C(1) << (interrupt_index % 32);
+
+    rtems_interrupt_lock_acquire(&riscv_plic_lock, &lock_context);
+
+    if (enable != NULL) {
+      enable[group] &= ~bit;
+    } else {
+      uint32_t cpu_max;
+      uint32_t cpu_index;
+
+      cpu_max = _SMP_Get_processor_maximum();
+
+      for (cpu_index = 0; cpu_index < cpu_max; ++cpu_index) {
+        Per_CPU_Control *cpu;
+
+        cpu = _Per_CPU_Get_by_index(cpu_index);
+        enable = cpu->cpu_per_cpu.plic_m_ie;
+
+        if (enable != NULL) {
+          enable[group] &= ~bit;
+        }
+      }
+    }
+
+    rtems_interrupt_lock_release(&riscv_plic_lock, &lock_context);
+  }
+}
+
+void bsp_interrupt_set_affinity(
+  rtems_vector_number vector,
+  const Processor_mask *affinity
+)
+{
+  if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
+    uint32_t interrupt_index;
+    Processor_mask mask;
+
+    interrupt_index = RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
+
+    _Processor_mask_And(&mask, affinity, _SMP_Get_online_processors());
+
+    if (_Processor_mask_Is_equal(&mask, _SMP_Get_online_processors())) {
+      riscv_plic_irq_to_cpu[interrupt_index - 1] = NULL;
+      return;
+    }
+
+    if (_Processor_mask_Count(&mask) == 1) {
+      uint32_t cpu_index;
+      Per_CPU_Control *cpu;
+
+      cpu_index = _Processor_mask_Find_last_set(&mask) - 1;
+      cpu = _Per_CPU_Get_by_index(cpu_index);
+      riscv_plic_irq_to_cpu[interrupt_index - 1] = cpu->cpu_per_cpu.plic_m_ie;
+      return;
+    }
+
+    bsp_fatal(RISCV_FATAL_INVALID_INTERRUPT_AFFINITY);
+  }
+}
+
+void bsp_interrupt_get_affinity(
+  rtems_vector_number vector,
+  Processor_mask *affinity
+)
+{
+  _Processor_mask_Zero(affinity);
+
+  if (RISCV_INTERRUPT_VECTOR_IS_EXTERNAL(vector)) {
+    uint32_t interrupt_index;
+    volatile uint32_t *enable;
+
+    interrupt_index = RISCV_INTERRUPT_VECTOR_EXTERNAL_TO_INDEX(vector);
+    enable = riscv_plic_irq_to_cpu[interrupt_index - 1];
+
+    if (enable != NULL) {
+      uint32_t cpu_max;
+      uint32_t cpu_index;
+
+      cpu_max = _SMP_Get_processor_maximum();
+
+      for (cpu_index = 0; cpu_index < cpu_max; ++cpu_index) {
+        Per_CPU_Control *cpu;
+
+        cpu = _Per_CPU_Get_by_index(cpu_index);
+
+        if (enable == cpu->cpu_per_cpu.plic_m_ie) {
+          _Processor_mask_Set(affinity, cpu_index);
+          break;
+        }
+      }
+    } else {
+      _Processor_mask_Assign(affinity, _SMP_Get_online_processors());
+    }
+  }
+}
diff --git a/c/src/lib/libbsp/riscv/acinclude.m4 b/c/src/lib/libbsp/riscv/acinclude.m4
index db1a210..40b6ab0 100644
--- a/c/src/lib/libbsp/riscv/acinclude.m4
+++ b/c/src/lib/libbsp/riscv/acinclude.m4
@@ -6,6 +6,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
     AC_CONFIG_SUBDIRS([griscv]);;
   riscv )
     AC_CONFIG_SUBDIRS([riscv]);;
+ frdme310arty )
+    AC_CONFIG_SUBDIRS([frdme310arty]);;
   *)
     AC_MSG_ERROR([Invalid BSP]);;
   esac
diff --git a/c/src/lib/libbsp/riscv/frdme310arty/Makefile.am b/c/src/lib/libbsp/riscv/frdme310arty/Makefile.am
new file mode 100644
index 0000000..3fa5fae
--- /dev/null
+++ b/c/src/lib/libbsp/riscv/frdme310arty/Makefile.am
@@ -0,0 +1,75 @@
+##
+#
+# @brief Makefile of LibBSP for the frdme310arty.
+#
+#
+ACLOCAL_AMFLAGS = -I ../../../../aclocal
+
+include $(top_srcdir)/../../../../automake/compile.am
+include $(top_srcdir)/../../bsp.am
+
+dist_project_lib_DATA = ../../../../../../bsps/riscv/frdme310arty/start/bsp_specs
+
+###############################################################################
+#                  Header                                                     #
+###############################################################################
+
+###############################################################################
+#                  Data                                                       #
+###############################################################################
+
+start.$(OBJEXT): ../../../../../../bsps/riscv/frdme310arty/start/start.S
+	$(CPPASCOMPILE) -o $@ -c $<
+project_lib_DATA = start.$(OBJEXT)
+
+
+project_lib_DATA += linkcmds
+project_lib_DATA += ../../../../../../bsps/riscv/shared/start/linkcmds.base
+
+	
+###############################################################################
+#                  LibBSP                                                     #
+###############################################################################
+
+project_lib_LIBRARIES = librtemsbsp.a
+
+# Startup
+librtemsbsp_a_SOURCES = ../../../../../../bsps/shared/start/bspreset-empty.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/start/bspstart.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/start/bsp_fatal_halt.c
+
+# Shared
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspfatal-default.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/getentropy/getentropy-cpucounter.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bsp-fdt.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspgetworkarea-default.c
+
+# clock
+librtemsbsp_a_SOURCES +=../../../../../../bsps/riscv/frdme310arty/clock/clockdrv.c
+
+# Timer
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/btimer/btimer.c
+
+# IRQ
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/irq/irq-default-handler.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/shared/irq/irq.c
+
+# Cache
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c
+
+# Console
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/console-termios.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/console/console-config.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/console/uart.c
+
+
+#device tree
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/dts/frdme310arty_dtb_array.c
+
+if HAS_SMP
+librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/frdme310arty/start/bspsmp.c
+endif
+
+include $(srcdir)/../../../../../../bsps/shared/irq-sources.am
+include $(srcdir)/../../../../../../bsps/shared/shared-sources.am
+include $(srcdir)/../../../../../../bsps/riscv/frdme310arty/headers.am
diff --git a/c/src/lib/libbsp/riscv/frdme310arty/configure.ac b/c/src/lib/libbsp/riscv/frdme310arty/configure.ac
new file mode 100644
index 0000000..a0dc83e
--- /dev/null
+++ b/c/src/lib/libbsp/riscv/frdme310arty/configure.ac
@@ -0,0 +1,68 @@
+##
+#
+# @file
+#
+# @brief Configure script of LibBSP for frdme310arty BSP.
+#
+
+AC_PREREQ([2.69])
+AC_INIT([rtems-c-src-lib-libbsp-riscv],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
+RTEMS_TOP(../../../../../..)
+RTEMS_SOURCE_TOP
+RTEMS_BUILD_TOP
+
+RTEMS_CANONICAL_TARGET_CPU
+AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2])
+RTEMS_BSP_CONFIGURE
+
+RTEMS_BSPOPTS_SET([BSP_START_COPY_FDT_FROM_U_BOOT],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_START_COPY_FDT_FROM_U_BOOT],[copy the U-Boot provided FDT to an internal storage])
+
+RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_SIZE_MAX],[*],[65536])
+RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_SIZE_MAX],[maximum size of the FDT blob in bytes])
+
+RTEMS_BSPOPTS_SET([BSP_FDT_BLOB_READ_ONLY],[*],[1])
+RTEMS_BSPOPTS_HELP([BSP_FDT_BLOB_READ_ONLY],[place the FDT blob into the read-only data area])
+
+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_MAXIMUM_EXTERNAL_INTERRUPTS],[*],[64])
+RTEMS_BSPOPTS_HELP([RISCV_MAXIMUM_EXTERNAL_INTERRUPTS],[maximum number of external interrupts supported by the BSP (default 64)])
+
+RTEMS_BSPOPTS_SET([RISCV_ENABLE_HTIF_SUPPORT],[*],[])
+RTEMS_BSPOPTS_HELP([RISCV_ENABLE_HTIF_SUPPORT],[enables the HTIF support if defined to a non-zero value, otherwise it is disabled (disabled 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
+  rv64*medany)
+    RISCV_RAM_REGION_BEGIN_DEFAULT=0x80000000
+    ;;
+  rv64*)
+    RISCV_RAM_REGION_BEGIN_DEFAULT=0x70000000
+    ;;
+  *)
+    RISCV_RAM_REGION_BEGIN_DEFAULT=0x80000000
+    ;;
+esac
+
+AC_DEFUN([RISCV_LINKCMD],[
+AC_ARG_VAR([$1],[$2])dnl
+[$1]=[$]{[$1]:-[$3]}
+])
+
+RISCV_LINKCMD([RISCV_RAM_REGION_BEGIN],[begin of the RAM region for linker command file (default is 0x80000000)],[${RISCV_RAM_REGION_BEGIN_DEFAULT}])
+RISCV_LINKCMD([RISCV_RAM_REGION_SIZE],[size of the RAM region for linker command file (default 64MiB)],[0x04000000])
+
+AC_CONFIG_FILES([
+Makefile
+linkcmds:../../../../../../bsps/riscv/frdme310arty/start/linkcmds.in
+])
+AC_OUTPUT
-- 
2.7.4



More information about the devel mailing list