[RTEMS][PATCH v2 1/2] riscv: add freedom E310 Arty A7 bsp
Pragnesh Patel
pragnesh.patel at sifive.com
Tue Sep 10 06:34:19 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 | 104 ++++++
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 | 59 ++++
bsps/riscv/frdme310arty/include/tm27.h | 334 ++++++++++++++++++
bsps/riscv/frdme310arty/start/bsp_specs | 9 +
bsps/riscv/frdme310arty/start/bspstart.c | 204 +++++++++++
bsps/riscv/frdme310arty/start/linkcmds.in | 49 +++
bsps/riscv/frdme310arty/start/start.S | 147 ++++++++
bsps/riscv/shared/clock/clockdrv.c | 231 +++++++++++++
bsps/riscv/shared/irq/irq.c | 379 +++++++++++++++++++++
bsps/riscv/shared/start/bsp_fatal_halt.c | 53 +++
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, 2552 insertions(+), 1 deletion(-)
create mode 100644 bsps/riscv/frdme310arty/btimer/btimer.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_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/clock/clockdrv.c
create mode 100644 bsps/riscv/shared/irq/irq.c
create mode 100644 bsps/riscv/shared/start/bsp_fatal_halt.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..b03c245
--- /dev/null
+++ b/bsps/riscv/frdme310arty/btimer/btimer.c
@@ -0,0 +1,104 @@
+/**
+ * @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>
+#include <rtems/score/riscv-utility.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
+
+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/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..a51f8aa
--- /dev/null
+++ b/bsps/riscv/frdme310arty/include/bsp/riscv.h
@@ -0,0 +1,59 @@
+/*
+ * 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 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_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..9659484
--- /dev/null
+++ b/bsps/riscv/frdme310arty/start/bspstart.c
@@ -0,0 +1,204 @@
+/*
+ * 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;
+
+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..ba76361
--- /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 = @RISCV_RAM_REGION_BEGIN@, LENGTH = @RISCV_RAM_REGION_SIZE@
+}
+
+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/clock/clockdrv.c b/bsps/riscv/shared/clock/clockdrv.c
new file mode 100644
index 0000000..74d7d7b
--- /dev/null
+++ b/bsps/riscv/shared/clock/clockdrv.c
@@ -0,0 +1,231 @@
+/**
+ * @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 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];
+}
+
+
+
+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");
+
+ val = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
+
+ if (val == NULL || len < 4) {
+ 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 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
+ );
+
+ /* Enable mtimer interrupts */
+ set_csr(mie, MIP_MTIP);
+
+ /* 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);
+
+}
+
+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());
+}
+
+CPU_Counter_ticks _CPU_Counter_read( void )
+{
+ return *_RISCV_Counter;
+}
+
+RTEMS_SYSINIT_ITEM(
+ riscv_counter_initialize,
+ RTEMS_SYSINIT_CPU_COUNTER,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
+
+#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()
+
+#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
+
+#include "../../../shared/dev/clock/clockimpl.h"
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/bsps/riscv/shared/start/bsp_fatal_halt.c b/bsps/riscv/shared/start/bsp_fatal_halt.c
new file mode 100644
index 0000000..af9e2ac
--- /dev/null
+++ b/bsps/riscv/shared/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;
+
+#if RISCV_ENABLE_HTIF_SUPPORT != 0
+ htif_poweroff();
+#endif
+
+ fdt = bsp_fdt_get();
+ node = fdt_node_offset_by_compatible(fdt, -1, "sifive,test0");
+ sifive_test = riscv_fdt_get_address(fdt, node);
+
+ while (true) {
+ if (sifive_test != NULL) {
+ *sifive_test = 0x5555;
+ }
+ }
+}
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..594ddf2
--- /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/shared/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/shared/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..3f91c9e
--- /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 256MiB)],[0x10000000])
+
+AC_CONFIG_FILES([
+Makefile
+linkcmds:../../../../../../bsps/riscv/frdme310arty/start/linkcmds.in
+])
+AC_OUTPUT
--
2.7.4
More information about the devel
mailing list