summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal')
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h59
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h58
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h119
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h271
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h24
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h203
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h31
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h42
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h20
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h26
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h23
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h23
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h24
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h28
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h151
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h134
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h22
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h21
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h68
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h127
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h872
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h249
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h237
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h81
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h204
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h122
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h36
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h78
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h51
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h36
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h23
-rw-r--r--FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h94
43 files changed, 3794 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h
new file mode 100644
index 000000000..0c26f435a
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h
@@ -0,0 +1,59 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__BUTTON_H
+#define METAL__BUTTON_H
+
+/*!
+ * @file button.h
+ * API for interfacing with physical buttons
+ */
+
+#include <metal/interrupt.h>
+
+struct metal_button;
+
+struct metal_button_vtable {
+ int (*button_exist)(struct metal_button *button, char *label);
+ struct metal_interrupt* (*interrupt_controller)(struct metal_button *button);
+ int (*get_interrupt_id)(struct metal_button *button);
+};
+
+/*!
+ * @brief A button device handle
+ *
+ * A `struct metal_button` is an implementation-defined object which represents
+ * a button on a development board.
+ */
+struct metal_button {
+ const struct metal_button_vtable *vtable;
+};
+
+/*!
+ * @brief Get a reference to a button
+ *
+ * @param label The DeviceTree label for the button
+ * @return A handle for the button
+ */
+struct metal_button* metal_button_get(char *label);
+
+
+/*!
+ * @brief Get the interrupt controller for a button
+ *
+ * @param button The handle for the button
+ * @return A pointer to the interrupt controller responsible for handling
+ * button interrupts.
+ */
+inline struct metal_interrupt*
+ metal_button_interrupt_controller(struct metal_button *button) { return button->vtable->interrupt_controller(button); }
+
+/*!
+ * @brief Get the interrupt id for a button
+ *
+ * @param button The handle for the button
+ * @return The interrupt id corresponding to a button.
+ */
+inline int metal_button_get_interrupt_id(struct metal_button *button) { return button->vtable->get_interrupt_id(button); }
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h
new file mode 100644
index 000000000..a8a60ada6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h
@@ -0,0 +1,58 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__CACHE_H
+#define METAL__CACHE_H
+
+/*!
+ * @file cache.h
+ *
+ * @brief API for configuring caches
+ */
+
+struct metal_cache;
+
+struct __metal_cache_vtable {
+ void (*init)(struct metal_cache *cache, int ways);
+ int (*get_enabled_ways)(struct metal_cache *cache);
+ int (*set_enabled_ways)(struct metal_cache *cache, int ways);
+};
+
+/*!
+ * @brief a handle for a cache
+ */
+struct metal_cache {
+ const struct __metal_cache_vtable *vtable;
+};
+
+/*!
+ * @brief Initialize a cache
+ * @param cache The handle for the cache to initialize
+ * @param ways The number of ways to enable
+ *
+ * Initializes a cache with the requested number of ways enabled.
+ */
+inline void metal_cache_init(struct metal_cache *cache, int ways) {
+ return cache->vtable->init(cache, ways);
+}
+
+/*!
+ * @brief Get the current number of enabled cache ways
+ * @param cache The handle for the cache
+ * @return The current number of enabled cache ways
+ */
+inline int metal_cache_get_enabled_ways(struct metal_cache *cache) {
+ return cache->vtable->get_enabled_ways(cache);
+}
+
+/*!
+ * @brief Enable the requested number of cache ways
+ * @param cache The handle for the cache
+ * @param ways The number of ways to enabled
+ * @return 0 if the ways are successfully enabled
+ */
+inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) {
+ return cache->vtable->set_enabled_ways(cache, ways);
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h
new file mode 100644
index 000000000..277841e01
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h
@@ -0,0 +1,119 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__CLOCK_H
+#define METAL__CLOCK_H
+
+/*!
+ * @file clock.h
+ * @brief API for manipulating clock sources
+ *
+ * The clock interface allows for controlling the rate of various clocks in the system.
+ */
+
+struct metal_clock;
+
+#include <stddef.h>
+
+/* The generic interface to all clocks. */
+struct __metal_clock_vtable {
+ long (*get_rate_hz)(const struct metal_clock *clk);
+ long (*set_rate_hz)(struct metal_clock *clk, long hz);
+};
+
+/*!
+ * @brief Function signature of clock pre-rate change callbacks
+ */
+typedef void (*metal_clock_pre_rate_change_callback)(void *priv);
+
+/*!
+ * @brief Function signature of clock post-rate change callbacks
+ */
+typedef void (*metal_clock_post_rate_change_callback)(void *priv);
+
+/*!
+ * @struct metal_clock
+ * @brief The handle for a clock
+ *
+ * Clocks are defined as a pointer to a `struct metal_clock`, the contents of which
+ * are implementation defined. Users of the clock interface must call functions
+ * which accept a `struct metal_clock *` as an argument to interract with the clock.
+ *
+ * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has been
+ * defined, making it impossible to call any of these functions without invoking
+ * implementation-defined behavior.
+ */
+struct metal_clock {
+ const struct __metal_clock_vtable *vtable;
+
+ /* Pre-rate change callback */
+ metal_clock_pre_rate_change_callback _pre_rate_change_callback;
+ void *_pre_rate_change_callback_priv;
+
+ /* Post-rate change callback */
+ metal_clock_post_rate_change_callback _post_rate_change_callback;
+ void *_post_rate_change_callback_priv;
+};
+
+/*!
+ * @brief Returns the current rate of the given clock
+ *
+ * @param clk The handle for the clock
+ * @return The current rate of the clock in Hz
+ */
+inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk->vtable->get_rate_hz(clk); }
+
+/*!
+ * @brief Set the current rate of a clock
+ *
+ * @param clk The handle for the clock
+ * @param hz The desired rate in Hz
+ * @return The new rate of the clock in Hz.
+ *
+ * Attempts to set the current rate of the given clock to as close as possible
+ * to the given rate in Hz. Returns the actual value that's been selected, which
+ * could be anything!
+ *
+ * Prior to and after the rate change of the clock, this will call the registered
+ * pre- and post-rate change callbacks.
+ */
+inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz)
+{
+ if(clk->_pre_rate_change_callback != NULL)
+ clk->_pre_rate_change_callback(clk->_pre_rate_change_callback_priv);
+
+ long out = clk->vtable->set_rate_hz(clk, hz);
+
+ if (clk->_post_rate_change_callback != NULL)
+ clk->_post_rate_change_callback(clk->_post_rate_change_callback_priv);
+
+ return out;
+}
+
+/*!
+ * @brief Register a callback that must be called before a rate change
+ *
+ * @param clk The handle for the clock
+ * @param cb The callback to be registered
+ * @param priv Private data for the callback handler
+ */
+inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_pre_rate_change_callback cb, void *priv)
+{
+ clk->_pre_rate_change_callback = cb;
+ clk->_pre_rate_change_callback_priv = priv;
+}
+
+/*!
+ * @brief Registers a callback that must be called after a rate change
+ *
+ * @param clk The handle for the clock
+ * @param cb The callback to be registered
+ * @param priv Private data for the callback handler
+ */
+inline void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_post_rate_change_callback cb, void *priv)
+{
+ clk->_post_rate_change_callback = cb;
+ clk->_post_rate_change_callback_priv = priv;
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h
new file mode 100644
index 000000000..62c0ea975
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__COMPILER_H
+#define METAL__COMPILER_H
+
+#define __METAL_DECLARE_VTABLE(type) \
+ extern const struct type type;
+
+#define __METAL_DEFINE_VTABLE(type) \
+ const struct type type
+
+#define __METAL_GET_FIELD(reg, mask) \
+ (((reg) & (mask)) / ((mask) & ~((mask) << 1)))
+
+/* Set field with mask for a given value */
+#define __METAL_SET_FIELD(reg, mask, val) \
+ (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
+
+void _metal_trap(int ecode);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h
new file mode 100644
index 000000000..453bd12de
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h
@@ -0,0 +1,271 @@
+/* Copyright 2018 SiFive, Inc */
+
+/* SPDX-License-Identifier: Apache-2.0 */
+
+/*! @file cpu.h
+ * @brief API for accessing CPU capabilities.
+ */
+
+#ifndef METAL__CPU_H
+#define METAL__CPU_H
+
+#include <stdint.h>
+#include <metal/interrupt.h>
+
+struct metal_cpu;
+
+/*!
+ * @brief Function signature for exception handlers
+ */
+typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode);
+
+struct metal_cpu_vtable {
+ unsigned long long (*timer_get)(struct metal_cpu *cpu);
+ unsigned long long (*timebase_get)(struct metal_cpu *cpu);
+ unsigned long long (*mtime_get)(struct metal_cpu *cpu);
+ int (*mtimecmp_set)(struct metal_cpu *cpu, unsigned long long time);
+ struct metal_interrupt* (*tmr_controller_interrupt)(struct metal_cpu *cpu);
+ int (*get_tmr_interrupt_id)(struct metal_cpu *cpu);
+ struct metal_interrupt* (*sw_controller_interrupt)(struct metal_cpu *cpu);
+ int (*get_sw_interrupt_id)(struct metal_cpu *cpu);
+ int (*set_sw_ipi)(struct metal_cpu *cpu, int hartid);
+ int (*clear_sw_ipi)(struct metal_cpu *cpu, int hartid);
+ int (*get_msip)(struct metal_cpu *cpu, int hartid);
+ struct metal_interrupt* (*controller_interrupt)(struct metal_cpu *cpu);
+ int (*exception_register)(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler);
+ int (*get_ilen)(struct metal_cpu *cpu, uintptr_t epc);
+ uintptr_t (*get_epc)(struct metal_cpu *cpu);
+ int (*set_epc)(struct metal_cpu *cpu, uintptr_t epc);
+};
+
+/*! @brief A device handle for a CPU hart
+ */
+struct metal_cpu {
+ const struct metal_cpu_vtable *vtable;
+};
+
+/*! @brief Get a reference to a CPU hart
+ *
+ * @param hartid The ID of the desired CPU hart
+ * @return A pointer to the CPU device handle
+ */
+struct metal_cpu* metal_cpu_get(int hartid);
+
+/*! @brief Get the hartid of the CPU hart executing this function
+ *
+ * @return The hartid of the current CPU hart */
+int metal_cpu_get_current_hartid();
+
+/*! @brief Get the number of CPU harts
+ *
+ * @return The number of CPU harts */
+int metal_cpu_get_num_harts();
+
+/*! @brief Get the CPU cycle count timer value
+ *
+ * Get the value of the cycle count timer for a given CPU
+ *
+ * @param cpu The CPU device handle
+ * @return The value of the CPU cycle count timer
+ */
+inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu)
+{ return cpu->vtable->timer_get(cpu); }
+
+/*! @brief Get the timebase of the CPU
+ *
+ * Get the value of the timebase of the cycle count timer
+ *
+ * @param cpu The CPU device handle
+ * @return The value of the cycle count timer timebase
+ */
+inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu)
+{ return cpu->vtable->timebase_get(cpu); }
+
+/*! @brief Get the value of the mtime RTC
+ *
+ * Get the value of the mtime real-time clock. The CPU interrupt controller
+ * must be initialized before this function is called or the return value
+ * will be 0.
+ *
+ * @param cpu The CPU device handle
+ * @return The value of mtime, or 0 if failure
+ */
+inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu)
+{ return cpu->vtable->mtime_get(cpu); }
+
+/*! @brief Set the value of the RTC mtimecmp RTC
+ *
+ * Set the value of the mtime real-time clock compare register. The CPU
+ * interrupt controller must be initialized before this function is called
+ * or the return value will be -1;
+ *
+ * @param cpu The CPU device handle
+ * @param time The value to set the compare register to
+ * @return The value of mtimecmp or -1 if error
+ */
+inline int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time)
+{ return cpu->vtable->mtimecmp_set(cpu, time); }
+
+/*! @brief Get a reference to RTC timer interrupt controller
+ *
+ * Get a reference to the interrupt controller for the real-time clock interrupt.
+ * The controller returned by this function must be initialized before any interrupts
+ * are registered or enabled with it.
+ *
+ * @param cpu The CPU device handle
+ * @return A pointer to the timer interrupt handle
+ */
+inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu)
+{ return cpu->vtable->tmr_controller_interrupt(cpu); }
+
+/*! @brief Get the RTC timer interrupt id
+ *
+ * Get the interrupt ID of the real-time clock interrupt
+ *
+ * @param cpu The CPU device handle
+ * @return The timer interrupt ID
+ */
+inline int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu)
+{ return cpu->vtable->get_tmr_interrupt_id(cpu); }
+
+/*! @brief Get a reference to the software interrupt controller
+ *
+ * Get a reference to the interrupt controller for the software/inter-process
+ * interrupt. The controller returned by this function must be initialized before
+ * any interrupts are registered or enabled with it.
+ *
+ * @param cpu The CPU device handle
+ * @return A pointer to the software interrupt handle
+ */
+inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu)
+{ return cpu->vtable->sw_controller_interrupt(cpu); }
+
+/*! @brief Get the software interrupt id
+ *
+ * Get the interrupt ID for the software/inter-process interrupt
+ *
+ * @param cpu The CPU device handle
+ * @return the software interrupt ID
+ */
+inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu)
+{ return cpu->vtable->get_sw_interrupt_id(cpu); }
+
+/*!
+ * @brief Set the inter-process interrupt for a hart
+ *
+ * Trigger a software/inter-process interrupt for a hart. The CPU interrupt
+ * controller for the CPU handle passed to this function must be initialized
+ * before this function is called.
+ *
+ * @param cpu The CPU device handle
+ * @param hartid The CPU hart ID to be interrupted
+ * @return 0 upon success
+ */
+inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid)
+{ return cpu->vtable->set_sw_ipi(cpu, hartid); }
+
+/*!
+ * @brief Clear the inter-process interrupt for a hart
+ *
+ * Clear the software/inter-process interrupt for a hart. The CPU interrupt
+ * controller for the CPU handle passed to this function must be initialized
+ * before this function is called.
+ *
+ * @param cpu The CPU device handle
+ * @param hartid The CPU hart ID to clear
+ * @return 0 upon success
+ */
+inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid)
+{ return cpu->vtable->clear_sw_ipi(cpu, hartid); }
+
+/*!
+ * @brief Get the value of MSIP for the given hart
+ *
+ * Get the value of the machine software interrupt pending bit for
+ * the given hart. The CPU interrupt controller for the CPU handle passed
+ * as argument to this function must be initialized before this function
+ * is called.
+ *
+ * @param cpu the CPU device handle
+ * @param hartid The CPU hart to read
+ * @return 0 upon success
+ */
+inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid)
+{ return cpu->vtable->get_msip(cpu, hartid); }
+
+/*!
+ * @brief Get the interrupt controller for the CPU
+ *
+ * Get the CPU interrupt controller. The controller returned by this
+ * function must be initialized before any interrupts are registered
+ * or enabled and before any exception handlers are registered with
+ * this CPU.
+ *
+ * @param cpu The CPU device handle
+ * @return The handle for the CPU interrupt controller
+ */
+inline struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu)
+{ return cpu->vtable->controller_interrupt(cpu); }
+
+/*!
+ * @brief Register an exception handler
+ *
+ * Register an exception handler for the CPU. The CPU interrupt controller must be initialized
+ * before this function is called.
+ *
+ * @param cpu The CPU device handle
+ * @param ecode The exception code to register a handler for
+ * @param handler Callback function for the exception handler
+ * @return 0 upon success
+ */
+inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler)
+{ return cpu->vtable->exception_register(cpu, ecode, handler); }
+
+/*!
+ * @brief Get the length of an instruction in bytes
+ *
+ * Get the length of an instruction in bytes.
+ *
+ * On RISC-V platforms, this is useful for detecting whether an instruction is
+ * compressed (2 bytes long) or uncompressed (4 bytes long).
+ *
+ * This function is useful in conjuction with `metal_cpu_get_exception_pc()`
+ * and `metal_cpu_set_exception_pc()` in order to cause the exception handler to
+ * return execution after the faulting instruction.
+ *
+ * @param cpu The CPU device handle
+ * @param epc The address of the instruction to measure
+ * @return the length of the instruction in bytes
+ */
+inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc)
+{ return cpu->vtable->get_ilen(cpu, epc); }
+
+/*!
+ * @brief Get the program counter of the current exception.
+ *
+ * This function must be called within an exception handler. The behavior is
+ * undefined outside of an exception handler.
+ *
+ * @param cpu The CPU device handle
+ * @return The value of the program counter at the time of the exception
+ */
+inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu)
+{ return cpu->vtable->get_epc(cpu); }
+
+/*!
+ * @brief Set the exception program counter
+ *
+ * This function must be called within an exception handler. The behavior
+ * is undefined outside of an exception handler.
+ *
+ * This function can be used to cause an exception handler to return execution
+ * to an address other than the one that caused the exception.
+ *
+ * @param cpu the CPU device handle
+ * @param epc The address to set the exception program counter to
+ * @return 0 upon success
+ */
+inline int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc)
+{ return cpu->vtable->set_epc(cpu, epc); }
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h
new file mode 100644
index 000000000..2647c5981
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__FIXED_CLOCK_H
+#define METAL__DRIVERS__FIXED_CLOCK_H
+
+struct __metal_driver_fixed_clock;
+
+#include <metal/compiler.h>
+#include <metal/clock.h>
+
+struct __metal_driver_vtable_fixed_clock {
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_clock)
+
+struct __metal_driver_fixed_clock {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h
new file mode 100644
index 000000000..936ce8d77
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__FIXED_FACTOR_CLOCK_H
+#define METAL__DRIVERS__FIXED_FACTOR_CLOCK_H
+
+struct __metal_driver_fixed_factor_clock;
+
+#include <metal/compiler.h>
+#include <metal/clock.h>
+
+struct __metal_driver_vtable_fixed_factor_clock {
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_factor_clock)
+
+struct __metal_driver_fixed_factor_clock {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h
new file mode 100644
index 000000000..08d571e1c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h
@@ -0,0 +1,24 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__RISCV_CLINT0_H
+#define METAL__DRIVERS__RISCV_CLINT0_H
+
+#include <metal/compiler.h>
+#include <metal/drivers/riscv_cpu.h>
+
+struct __metal_driver_vtable_riscv_clint0 {
+ struct metal_interrupt_vtable clint_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_clint0)
+
+#define __METAL_MACHINE_MACROS
+#include <metal/machine.h>
+struct __metal_driver_riscv_clint0 {
+ struct metal_interrupt controller;
+ int init_done;
+};
+#undef __METAL_MACHINE_MACROS
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h
new file mode 100644
index 000000000..eb1e5b8ca
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h
@@ -0,0 +1,203 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__RISCV_CPU_H
+#define METAL__DRIVERS__RISCV_CPU_H
+
+#include <stdint.h>
+#include <metal/cpu.h>
+#include <metal/compiler.h>
+
+#define METAL_MAX_CORES 8
+#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */
+#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */
+#define METAL_DEFAULT_RTC_FREQ 32768
+
+#define METAL_DISABLE 0
+#define METAL_ENABLE 1
+
+#define METAL_ISA_A_EXTENSIONS 0x0001
+#define METAL_ISA_C_EXTENSIONS 0x0004
+#define METAL_ISA_D_EXTENSIONS 0x0008
+#define METAL_ISA_E_EXTENSIONS 0x0010
+#define METAL_ISA_F_EXTENSIONS 0x0020
+#define METAL_ISA_G_EXTENSIONS 0x0040
+#define METAL_ISA_I_EXTENSIONS 0x0100
+#define METAL_ISA_M_EXTENSIONS 0x1000
+#define METAL_ISA_N_EXTENSIONS 0x2000
+#define METAL_ISA_Q_EXTENSIONS 0x10000
+#define METAL_ISA_S_EXTENSIONS 0x40000
+#define METAL_ISA_U_EXTENSIONS 0x100000
+#define METAL_ISA_V_EXTENSIONS 0x200000
+#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL
+#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL
+#define METAL_ISA_XL128_EXTENSIONS 0xC000000000000000UL
+
+#define METAL_MTVEC_DIRECT 0x00
+#define METAL_MTVEC_VECTORED 0x01
+#define METAL_MTVEC_CLIC 0x02
+#define METAL_MTVEC_CLIC_VECTORED 0x03
+#define METAL_MTVEC_CLIC_RESERVED 0x3C
+#define METAL_MTVEC_MASK 0x3F
+#if __riscv_xlen == 32
+#define METAL_MCAUSE_INTR 0x80000000UL
+#define METAL_MCAUSE_CAUSE 0x000003FFUL
+#else
+#define METAL_MCAUSE_INTR 0x8000000000000000UL
+#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL
+#endif
+#define METAL_MCAUSE_MINHV 0x40000000UL
+#define METAL_MCAUSE_MPP 0x30000000UL
+#define METAL_MCAUSE_MPIE 0x08000000UL
+#define METAL_MCAUSE_MPIL 0x00FF0000UL
+#define METAL_MSTATUS_MIE 0x00000008UL
+#define METAL_MSTATUS_MPIE 0x00000080UL
+#define METAL_MSTATUS_MPP 0x00001800UL
+#define METAL_MSTATUS_FS_INIT 0x00002000UL
+#define METAL_MSTATUS_FS_CLEAN 0x00004000UL
+#define METAL_MSTATUS_FS_DIRTY 0x00006000UL
+#define METAL_MSTATUS_MPRV 0x00020000UL
+#define METAL_MSTATUS_MXR 0x00080000UL
+#define METAL_MINTSTATUS_MIL 0xFF000000UL
+#define METAL_MINTSTATUS_SIL 0x0000FF00UL
+#define METAL_MINTSTATUS_UIL 0x000000FFUL
+
+#define METAL_LOCAL_INTR(X) (16 + X)
+#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR)
+#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0)
+#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1)
+#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3)
+#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7)
+#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11)
+#define METAL_LOCAL_INTR_EXCEPTION(X) (METAL_MCAUSE_INTR + METAL_LOCAL_INTR(X))
+#define METAL_LOCAL_INTR_RESERVE0 1
+#define METAL_LOCAL_INTR_RESERVE1 2
+#define METAL_LOCAL_INTR_RESERVE2 4
+#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */
+#define METAL_LOCAL_INTR_RESERVE4 16
+#define METAL_LOCAL_INTR_RESERVE5 32
+#define METAL_LOCAL_INTR_RESERVE6 64
+#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */
+#define METAL_LOCAL_INTR_RESERVE8 256
+#define METAL_LOCAL_INTR_RESERVE9 512
+#define METAL_LOCAL_INTR_RESERVE10 1024
+#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */
+/* Bit12 to Bit15 are Reserved */
+#define METAL_LOCAL_INTERRUPT(X) (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */
+#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE
+
+typedef enum {
+ METAL_MACHINE_PRIVILEGE_MODE,
+ METAL_SUPERVISOR_PRIVILEGE_MODE,
+ METAL_USER_PRIVILEGE_MODE,
+} metal_privilege_mode_e;
+
+typedef enum {
+ METAL_INTERRUPT_ID_BASE,
+ METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3),
+ METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7),
+ METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11),
+ METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)),
+ METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)),
+ METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)),
+ METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)),
+ METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)),
+ METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)),
+ METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)),
+ METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)),
+ METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)),
+ METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)),
+ METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)),
+ METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)),
+ METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)),
+ METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)),
+ METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)),
+ METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)),
+ METAL_INTERRUPT_ID_LCMX,
+ METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX,
+ METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1),
+} metal_interrupt_id_e;
+
+typedef enum {
+ METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */
+ METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */
+ METAL_II_EXCEPTION_CODE, /* Illegal instruction */
+ METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */
+ METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */
+ METAL_LAF_EXCEPTION_CODE, /* Load access fault */
+ METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */
+ METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */
+ METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */
+ METAL_R9_EXCEPTION_CODE, /* Reserved */
+ METAL_R10_EXCEPTION_CODE, /* Reserved */
+ METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */
+ METAL_MAX_EXCEPTION_CODE,
+} metal_exception_code_e;
+
+typedef enum {
+ METAL_TIMER_MTIME_GET = 1,
+ METAL_SOFTWARE_IPI_CLEAR,
+ METAL_SOFTWARE_IPI_SET,
+ METAL_SOFTWARE_MSIP_GET,
+ METAL_MAX_INTERRUPT_GET,
+ METAL_INDEX_INTERRUPT_GET,
+} metal_interrup_cmd_e;
+
+typedef struct __metal_interrupt_data {
+ long long pad : 64;
+ metal_interrupt_handler_t handler;
+ void *sub_int;
+ void *exint_data;
+} __metal_interrupt_data;
+
+/* CPU interrupt controller */
+
+uintptr_t __metal_myhart_id(void);
+
+struct __metal_driver_interrupt_controller_vtable {
+ void (*interrupt_init)(struct metal_interrupt *controller);
+ int (*interrupt_register)(struct metal_interrupt *controller,
+ int id, metal_interrupt_handler_t isr, void *priv_data);
+ int (*interrupt_enable)(struct metal_interrupt *controller, int id);
+ int (*interrupt_disable)(struct metal_interrupt *controller, int id);
+ int (*command_request)(struct metal_interrupt *intr, int cmd, void *data);
+};
+
+struct __metal_driver_vtable_riscv_cpu_intc {
+ struct metal_interrupt_vtable controller_vtable;
+};
+
+
+void __metal_interrupt_global_enable(void);
+void __metal_interrupt_global_disable(void);
+void __metal_controller_interrupt_vector(metal_vector_mode mode, void *vec_table);
+inline int __metal_controller_interrupt_is_selective_vectored (void)
+{
+ uintptr_t val;
+
+ asm volatile ("csrr %0, mtvec" : "=r"(val));
+ return ((val & METAL_MTVEC_CLIC_VECTORED) == METAL_MTVEC_CLIC);
+}
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc)
+
+struct __metal_driver_riscv_cpu_intc {
+ struct metal_interrupt controller;
+ int init_done;
+ uintptr_t metal_mtvec_table[METAL_MAX_MI];
+ __metal_interrupt_data metal_int_table[METAL_MAX_MI];
+ metal_exception_handler_t metal_exception_table[METAL_MAX_ME];
+};
+
+/* CPU driver*/
+struct __metal_driver_vtable_cpu {
+ struct metal_cpu_vtable cpu_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu)
+
+struct __metal_driver_cpu {
+ struct metal_cpu cpu;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h
new file mode 100644
index 000000000..159ee6d69
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h
@@ -0,0 +1,31 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__RISCV_PLIC0_H
+#define METAL__DRIVERS__RISCV_PLIC0_H
+
+#include <metal/compiler.h>
+#include <metal/drivers/riscv_cpu.h>
+
+#define METAL_PLIC_SOURCE_MASK 0x1F
+#define METAL_PLIC_SOURCE_SHIFT 5
+#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2
+#define METAL_PLIC_SOURCE_PENDING_SHIFT 0
+
+struct __metal_driver_vtable_riscv_plic0 {
+ struct metal_interrupt_vtable plic_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_plic0)
+
+#define __METAL_MACHINE_MACROS
+#include <metal/machine.h>
+struct __metal_driver_riscv_plic0 {
+ struct metal_interrupt controller;
+ int init_done;
+ metal_interrupt_handler_t metal_exint_table[__METAL_PLIC_SUBINTERRUPTS];
+ __metal_interrupt_data metal_exdata_table[__METAL_PLIC_SUBINTERRUPTS];
+};
+#undef __METAL_MACHINE_MACROS
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h
new file mode 100644
index 000000000..db9674625
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h
@@ -0,0 +1,42 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_CLIC0_H
+#define METAL__DRIVERS__SIFIVE_CLIC0_H
+
+#include <metal/compiler.h>
+#include <metal/drivers/riscv_cpu.h>
+
+#define METAL_CLIC_MAX_NMBITS 2
+#define METAL_CLIC_MAX_NLBITS 8
+#define METAL_CLIC_MAX_NVBITS 1
+
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60
+#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E
+#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01
+
+#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */
+#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */
+
+#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1)
+
+struct __metal_driver_vtable_sifive_clic0 {
+ struct metal_interrupt_vtable clic_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0)
+
+#define __METAL_MACHINE_MACROS
+#include <metal/machine.h>
+struct __metal_driver_sifive_clic0 {
+ struct metal_interrupt controller;
+ int init_done;
+ metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS];
+ __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS];
+};
+#undef __METAL_MACHINE_MACROS
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h
new file mode 100644
index 000000000..d311f0cf2
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H
+#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H
+
+#include <metal/drivers/sifive_fe310-g000_prci.h>
+#include <metal/compiler.h>
+#include <metal/clock.h>
+#include <metal/io.h>
+
+struct __metal_driver_vtable_sifive_fe310_g000_hfrosc {
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc)
+
+struct __metal_driver_sifive_fe310_g000_hfrosc {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h
new file mode 100644
index 000000000..b86926fba
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h
@@ -0,0 +1,20 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H
+#define METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H
+
+#include <metal/clock.h>
+#include <metal/drivers/sifive_fe310-g000_prci.h>
+
+struct __metal_driver_vtable_sifive_fe310_g000_hfxosc {
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc)
+
+struct __metal_driver_sifive_fe310_g000_hfxosc {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h
new file mode 100644
index 000000000..67f818f7b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h
@@ -0,0 +1,26 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#include <metal/machine/platform.h>
+
+#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H
+#define METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H
+
+struct __metal_driver_sifive_fe310_g000_pll;
+
+#include <metal/clock.h>
+#include <metal/drivers/sifive_fe310-g000_prci.h>
+#include <metal/machine.h>
+
+struct __metal_driver_vtable_sifive_fe310_g000_pll {
+ void (*init)(struct __metal_driver_sifive_fe310_g000_pll *pll);
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll)
+
+struct __metal_driver_sifive_fe310_g000_pll {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h
new file mode 100644
index 000000000..87c9ca985
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h
@@ -0,0 +1,23 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H
+#define METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H
+
+#include <metal/compiler.h>
+#include <metal/io.h>
+
+struct __metal_driver_sifive_fe310_g000_prci;
+
+struct __metal_driver_vtable_sifive_fe310_g000_prci {
+ long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset);
+ long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset, long value);
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci)
+
+struct __metal_driver_sifive_fe310_g000_prci {
+};
+
+#endif
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h
new file mode 100644
index 000000000..8c3cf907e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h
@@ -0,0 +1,23 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_FU540_C000_L2_H
+#define METAL__DRIVERS__SIFIVE_FU540_C000_L2_H
+
+struct __metal_driver_sifive_fu540_c000_l2;
+
+#include <stdint.h>
+#include <metal/cache.h>
+
+struct __metal_driver_vtable_sifive_fu540_c000_l2 {
+ struct __metal_cache_vtable cache;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2)
+
+struct __metal_driver_sifive_fu540_c000_l2 {
+ struct metal_cache cache;
+};
+
+#endif
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h
new file mode 100644
index 000000000..9e6f2faf6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H
+#define METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H
+
+#include <metal/compiler.h>
+#include <metal/drivers/riscv_cpu.h>
+
+struct __metal_driver_vtable_sifive_global_external_interrupts0 {
+ struct metal_interrupt_vtable global0_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0)
+
+struct __metal_driver_sifive_global_external_interrupts0 {
+ struct metal_interrupt irc;
+ int init_done;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h
new file mode 100644
index 000000000..a0caeaba8
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H
+#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H
+
+#include <string.h>
+#include <metal/button.h>
+#include <metal/compiler.h>
+
+struct __metal_driver_vtable_sifive_button {
+ struct metal_button_vtable button_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button)
+
+struct __metal_driver_sifive_gpio_button {
+ struct metal_button button;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h
new file mode 100644
index 000000000..a8dacf116
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H
+#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H
+
+#include <metal/drivers/sifive_gpio0.h>
+#include <metal/led.h>
+#include <metal/compiler.h>
+
+struct __metal_driver_vtable_sifive_led {
+ struct metal_led_vtable led_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led)
+
+struct __metal_driver_sifive_gpio_led {
+ struct metal_led led;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h
new file mode 100644
index 000000000..c9c7839e9
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H
+#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H
+
+#include <metal/drivers/sifive_gpio0.h>
+#include <metal/switch.h>
+#include <metal/compiler.h>
+
+struct __metal_driver_vtable_sifive_switch {
+ struct metal_switch_vtable switch_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch)
+
+struct __metal_driver_sifive_gpio_switch {
+ struct metal_switch flip;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h
new file mode 100644
index 000000000..cc56dc722
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_GPIO0_H
+#define METAL__DRIVERS__SIFIVE_GPIO0_H
+
+#include <metal/compiler.h>
+#include <metal/gpio.h>
+
+struct __metal_driver_vtable_sifive_gpio0 {
+ const struct __metal_gpio_vtable gpio;
+};
+
+//struct __metal_driver_sifive_gpio0;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0)
+
+struct __metal_driver_sifive_gpio0 {
+ struct metal_gpio gpio;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h
new file mode 100644
index 000000000..aa8d63078
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H
+#define METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H
+
+#include <metal/compiler.h>
+#include <metal/drivers/riscv_cpu.h>
+
+struct __metal_driver_vtable_sifive_local_external_interrupts0 {
+ struct metal_interrupt_vtable local0_vtable;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0)
+
+struct __metal_driver_sifive_local_external_interrupts0 {
+ struct metal_interrupt irc;
+ int init_done;
+};
+
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h
new file mode 100644
index 000000000..90d4c831e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h
@@ -0,0 +1,24 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_SPI0_H
+#define METAL__DRIVERS__SIFIVE_SPI0_H
+
+#include <metal/drivers/sifive_gpio0.h>
+#include <metal/clock.h>
+#include <metal/compiler.h>
+#include <metal/io.h>
+#include <metal/spi.h>
+
+struct __metal_driver_vtable_sifive_spi0 {
+ const struct metal_spi_vtable spi;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0)
+
+struct __metal_driver_sifive_spi0 {
+ struct metal_spi spi;
+ unsigned long baud_rate;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h
new file mode 100644
index 000000000..e87db2c83
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_TEST0_H
+#define METAL__DRIVERS__SIFIVE_TEST0_H
+
+#include <metal/compiler.h>
+#include <metal/shutdown.h>
+
+struct __metal_driver_vtable_sifive_test0 {
+ const struct __metal_shutdown_vtable shutdown;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_test0)
+
+struct __metal_driver_sifive_test0 {
+ struct __metal_shutdown shutdown;
+};
+
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h
new file mode 100644
index 000000000..11d954002
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h
@@ -0,0 +1,28 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_UART0_H
+#define METAL__DRIVERS__SIFIVE_UART0_H
+
+#include <metal/drivers/sifive_gpio0.h>
+#include <metal/drivers/riscv_plic0.h>
+#include <metal/clock.h>
+#include <metal/io.h>
+#include <metal/uart.h>
+#include <metal/compiler.h>
+
+struct __metal_driver_vtable_sifive_uart0 {
+ const struct metal_uart_vtable uart;
+};
+
+struct __metal_driver_sifive_uart0;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0)
+
+struct __metal_driver_sifive_uart0 {
+ struct metal_uart uart;
+ unsigned long baud_rate;
+};
+
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h
new file mode 100644
index 000000000..513687dd7
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h
@@ -0,0 +1,151 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__GPIO_H
+#define METAL__GPIO_H
+
+#include <metal/compiler.h>
+
+/*!
+ * @file gpio.h
+ * @brief API for manipulating general-purpose input/output
+ */
+
+struct metal_gpio;
+
+struct __metal_gpio_vtable {
+ int (*disable_input)(struct metal_gpio *, long pins);
+ long (*output)(struct metal_gpio *);
+ int (*enable_output)(struct metal_gpio *, long pins);
+ int (*output_set)(struct metal_gpio *, long value);
+ int (*output_clear)(struct metal_gpio *, long value);
+ int (*output_toggle)(struct metal_gpio *, long value);
+ int (*enable_io)(struct metal_gpio *, long pins, long dest);
+};
+
+/*!
+ * @struct metal_gpio
+ * @brief The handle for a GPIO interface
+ */
+struct metal_gpio {
+ const struct __metal_gpio_vtable *vtable;
+};
+
+/*!
+ * @brief Get a GPIO device handle
+ * @param device_num The GPIO device index
+ * @return The GPIO device handle, or NULL if there is no device at that index
+ */
+struct metal_gpio *metal_gpio_get_device(int device_num);
+
+/*!
+ * @brief Disable input on a pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the input is successfully disabled
+ */
+inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
+ if(!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->disable_input(gpio, (1 << pin));
+}
+
+/*!
+ * @brief Enable output on a pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the output is successfully enabled
+ */
+inline int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
+ if(!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->enable_output(gpio, (1 << pin));
+}
+
+/*!
+ * @brief Set the output value of a GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @param value The value to set the pin to
+ * @return 0 if the output is successfully set
+ */
+inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
+ if(!gpio) {
+ return 1;
+ }
+
+ if(value == 0) {
+ return gpio->vtable->output_clear(gpio, (1 << pin));
+ } else {
+ return gpio->vtable->output_set(gpio, (1 << pin));
+ }
+}
+
+/*!
+ * @brief Get the value of the GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return The value of the GPIO pin
+ */
+inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) {
+ if(!gpio) {
+ return 0;
+ }
+
+ long value = gpio->vtable->output(gpio);
+
+ if(value & (1 << pin)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ * @brief Clears the value of the GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the pin is successfully cleared
+ */
+inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
+ if(!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->output_clear(gpio, (1 << pin));
+}
+
+/*!
+ * @brief Toggles the value of the GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the pin is successfully toggled
+ */
+inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
+ if(!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->output_toggle(gpio, (1 << pin));
+}
+
+/*!
+ * @brief Enables and sets the pinmux for a GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The bitmask for the pin to enable pinmux on
+ * @param io_function The IO function to set
+ * @return 0 if the pinmux is successfully set
+ */
+inline int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) {
+ if(!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin));
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h
new file mode 100644
index 000000000..43f587aca
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h
@@ -0,0 +1,134 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__INTERRUPT_H
+#define METAL__INTERRUPT_H
+
+/*! @file interrupt.h
+ * @brief API for registering and manipulating interrupts
+ */
+
+#include <stddef.h>
+
+/*!
+ * @brief Possible mode of interrupts to operate
+ */
+typedef enum metal_vector_mode_ {
+ METAL_DIRECT_MODE = 0,
+ METAL_VECTOR_MODE = 1,
+ METAL_SELECTIVE_VECTOR_MODE = 2,
+ METAL_HARDWARE_VECTOR_MODE = 3
+} metal_vector_mode;
+
+/*!
+ * @brief Function signature for interrupt callback handlers
+ */
+typedef void (*metal_interrupt_handler_t) (int, void *);
+
+struct metal_interrupt;
+
+struct metal_interrupt_vtable {
+ void (*interrupt_init)(struct metal_interrupt *controller);
+ int (*interrupt_register)(struct metal_interrupt *controller, int id,
+ metal_interrupt_handler_t isr, void *priv_data);
+ int (*interrupt_enable)(struct metal_interrupt *controller, int id);
+ int (*interrupt_disable)(struct metal_interrupt *controller, int id);
+ int (*interrupt_vector_enable)(struct metal_interrupt *controller,
+ int id, metal_vector_mode mode);
+ int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id);
+ int (*command_request)(struct metal_interrupt *controller, int cmd, void *data);
+ int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time);
+};
+
+/*!
+ * @brief A handle for an interrupt
+ */
+struct metal_interrupt {
+ const struct metal_interrupt_vtable *vtable;
+};
+
+/*!
+ * @brief Initialize a given interrupt controller
+ *
+ * Initialize a given interrupt controller. This function must be called
+ * before any interrupts are registered or enabled with the handler. It
+ * is invalid to initialize an interrupt controller more than once.
+ *
+ * @param controller The handle for the interrupt controller
+ */
+inline void metal_interrupt_init(struct metal_interrupt *controller)
+{
+ return controller->vtable->interrupt_init(controller);
+}
+
+
+/*!
+ * @brief Register an interrupt handler
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to register
+ * @param handler The interrupt handler callback
+ * @param priv_data Private data for the interrupt handler
+ * @return 0 upon success
+ */
+inline int metal_interrupt_register_handler(struct metal_interrupt *controller,
+ int id,
+ metal_interrupt_handler_t handler,
+ void *priv_data)
+{
+ return controller->vtable->interrupt_register(controller, id, handler, priv_data);
+}
+
+/*!
+ * @brief Enable an interrupt
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @return 0 upon success
+ */
+inline int metal_interrupt_enable(struct metal_interrupt *controller, int id)
+{
+ return controller->vtable->interrupt_enable(controller, id);
+}
+
+/*!
+ * @brief Disable an interrupt
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to disable
+ * @return 0 upon success
+ */
+inline int metal_interrupt_disable(struct metal_interrupt *controller, int id)
+{
+ return controller->vtable->interrupt_disable(controller, id);
+}
+
+/*!
+ * @brief Enable an interrupt vector
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @param mode The interrupt mode type to enable
+ * @return 0 upon success
+ */
+inline int metal_interrupt_vector_enable(struct metal_interrupt *controller,
+ int id, metal_vector_mode mode)
+{
+ return controller->vtable->interrupt_vector_enable(controller, id, mode);
+}
+
+/*!
+ * @brief Disable an interrupt vector
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to disable
+ * @return 0 upon success
+ */
+inline int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id)
+{
+ return controller->vtable->interrupt_vector_disable(controller, id);
+}
+
+/* Utilities function to controll, manages devices via a given interrupt controller */
+inline int _metal_interrupt_command_request(struct metal_interrupt *controller,
+ int cmd, void *data)
+{
+ return controller->vtable->command_request(controller, cmd, data);
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h
new file mode 100644
index 000000000..450054142
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h
@@ -0,0 +1,22 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__IO_H
+#define METAL__IO_H
+
+/* This macro enforces that the compiler will not elide the given access. */
+#define __METAL_ACCESS_ONCE(x) (*(typeof(*x) volatile *)(x))
+
+/* Allows users to specify arbitrary fences. */
+#define __METAL_IO_FENCE(pred, succ) __asm__ volatile ("fence " #pred "," #succ ::: "memory");
+
+/* Types that explicitly describe an address as being used for memory-mapped
+ * IO. These should only be accessed via __METAL_ACCESS_ONCE. */
+typedef unsigned char __metal_io_u8;
+typedef unsigned short __metal_io_u16;
+typedef unsigned int __metal_io_u32;
+#if __riscv_xlen >= 64
+typedef unsigned long __metal_io_u64;
+#endif
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h
new file mode 100644
index 000000000..1a2a05b8b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__ITIM_H
+#define METAL__ITIM_H
+
+/*! @file itim.h
+ *
+ * API for manipulating ITIM allocation
+ */
+
+
+/*! @def METAL_PLACE_IN_ITIM
+ * @brief Link a function into the ITIM
+ *
+ * Link a function into the ITIM (Instruction Tightly Integrated
+ * Memory) if the ITIM is present on the target device.
+ */
+#define METAL_PLACE_IN_ITIM __attribute__((section(".itim")))
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h
new file mode 100644
index 000000000..a430b84c2
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h
@@ -0,0 +1,68 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__LED_H
+#define METAL__LED_H
+
+/*!
+ * @file led.h
+ * @brief API for manipulating LEDs
+ */
+
+struct metal_led;
+
+struct metal_led_vtable {
+ int (*led_exist)(struct metal_led *led, char *label);
+ void (*led_enable)(struct metal_led *led);
+ void (*led_on)(struct metal_led *led);
+ void (*led_off)(struct metal_led *led);
+ void (*led_toggle)(struct metal_led *led);
+};
+
+/*!
+ * @brief A handle for an LED
+ */
+struct metal_led {
+ const struct metal_led_vtable *vtable;
+};
+
+/*!
+ * @brief Get a handle for an LED
+ * @param label The DeviceTree label for the desired LED
+ * @return A handle to the LED, or NULL if none is found for the requested label
+ */
+struct metal_led* metal_led_get(char *label);
+
+/*!
+ * @brief Get a handle for a channel of an RGB LED
+ * @param label The DeviceTree label for the desired LED
+ * @param color The color for the LED in the DeviceTree
+ * @return A handle to the LED, or NULL if none is found for the requested label and color
+ */
+struct metal_led* metal_led_get_rgb(char *label, char *color);
+
+/*!
+ * @brief Enable an LED
+ * @param led The handle for the LED
+ */
+inline void metal_led_enable(struct metal_led *led) { led->vtable->led_enable(led); }
+
+/*!
+ * @brief Turn an LED on
+ * @param led The handle for the LED
+ */
+inline void metal_led_on(struct metal_led *led) { led->vtable->led_on(led); }
+
+/*!
+ * @brief Turn an LED off
+ * @param led The handle for the LED
+ */
+inline void metal_led_off(struct metal_led *led) { led->vtable->led_off(led); }
+
+/*!
+ * @brief Toggle the on/off state of an LED
+ * @param led The handle for the LED
+ */
+inline void metal_led_toggle(struct metal_led *led) { led->vtable->led_toggle(led); }
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h
new file mode 100644
index 000000000..d863aa96e
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h
@@ -0,0 +1,127 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__LOCK_H
+#define METAL__LOCK_H
+
+#include <metal/memory.h>
+#include <metal/compiler.h>
+
+/*!
+ * @file lock.h
+ * @brief An API for creating and using a software lock/mutex
+ */
+
+/* TODO: How can we make the exception code platform-independant? */
+#define _METAL_STORE_AMO_ACCESS_FAULT 7
+
+/*!
+ * @def METAL_LOCK_DECLARE
+ * @brief Declare a lock
+ *
+ * Locks must be declared with METAL_LOCK_DECLARE to ensure that the lock
+ * is linked into a memory region which supports atomic memory operations.
+ */
+#define METAL_LOCK_DECLARE(name) \
+ __attribute__((section(".data.locks"))) \
+ struct metal_lock name
+
+/*!
+ * @brief A handle for a lock
+ */
+struct metal_lock {
+ int _state;
+};
+
+/*!
+ * @brief Initialize a lock
+ * @param lock The handle for a lock
+ * @return 0 if the lock is successfully initialized. A non-zero code indicates failure.
+ *
+ * If the lock cannot be initialized, attempts to take or give the lock
+ * will result in a Store/AMO access fault.
+ */
+inline int metal_lock_init(struct metal_lock *lock) {
+#ifdef __riscv_atomic
+ /* Get a handle for the memory which holds the lock state */
+ struct metal_memory *lock_mem = metal_get_memory_from_address((uintptr_t) &(lock->_state));
+ if(!lock_mem) {
+ return 1;
+ }
+
+ /* If the memory doesn't support atomics, report an error */
+ if(!metal_memory_supports_atomics(lock_mem)) {
+ return 2;
+ }
+
+ lock->_state = 0;
+
+ return 0;
+#else
+ return 3;
+#endif
+}
+
+/*!
+ * @brief Take a lock
+ * @param lock The handle for a lock
+ * @return 0 if the lock is successfully taken
+ *
+ * If the lock initialization failed, attempts to take a lock will result in
+ * a Store/AMO access fault.
+ */
+inline int metal_lock_take(struct metal_lock *lock) {
+#ifdef __riscv_atomic
+ int old = 1;
+ int new = 1;
+
+ while(old != 0) {
+ __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])"
+ : [old] "=r" (old)
+ : [new] "r" (new), [state] "r" (&(lock->_state))
+ : "memory");
+ }
+
+ return 0;
+#else
+ /* Store the memory address in mtval like a normal store/amo access fault */
+ __asm__ ("csrw mtval, %[state]"
+ :: [state] "r" (&(lock->_state)));
+
+ /* Trigger a Store/AMO access fault */
+ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT);
+
+ /* If execution returns, indicate failure */
+ return 1;
+#endif
+}
+
+/*!
+ * @brief Give back a held lock
+ * @param lock The handle for a lock
+ * @return 0 if the lock is successfully given
+ *
+ * If the lock initialization failed, attempts to give a lock will result in
+ * a Store/AMO access fault.
+ */
+inline int metal_lock_give(struct metal_lock *lock) {
+#ifdef __riscv_atomic
+ __asm__ volatile("amoswap.w.rl x0, x0, (%[state])"
+ :: [state] "r" (&(lock->_state))
+ : "memory");
+
+ return 0;
+#else
+ /* Store the memory address in mtval like a normal store/amo access fault */
+ __asm__ ("csrw mtval, %[state]"
+ :: [state] "r" (&(lock->_state)));
+
+ /* Trigger a Store/AMO access fault */
+ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT);
+
+ /* If execution returns, indicate failure */
+ return 1;
+#endif
+}
+
+#endif /* METAL__LOCK_H */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h
new file mode 100644
index 000000000..f76dbd632
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h
@@ -0,0 +1,872 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef ASSEMBLY
+
+#include <metal/machine/platform.h>
+
+#ifdef __METAL_MACHINE_MACROS
+
+#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
+#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
+
+#define __METAL_CLINT_NUM_PARENTS 2
+
+#ifndef __METAL_CLINT_NUM_PARENTS
+#define __METAL_CLINT_NUM_PARENTS 0
+#endif
+#define __METAL_PLIC_SUBINTERRUPTS 27
+
+#define __METAL_PLIC_NUM_PARENTS 1
+
+#ifndef __METAL_PLIC_SUBINTERRUPTS
+#define __METAL_PLIC_SUBINTERRUPTS 0
+#endif
+#ifndef __METAL_PLIC_NUM_PARENTS
+#define __METAL_PLIC_NUM_PARENTS 0
+#endif
+#ifndef __METAL_CLIC_SUBINTERRUPTS
+#define __METAL_CLIC_SUBINTERRUPTS 0
+#endif
+
+#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/
+
+#else /* ! __METAL_MACHINE_MACROS */
+
+#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
+#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
+
+#define __METAL_CLINT_2000000_INTERRUPTS 2
+
+#define METAL_MAX_CLINT_INTERRUPTS 2
+
+#define __METAL_CLINT_NUM_PARENTS 2
+
+#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1
+
+#define __METAL_PLIC_SUBINTERRUPTS 27
+
+#define METAL_MAX_PLIC_INTERRUPTS 1
+
+#define __METAL_PLIC_NUM_PARENTS 1
+
+#define __METAL_CLIC_SUBINTERRUPTS 0
+#define METAL_MAX_CLIC_INTERRUPTS 0
+
+#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16
+
+#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16
+
+#define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0
+
+#define __METAL_GPIO_10012000_INTERRUPTS 16
+
+#define METAL_MAX_GPIO_INTERRUPTS 16
+
+#define __METAL_SERIAL_10013000_INTERRUPTS 1
+
+#define METAL_MAX_UART_INTERRUPTS 1
+
+
+#include <metal/drivers/fixed-clock.h>
+#include <metal/memory.h>
+#include <metal/drivers/riscv_clint0.h>
+#include <metal/drivers/riscv_cpu.h>
+#include <metal/drivers/riscv_plic0.h>
+#include <metal/pmp.h>
+#include <metal/drivers/sifive_local-external-interrupts0.h>
+#include <metal/drivers/sifive_gpio0.h>
+#include <metal/drivers/sifive_gpio-leds.h>
+#include <metal/drivers/sifive_spi0.h>
+#include <metal/drivers/sifive_uart0.h>
+#include <metal/drivers/sifive_fe310-g000_hfrosc.h>
+#include <metal/drivers/sifive_fe310-g000_hfxosc.h>
+#include <metal/drivers/sifive_fe310-g000_pll.h>
+#include <metal/drivers/sifive_fe310-g000_prci.h>
+
+/* From clock@0 */
+struct __metal_driver_fixed_clock __metal_dt_clock_0;
+
+/* From clock@2 */
+struct __metal_driver_fixed_clock __metal_dt_clock_2;
+
+/* From clock@5 */
+struct __metal_driver_fixed_clock __metal_dt_clock_5;
+
+struct metal_memory __metal_dt_mem_dtim_80000000;
+
+struct metal_memory __metal_dt_mem_spi_10014000;
+
+/* From clint@2000000 */
+struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
+
+/* From cpu@0 */
+struct __metal_driver_cpu __metal_dt_cpu_0;
+
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
+
+/* From interrupt_controller@c000000 */
+struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
+
+struct metal_pmp __metal_dt_pmp;
+
+/* From local_external_interrupts_0 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0;
+
+/* From gpio@10012000 */
+struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000;
+
+/* From led@0red */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0red;
+
+/* From led@0green */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0green;
+
+/* From led@0blue */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue;
+
+/* From spi@10014000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000;
+
+/* From serial@10013000 */
+struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000;
+
+/* From clock@3 */
+struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3;
+
+/* From clock@1 */
+struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1;
+
+/* From clock@4 */
+struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4;
+
+/* From prci@10008000 */
+struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000;
+
+
+
+/* --------------------- fixed_clock ------------ */
+static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) {
+ return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY;
+ }
+ else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) {
+ return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY;
+ }
+ else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) {
+ return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- fixed_factor_clock ------------ */
+
+
+/* --------------------- sifive_clint0 ------------ */
+static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_RISCV_CLINT0_2000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_MAX_CLINT_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 1) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 3;
+ }
+ else if (idx == 1) {
+ return 7;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- cpu ------------ */
+static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 1000000;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return &__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 8;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_plic0 ------------ */
+static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_RISCV_NDEV;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 11;
+ }
+ else if (idx == 0) {
+ return 11;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_clic0 ------------ */
+
+
+/* --------------------- sifive_local_external_interrupts0 ------------ */
+static inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
+ return METAL_MAX_LOCAL_EXT_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 16;
+ }
+ else if (idx == 1) {
+ return 17;
+ }
+ else if (idx == 2) {
+ return 18;
+ }
+ else if (idx == 3) {
+ return 19;
+ }
+ else if (idx == 4) {
+ return 20;
+ }
+ else if (idx == 5) {
+ return 21;
+ }
+ else if (idx == 6) {
+ return 22;
+ }
+ else if (idx == 7) {
+ return 23;
+ }
+ else if (idx == 8) {
+ return 24;
+ }
+ else if (idx == 9) {
+ return 25;
+ }
+ else if (idx == 10) {
+ return 26;
+ }
+ else if (idx == 11) {
+ return 27;
+ }
+ else if (idx == 12) {
+ return 28;
+ }
+ else if (idx == 13) {
+ return 29;
+ }
+ else if (idx == 14) {
+ return 30;
+ }
+ else if (idx == 15) {
+ return 31;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_global_external_interrupts0 ------------ */
+
+
+/* --------------------- sifive_gpio0 ------------ */
+static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio)
+{
+ if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
+ return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio)
+{
+ if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
+ return METAL_SIFIVE_GPIO0_10012000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio)
+{
+ if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
+ return METAL_MAX_GPIO_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio)
+{
+ if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx)
+{
+ if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) {
+ return 7;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) {
+ return 8;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) {
+ return 9;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) {
+ return 10;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) {
+ return 11;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) {
+ return 12;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) {
+ return 13;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) {
+ return 14;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) {
+ return 15;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) {
+ return 16;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) {
+ return 17;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) {
+ return 18;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) {
+ return 19;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) {
+ return 20;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) {
+ return 21;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) {
+ return 22;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_gpio_button ------------ */
+
+
+/* --------------------- sifive_gpio_led ------------ */
+static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led)
+{
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ return (struct metal_gpio *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ return (struct metal_gpio *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ return (struct metal_gpio *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
+{
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ return 22;
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ return 19;
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ return 21;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
+{
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ return "LD0red";
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ return "LD0green";
+ }
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ return "LD0blue";
+ }
+ else {
+ return "";
+ }
+}
+
+
+
+/* --------------------- sifive_gpio_switch ------------ */
+
+
+/* --------------------- sifive_spi0 ------------ */
+static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi)
+{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi)
+{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return METAL_SIFIVE_SPI0_10014000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi)
+{
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+}
+
+static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi)
+{
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+}
+
+static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi)
+{
+ return 60;
+}
+
+static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi)
+{
+ return 60;
+}
+
+
+
+/* --------------------- sifive_test0 ------------ */
+
+
+/* --------------------- sifive_uart0 ------------ */
+static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return METAL_SIFIVE_UART0_10013000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return METAL_MAX_UART_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart)
+{
+ return 5;
+}
+
+static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart)
+{
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+}
+
+static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart)
+{
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+}
+
+static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart)
+{
+ return 196608;
+}
+
+static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart)
+{
+ return 196608;
+}
+
+
+
+/* --------------------- sifive_fe310_g000_hfrosc ------------ */
+static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock)
+{
+ return (struct metal_clock *)&__metal_dt_clock_2.clock;
+}
+
+static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock)
+{
+ return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
+}
+
+static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock)
+{
+ return &__metal_driver_vtable_sifive_fe310_g000_prci;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock)
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG;
+}
+
+
+
+/* --------------------- sifive_fe310_g000_hfxosc ------------ */
+static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock)
+{
+ return (struct metal_clock *)&__metal_dt_clock_0.clock;
+}
+
+static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock)
+{
+ return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock)
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG;
+}
+
+
+
+/* --------------------- sifive_fe310_g000_pll ------------ */
+static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock)
+{
+ return (struct metal_clock *)&__metal_dt_clock_3.clock;
+}
+
+static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock)
+{
+ return (struct metal_clock *)&__metal_dt_clock_1.clock;
+}
+
+static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock)
+{
+ return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock)
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV;
+}
+
+static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( )
+{
+ return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_pll_config_offset( )
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( )
+{
+ return 16000000;
+}
+
+
+
+/* --------------------- sifive_fe310_g000_prci ------------ */
+static inline long __metal_driver_sifive_fe310_g000_prci_base( )
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS;
+}
+
+static inline long __metal_driver_sifive_fe310_g000_prci_size( )
+{
+ return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE;
+}
+
+static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( )
+{
+ return &__metal_driver_vtable_sifive_fe310_g000_prci;
+}
+
+
+
+/* --------------------- sifive_fu540_c000_l2 ------------ */
+
+
+#define __METAL_DT_MAX_MEMORIES 2
+
+asm (".weak __metal_memory_table");
+struct metal_memory *__metal_memory_table[] = {
+ &__metal_dt_mem_dtim_80000000,
+ &__metal_dt_mem_spi_10014000};
+
+/* From serial@10013000 */
+#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart)
+
+#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart)
+
+#define __METAL_DT_STDOUT_UART_BAUD 115200
+
+/* From clint@2000000 */
+#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller)
+
+#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller)
+
+#define __METAL_DT_MAX_HARTS 1
+
+asm (".weak __metal_cpu_table");
+struct __metal_driver_cpu *__metal_cpu_table[] = {
+ &__metal_dt_cpu_0};
+
+/* From interrupt_controller@c000000 */
+#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller)
+
+#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller)
+
+#define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp)
+
+/* From local_external_interrupts_0 */
+#define __METAL_DT_SIFIVE_LOCAL_EXINTR0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
+
+#define __METAL_DT_LOCAL_EXTERNAL_INTERRUPTS_0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
+
+#define __MEE_DT_MAX_GPIOS 1
+
+asm (".weak __metal_gpio_table");
+struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = {
+ &__metal_dt_gpio_10012000};
+
+#define __METAL_DT_MAX_BUTTONS 0
+
+asm (".weak __metal_button_table");
+struct __metal_driver_sifive_gpio_button *__metal_button_table[] = {
+ NULL };
+#define __METAL_DT_MAX_LEDS 3
+
+asm (".weak __metal_led_table");
+struct __metal_driver_sifive_gpio_led *__metal_led_table[] = {
+ &__metal_dt_led_0red,
+ &__metal_dt_led_0green,
+ &__metal_dt_led_0blue};
+
+#define __METAL_DT_MAX_SWITCHES 0
+
+asm (".weak __metal_switch_table");
+struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = {
+ NULL };
+#define __METAL_DT_MAX_SPIS 1
+
+asm (".weak __metal_spi_table");
+struct __metal_driver_sifive_spi0 *__metal_spi_table[] = {
+ &__metal_dt_spi_10014000};
+
+/* From clock@4 */
+#define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4)
+
+#define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4)
+
+#endif /* MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H*/
+
+#endif /* ! __METAL_MACHINE_MACROS */
+
+#endif /* ! ASSEMBLY */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h
new file mode 100644
index 000000000..8c0cd048b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h
@@ -0,0 +1,249 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef ASSEMBLY
+
+#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
+#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
+
+#include <metal/machine.h>
+
+
+/* --------------------- fixed_clock ------------ */
+extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
+
+
+/* --------------------- fixed_factor_clock ------------ */
+
+
+/* --------------------- sifive_clint0 ------------ */
+extern inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
+extern inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
+extern inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
+extern inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- cpu ------------ */
+extern inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
+extern inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
+extern inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
+extern inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+
+
+/* --------------------- sifive_plic0 ------------ */
+extern inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
+extern inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
+extern inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
+extern inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
+extern inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- sifive_clic0 ------------ */
+
+
+/* --------------------- sifive_local_external_interrupts0 ------------ */
+extern inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller);
+extern inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller);
+extern inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- sifive_global_external_interrupts0 ------------ */
+
+
+/* --------------------- sifive_gpio0 ------------ */
+extern inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio);
+extern inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio);
+extern inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio);
+extern inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio);
+extern inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx);
+
+
+/* --------------------- sifive_gpio_button ------------ */
+
+
+/* --------------------- sifive_gpio_led ------------ */
+extern inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led);
+extern inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led);
+extern inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led);
+
+
+/* --------------------- sifive_gpio_switch ------------ */
+
+
+/* --------------------- sifive_spi0 ------------ */
+extern inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi);
+extern inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi);
+extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi);
+extern inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi);
+extern inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi);
+
+
+/* --------------------- sifive_test0 ------------ */
+
+
+/* --------------------- sifive_uart0 ------------ */
+extern inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart);
+extern inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart);
+extern inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart);
+extern inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart);
+extern inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart);
+extern inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart);
+extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart);
+extern inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart);
+extern inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart);
+
+
+/* --------------------- sifive_fe310_g000_hfrosc ------------ */
+extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock);
+extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock);
+extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock);
+extern inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock);
+
+
+/* --------------------- sifive_fe310_g000_hfxosc ------------ */
+extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock);
+extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock);
+extern inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock);
+
+
+/* --------------------- sifive_fe310_g000_pll ------------ */
+extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock);
+extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock);
+extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( );
+extern inline long __metal_driver_sifive_fe310_g000_pll_config_offset( );
+extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock);
+extern inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock);
+extern inline long __metal_driver_sifive_fe310_g000_pll_init_rate( );
+
+
+/* --------------------- fe310_g000_prci ------------ */
+extern inline long __metal_driver_sifive_fe310_g000_prci_base( );
+extern inline long __metal_driver_sifive_fe310_g000_prci_size( );
+extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( );
+
+
+/* --------------------- sifive_fu540_c000_l2 ------------ */
+
+
+/* From clock@0 */
+struct __metal_driver_fixed_clock __metal_dt_clock_0 = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
+/* From clock@2 */
+struct __metal_driver_fixed_clock __metal_dt_clock_2 = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
+/* From clock@5 */
+struct __metal_driver_fixed_clock __metal_dt_clock_5 = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
+struct metal_memory __metal_dt_mem_dtim_80000000 = {
+ ._base_address = 2147483648UL,
+ ._size = 16384UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+struct metal_memory __metal_dt_mem_spi_10014000 = {
+ ._base_address = 536870912UL,
+ ._size = 500000UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+/* From clint@2000000 */
+struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
+ .controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable,
+ .init_done = 0,
+};
+
+/* From cpu@0 */
+struct __metal_driver_cpu __metal_dt_cpu_0 = {
+ .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+};
+
+/* From interrupt_controller */
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = {
+ .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable,
+ .init_done = 0,
+};
+
+/* From interrupt_controller@c000000 */
+struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = {
+ .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable,
+ .init_done = 0,
+};
+
+/* From local_external_interrupts_0 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = {
+ .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
+ .init_done = 0,
+};
+
+/* From gpio@10012000 */
+struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = {
+ .gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio,
+};
+
+/* From led@0red */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = {
+ .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
+};
+
+/* From led@0green */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = {
+ .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
+};
+
+/* From led@0blue */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = {
+ .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
+};
+
+/* From spi@10014000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = {
+ .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
+};
+
+/* From serial@10013000 */
+struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart,
+};
+
+/* From clock@3 */
+struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = {
+ .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock,
+};
+
+/* From clock@1 */
+struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = {
+ .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock,
+};
+
+/* From clock@4 */
+struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = {
+ .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock,
+};
+
+/* From prci@10008000 */
+struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = {
+};
+
+
+#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/
+#endif /* ! ASSEMBLY */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h
new file mode 100644
index 000000000..4ecd3e336
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h
@@ -0,0 +1,237 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
+#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
+
+/* From clock@0 */
+#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL
+
+/* From clock@2 */
+#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL
+
+/* From clock@5 */
+#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL
+
+#define METAL_FIXED_CLOCK
+
+/* From clint@2000000 */
+#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL
+#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL
+#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL
+#define METAL_RISCV_CLINT0_0_SIZE 65536UL
+
+#define METAL_RISCV_CLINT0
+#define METAL_RISCV_CLINT0_MSIP_BASE 0UL
+#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL
+#define METAL_RISCV_CLINT0_MTIME 49144UL
+
+/* From interrupt_controller@c000000 */
+#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592UL
+#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL
+#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL
+#define METAL_RISCV_PLIC0_0_SIZE 67108864UL
+#define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL
+#define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL
+#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 27UL
+#define METAL_RISCV_PLIC0_0_RISCV_NDEV 27UL
+
+#define METAL_RISCV_PLIC0
+#define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL
+#define METAL_RISCV_PLIC0_PENDING_BASE 4096UL
+#define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL
+#define METAL_RISCV_PLIC0_THRESHOLD 2097152UL
+#define METAL_RISCV_PLIC0_CLAIM 2097156UL
+
+/* From aon@10000000 */
+#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL
+#define METAL_SIFIVE_AON0_0_SIZE 32768UL
+
+#define METAL_SIFIVE_AON0
+#define METAL_SIFIVE_AON0_WDOGCFG 0UL
+#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL
+#define METAL_SIFIVE_AON0_WDOGS 16UL
+#define METAL_SIFIVE_AON0_WDOGFEED 24UL
+#define METAL_SIFIVE_AON0_WDOGKEY 28UL
+#define METAL_SIFIVE_AON0_WDOGCMP 32UL
+#define METAL_SIFIVE_AON0_RTCCFG 64UL
+#define METAL_SIFIVE_AON0_RTCLO 72UL
+#define METAL_SIFIVE_AON0_RTCHI 72UL
+#define METAL_SIFIVE_AON0_RTCS 80UL
+#define METAL_SIFIVE_AON0_RTCCMP 96UL
+#define METAL_SIFIVE_AON0_LFROSCCFG 112UL
+#define METAL_SIFIVE_AON0_BACKUP0 128UL
+#define METAL_SIFIVE_AON0_BACKUP1 132UL
+#define METAL_SIFIVE_AON0_BACKUP2 136UL
+#define METAL_SIFIVE_AON0_BACKUP3 140UL
+#define METAL_SIFIVE_AON0_BACKUP4 144UL
+#define METAL_SIFIVE_AON0_BACKUP5 148UL
+#define METAL_SIFIVE_AON0_BACKUP6 152UL
+#define METAL_SIFIVE_AON0_BACKUP7 152UL
+#define METAL_SIFIVE_AON0_BACKUP8 160UL
+#define METAL_SIFIVE_AON0_BACKUP9 164UL
+#define METAL_SIFIVE_AON0_BACKUP10 168UL
+#define METAL_SIFIVE_AON0_BACKUP11 172UL
+#define METAL_SIFIVE_AON0_BACKUP12 176UL
+#define METAL_SIFIVE_AON0_BACKUP13 180UL
+#define METAL_SIFIVE_AON0_BACKUP14 184UL
+#define METAL_SIFIVE_AON0_BACKUP15 188UL
+#define METAL_SIFIVE_AON0_BACKUP16 192UL
+#define METAL_SIFIVE_AON0_BACKUP17 196UL
+#define METAL_SIFIVE_AON0_BACKUP18 200UL
+#define METAL_SIFIVE_AON0_BACKUP19 204UL
+#define METAL_SIFIVE_AON0_BACKUP20 208UL
+#define METAL_SIFIVE_AON0_BACKUP21 212UL
+#define METAL_SIFIVE_AON0_BACKUP22 216UL
+#define METAL_SIFIVE_AON0_BACKUP23 220UL
+#define METAL_SIFIVE_AON0_BACKUP24 224UL
+#define METAL_SIFIVE_AON0_BACKUP25 228UL
+#define METAL_SIFIVE_AON0_BACKUP26 232UL
+#define METAL_SIFIVE_AON0_BACKUP27 236UL
+#define METAL_SIFIVE_AON0_BACKUP28 240UL
+#define METAL_SIFIVE_AON0_BACKUP29 244UL
+#define METAL_SIFIVE_AON0_BACKUP30 248UL
+#define METAL_SIFIVE_AON0_BACKUP31 252UL
+#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL
+#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL
+#define METAL_SIFIVE_AON0_PMUIE 320UL
+#define METAL_SIFIVE_AON0_PMUCAUSE 324UL
+#define METAL_SIFIVE_AON0_PMUSLEEP 328UL
+#define METAL_SIFIVE_AON0_PMUKEY 332UL
+
+/* From clock@3 */
+
+#define METAL_SIFIVE_FE310_G000_HFROSC
+
+/* From clock@1 */
+
+#define METAL_SIFIVE_FE310_G000_HFXOSC
+
+/* From prci@10008000 */
+#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL
+#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL
+#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL
+#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL
+
+#define METAL_SIFIVE_FE310_G000_PRCI
+#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL
+#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL
+#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL
+#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL
+
+/* From clock@4 */
+#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL
+
+#define METAL_SIFIVE_FE310_G000_PLL
+
+/* From gpio@10012000 */
+#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL
+#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL
+#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL
+#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL
+
+#define METAL_SIFIVE_GPIO0
+#define METAL_SIFIVE_GPIO0_VALUE 0UL
+#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL
+#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL
+#define METAL_SIFIVE_GPIO0_PORT 12UL
+#define METAL_SIFIVE_GPIO0_PUE 16UL
+#define METAL_SIFIVE_GPIO0_DS 20UL
+#define METAL_SIFIVE_GPIO0_RISE_IE 24UL
+#define METAL_SIFIVE_GPIO0_RISE_IP 28UL
+#define METAL_SIFIVE_GPIO0_FALL_IE 32UL
+#define METAL_SIFIVE_GPIO0_FALL_IP 36UL
+#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL
+#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL
+#define METAL_SIFIVE_GPIO0_LOW_IE 48UL
+#define METAL_SIFIVE_GPIO0_LOW_IP 52UL
+#define METAL_SIFIVE_GPIO0_IOF_EN 56UL
+#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL
+#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL
+
+/* From led@0red */
+
+/* From led@0green */
+
+/* From led@0blue */
+
+#define METAL_SIFIVE_GPIO_LEDS
+
+/* From i2c@10016000 */
+#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL
+#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL
+#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL
+#define METAL_SIFIVE_I2C0_0_SIZE 4096UL
+
+#define METAL_SIFIVE_I2C0
+#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL
+#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL
+#define METAL_SIFIVE_I2C0_CONTROL 8UL
+#define METAL_SIFIVE_I2C0_TRANSMIT 12UL
+#define METAL_SIFIVE_I2C0_RECEIVE 12UL
+#define METAL_SIFIVE_I2C0_COMMAND 16UL
+#define METAL_SIFIVE_I2C0_STATUS 16UL
+
+/* From local_external_interrupts_0 */
+
+#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0
+
+/* From pwm@10015000 */
+#define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL
+#define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL
+#define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL
+#define METAL_SIFIVE_PWM0_0_SIZE 4096UL
+
+#define METAL_SIFIVE_PWM0
+#define METAL_SIFIVE_PWM0_PWMCFG 0UL
+#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL
+#define METAL_SIFIVE_PWM0_PWMS 16UL
+#define METAL_SIFIVE_PWM0_PWMCMP0 32UL
+#define METAL_SIFIVE_PWM0_PWMCMP1 36UL
+#define METAL_SIFIVE_PWM0_PWMCMP2 40UL
+#define METAL_SIFIVE_PWM0_PWMCMP3 44UL
+
+/* From spi@10014000 */
+#define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL
+#define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL
+#define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL
+#define METAL_SIFIVE_SPI0_0_SIZE 4096UL
+
+#define METAL_SIFIVE_SPI0
+#define METAL_SIFIVE_SPI0_SCKDIV 0UL
+#define METAL_SIFIVE_SPI0_SCKMODE 4UL
+#define METAL_SIFIVE_SPI0_CSID 16UL
+#define METAL_SIFIVE_SPI0_CSDEF 20UL
+#define METAL_SIFIVE_SPI0_CSMODE 24UL
+#define METAL_SIFIVE_SPI0_DELAY0 40UL
+#define METAL_SIFIVE_SPI0_DELAY1 44UL
+#define METAL_SIFIVE_SPI0_FMT 64UL
+#define METAL_SIFIVE_SPI0_TXDATA 72UL
+#define METAL_SIFIVE_SPI0_RXDATA 76UL
+#define METAL_SIFIVE_SPI0_TXMARK 80UL
+#define METAL_SIFIVE_SPI0_RXMARK 84UL
+#define METAL_SIFIVE_SPI0_FCTRL 96UL
+#define METAL_SIFIVE_SPI0_FFMT 100UL
+#define METAL_SIFIVE_SPI0_IE 112UL
+#define METAL_SIFIVE_SPI0_IP 116UL
+
+/* From serial@10013000 */
+#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL
+#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL
+#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL
+#define METAL_SIFIVE_UART0_0_SIZE 4096UL
+
+#define METAL_SIFIVE_UART0
+#define METAL_SIFIVE_UART0_TXDATA 0UL
+#define METAL_SIFIVE_UART0_RXDATA 4UL
+#define METAL_SIFIVE_UART0_TXCTRL 8UL
+#define METAL_SIFIVE_UART0_RXCTRL 12UL
+#define METAL_SIFIVE_UART0_IE 16UL
+#define METAL_SIFIVE_UART0_IP 20UL
+#define METAL_SIFIVE_UART0_DIV 24UL
+
+#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h
new file mode 100644
index 000000000..b62d8b25a
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h
@@ -0,0 +1,81 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__MEMORY_H
+#define METAL__MEMORY_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/*!
+ * @file memory.h
+ *
+ * @brief API for enumerating memory blocks
+ */
+
+struct _metal_memory_attributes {
+ int R : 1;
+ int W : 1;
+ int X : 1;
+ int C : 1;
+ int A : 1;
+};
+
+/*!
+ * @brief A handle for a memory block
+ */
+struct metal_memory {
+ const uintptr_t _base_address;
+ const size_t _size;
+ const struct _metal_memory_attributes _attrs;
+};
+
+/*!
+ * @brief Get the memory block which services the given address
+ *
+ * Given a physical memory address, get a handle for the memory block to which
+ * that address is mapped.
+ *
+ * @param address The address to query
+ * @return The memory block handle, or NULL if the address is not mapped to a memory block
+ */
+struct metal_memory *metal_get_memory_from_address(const uintptr_t address);
+
+/*!
+ * @brief Get the base address for a memory block
+ * @param memory The handle for the memory block
+ * @return The base address of the memory block
+ */
+inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory) {
+ return memory->_base_address;
+}
+
+/*!
+ * @brief Get the size of a memory block
+ * @param memory The handle for the memory block
+ * @return The size of the memory block
+ */
+inline size_t metal_memory_get_size(const struct metal_memory *memory) {
+ return memory->_size;
+}
+
+/*!
+ * @brief Query if a memory block supports atomic operations
+ * @param memory The handle for the memory block
+ * @return nonzero if the memory block supports atomic operations
+ */
+inline int metal_memory_supports_atomics(const struct metal_memory *memory) {
+ return memory->_attrs.A;
+}
+
+/*!
+ * @brief Query if a memory block is cacheable
+ * @param memory The handle for the memory block
+ * @return nonzero if the memory block is cachable
+ */
+inline int metal_memory_is_cachable(const struct metal_memory *memory) {
+ return memory->_attrs.C;
+}
+
+#endif /* METAL__MEMORY_H */
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h
new file mode 100644
index 000000000..9121b10a1
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h
@@ -0,0 +1,204 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__PMP_H
+#define METAL__PMP_H
+
+/*!
+ * @file metal/pmp.h
+ *
+ * @brief API for Configuring Physical Memory Protection on RISC-V Cores
+ *
+ * The Physical Memory Protection (PMP) interface on RISC-V cores
+ * is a form of memory protection unit which allows for a finite number
+ * of physical memory regions to be configured with certain access
+ * permissions.
+ *
+ * Additional information about the use and configuration rules for PMPs
+ * can be found by reading the RISC-V Privileged Architecture Specification.
+ */
+
+#include <stddef.h>
+#include <metal/machine.h>
+
+struct metal_pmp;
+
+/*!
+ * @brief Set of available PMP addressing modes
+ */
+enum metal_pmp_address_mode {
+ /*! @brief Disable the PMP region */
+ METAL_PMP_OFF = 0,
+ /*! @brief Use Top-of-Range mode */
+ METAL_PMP_TOR = 1,
+ /*! @brief Use naturally-aligned 4-byte region mode */
+ METAL_PMP_NA4 = 2,
+ /*! @brief Use naturally-aligned power-of-two mode */
+ METAL_PMP_NAPOT = 3
+};
+
+/*!
+ * @brief Configuration for a PMP region
+ */
+struct metal_pmp_config {
+ /*! @brief Sets whether reads to the PMP region succeed */
+ int R : 1;
+ /*! @brief Sets whether writes to the PMP region succeed */
+ int W : 1;
+ /*! @brief Sets whether the PMP region is executable */
+ int X : 1;
+
+ /*! @brief Sets the addressing mode of the PMP region */
+ enum metal_pmp_address_mode A : 2;
+
+ int _pad : 2;
+
+ /*! @brief Sets whether the PMP region is locked */
+ enum metal_pmp_locked {
+ METAL_PMP_UNLOCKED = 0,
+ METAL_PMP_LOCKED = 1
+ } L : 1;
+};
+
+/*!
+ * @brief A handle for the PMP device
+ */
+struct metal_pmp {
+ /* The minimum granularity of the PMP region. Set by metal_pmp_init */
+ uintptr_t _granularity[METAL_MAX_CORES];
+};
+
+/*!
+ * @brief Get the PMP device handle
+ */
+struct metal_pmp *metal_pmp_get_device(void);
+
+/*!
+ * @brief Initialize the PMP
+ * @param pmp The PMP device handle to be initialized
+ *
+ * The PMP initialization routine is optional and may be called as many times
+ * as is desired. The effect of the initialization routine is to attempt to set
+ * all regions to unlocked and disabled, as well as to clear the X, W, and R
+ * bits. Only the pmp configuration of the hart which executes the routine will
+ * be affected.
+ *
+ * If any regions are fused to preset values by the implementation or locked,
+ * those PMP regions will silently remain uninitialized.
+ */
+void metal_pmp_init(struct metal_pmp *pmp);
+
+/*!
+ * @brief Configure a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to configure
+ * @param config The desired configuration of the PMP region
+ * @param address The desired address of the PMP region
+ * @return 0 upon success
+ */
+int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address);
+
+/*!
+ * @brief Get the configuration for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @param config Variable to store the PMP region configuration
+ * @param address Variable to store the PMP region address
+ * @return 0 if the region is read successfully
+ */
+int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address);
+
+/*!
+ * @brief Lock a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to lock
+ * @return 0 if the region is successfully locked
+ */
+int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region);
+
+/*!
+ * @brief Set the address for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to set
+ * @param address The desired address of the PMP region
+ * @return 0 if the address is successfully set
+ */
+int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address);
+
+/*!
+ * @brief Get the address of a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @return The address of the PMP region, or 0 if the region could not be read
+ */
+size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region);
+
+/*!
+ * @brief Set the addressing mode of a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to set
+ * @param mode The PMP addressing mode to set
+ * @return 0 if the addressing mode is successfully set
+ */
+int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode);
+
+/*!
+ * @brief Get the addressing mode of a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @return The address mode of the PMP region
+ */
+enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region);
+
+/*!
+ * @brief Set the executable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to set
+ * @param X The desired value of the executable bit
+ * @return 0 if the executable bit is successfully set
+ */
+int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X);
+
+/*!
+ * @brief Get the executable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @return the value of the executable bit
+ */
+int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region);
+
+/*!
+ * @brief Set the writable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to set
+ * @param W The desired value of the writable bit
+ * @return 0 if the writable bit is successfully set
+ */
+int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W);
+
+/*!
+ * @brief Get the writable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @return the value of the writable bit
+ */
+int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region);
+
+/*!
+ * @brief Set the readable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to set
+ * @param R The desired value of the readable bit
+ * @return 0 if the readable bit is successfully set
+ */
+int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R);
+
+/*!
+ * @brief Set the readable bit for a PMP region
+ * @param pmp The PMP device handle
+ * @param region The PMP region to read
+ * @return the value of the readable bit
+ */
+int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h
new file mode 100644
index 000000000..c5212e5d1
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h
@@ -0,0 +1,122 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__PRIVILEGE_H
+#define METAL__PRIVILEGE_H
+
+/*!
+ * @file metal/privilege.h
+ *
+ * @brief API for manipulating the privilege mode of a RISC-V system
+ *
+ * Additional information about privilege modes on RISC-V systems can be found
+ * by reading the RISC-V Privileged Architecture Specification v1.10.
+ */
+
+#include <stdint.h>
+
+enum metal_privilege_mode {
+ METAL_PRIVILEGE_USER = 0,
+ METAL_PRIVILEGE_SUPERVISOR = 1,
+ METAL_PRIVELEGE_MACHINE = 3,
+};
+
+#if __riscv_xlen == 32
+typedef uint32_t metal_xreg_t;
+#elif __riscv_xlen == 64
+typedef uint64_t metal_xreg_t;
+#endif
+
+#if __riscv_flen == 32
+typedef uint32_t metal_freg_t;
+#elif __riscv_flen == 64
+typedef uint64_t metal_freg_t;
+#endif
+
+struct metal_register_file {
+ metal_xreg_t ra;
+ metal_xreg_t sp;
+ metal_xreg_t gp;
+ metal_xreg_t tp;
+
+ metal_xreg_t t0;
+ metal_xreg_t t1;
+ metal_xreg_t t2;
+
+ metal_xreg_t s0;
+ metal_xreg_t s1;
+
+ metal_xreg_t a0;
+ metal_xreg_t a1;
+ metal_xreg_t a2;
+ metal_xreg_t a3;
+ metal_xreg_t a4;
+ metal_xreg_t a5;
+#ifndef __riscv_32e
+ metal_xreg_t a6;
+ metal_xreg_t a7;
+
+ metal_xreg_t s2;
+ metal_xreg_t s3;
+ metal_xreg_t s4;
+ metal_xreg_t s5;
+ metal_xreg_t s6;
+ metal_xreg_t s7;
+ metal_xreg_t s8;
+ metal_xreg_t s9;
+ metal_xreg_t s10;
+ metal_xreg_t s11;
+
+ metal_xreg_t t3;
+ metal_xreg_t t4;
+ metal_xreg_t t5;
+ metal_xreg_t t6;
+#endif /* __riscv_32e */
+
+#ifdef __riscv_flen
+ metal_freg_t ft0;
+ metal_freg_t ft1;
+ metal_freg_t ft2;
+ metal_freg_t ft3;
+ metal_freg_t ft4;
+ metal_freg_t ft5;
+ metal_freg_t ft6;
+ metal_freg_t ft7;
+
+ metal_freg_t fs0;
+ metal_freg_t fs1;
+
+ metal_freg_t fa0;
+ metal_freg_t fa1;
+ metal_freg_t fa2;
+ metal_freg_t fa3;
+ metal_freg_t fa4;
+ metal_freg_t fa5;
+ metal_freg_t fa6;
+ metal_freg_t fa7;
+
+ metal_freg_t fs2;
+ metal_freg_t fs3;
+ metal_freg_t fs4;
+ metal_freg_t fs5;
+ metal_freg_t fs6;
+ metal_freg_t fs7;
+ metal_freg_t fs8;
+ metal_freg_t fs9;
+ metal_freg_t fs10;
+ metal_freg_t fs11;
+
+ metal_freg_t ft8;
+ metal_freg_t ft9;
+ metal_freg_t ft10;
+ metal_freg_t ft11;
+#endif /* __riscv_flen */
+};
+
+typedef void (*metal_privilege_entry_point_t)();
+
+void metal_privilege_drop_to_mode(enum metal_privilege_mode mode,
+ struct metal_register_file regfile,
+ metal_privilege_entry_point_t entry_point);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h
new file mode 100644
index 000000000..3bebfa742
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h
@@ -0,0 +1,36 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__SHUTDOWN_H
+#define METAL__SHUTDOWN_H
+
+/*!
+ * @file shutdown.h
+ * @brief API for shutting down a machine
+ */
+
+struct __metal_shutdown;
+
+struct __metal_shutdown_vtable {
+ void (*exit)(const struct __metal_shutdown *sd, int code) __attribute__((noreturn));
+};
+
+struct __metal_shutdown {
+ const struct __metal_shutdown_vtable *vtable;
+};
+
+inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn));
+inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) { sd->vtable->exit(sd, code); }
+
+/*!
+ * @brief The public METAL shutdown interface
+ *
+ * Shuts down the machine, if the machine enables an interface for
+ * shutting down. When no interface is provided, will cause the machine
+ * to spin indefinitely.
+ *
+ * @param code The return code to set. 0 indicates program success.
+ */
+void metal_shutdown(int code) __attribute__((noreturn));
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h
new file mode 100644
index 000000000..b011fe3ce
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h
@@ -0,0 +1,78 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__SPI_H
+#define METAL__SPI_H
+
+struct metal_spi;
+
+/*! @brief The configuration for a SPI transfer */
+struct metal_spi_config {
+ /*! @brief The protocol for the SPI transfer */
+ enum {
+ METAL_SPI_SINGLE,
+ METAL_SPI_DUAL,
+ METAL_SPI_QUAD
+ } protocol;
+
+ /*! @brief The polarity of the SPI transfer, equivalent to CPOL */
+ unsigned int polarity : 1;
+ /*! @brief The phase of the SPI transfer, equivalent to CPHA */
+ unsigned int phase : 1;
+ /*! @brief The endianness of the SPI transfer */
+ unsigned int little_endian : 1;
+ /*! @brief The active state of the chip select line */
+ unsigned int cs_active_high : 1;
+ /*! @brief The chip select ID to activate for the SPI transfer */
+ unsigned int csid;
+};
+
+struct metal_spi_vtable {
+ void (*init)(struct metal_spi *spi, int baud_rate);
+ int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf);
+ int (*get_baud_rate)(struct metal_spi *spi);
+ int (*set_baud_rate)(struct metal_spi *spi, int baud_rate);
+};
+
+/*! @brief A handle for a SPI device */
+struct metal_spi {
+ const struct metal_spi_vtable *vtable;
+};
+
+/*! @brief Get a handle for a SPI device
+ * @param device_num The index of the desired SPI device
+ * @return A handle to the SPI device, or NULL if the device does not exist*/
+struct metal_spi *metal_spi_get_device(int device_num);
+
+/*! @brief Initialize a SPI device with a certain baud rate
+ * @param spi The handle for the SPI device to initialize
+ * @param baud_rate The baud rate to set the SPI device to
+ */
+inline void metal_spi_init(struct metal_spi *spi, int baud_rate) { spi->vtable->init(spi, baud_rate); }
+
+/*! @brief Perform a SPI transfer
+ * @param spi The handle for the SPI device to perform the transfer
+ * @param config The configuration for the SPI transfer.
+ * @param len The number of bytes to transfer
+ * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If NULL, the SPI will transfer the value 0.
+ * @param rx_buf The buffer to receive data into. Must be len bytes long. If NULL, the SPI will ignore received bytes.
+ * @return 0 if the transfer succeeds
+ */
+inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf) {
+ return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf);
+}
+
+/*! @brief Get the current baud rate of the SPI device
+ * @param spi The handle for the SPI device
+ * @return The baud rate in Hz
+ */
+inline int metal_spi_get_baud_rate(struct metal_spi *spi) { return spi->vtable->get_baud_rate(spi); }
+
+/*! @brief Set the current baud rate of the SPI device
+ * @param spi The handle for the SPI device
+ * @param baud_rate The desired baud rate of the SPI device
+ * @return 0 if the baud rate is successfully changed
+ */
+inline int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { return spi->vtable->set_baud_rate(spi, baud_rate); }
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h
new file mode 100644
index 000000000..d1c35bc93
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h
@@ -0,0 +1,51 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__SWITCH_H
+#define METAL__SWITCH_H
+
+/*!
+ * @file switch.h
+ * @brief API for reading toggle switches
+ */
+
+#include <metal/interrupt.h>
+
+struct metal_switch;
+
+struct metal_switch_vtable {
+ int (*switch_exist)(struct metal_switch *sw, char *label);
+ struct metal_interrupt* (*interrupt_controller)(struct metal_switch *sw);
+ int (*get_interrupt_id)(struct metal_switch *sw);
+};
+
+/*!
+ * @brief A handle for a switch
+ */
+struct metal_switch {
+ const struct metal_switch_vtable *vtable;
+};
+
+/*!
+ * @brief Get a handle for a switch
+ * @param label The DeviceTree label for the desired switch
+ * @return A handle to the switch, or NULL if none is found for the requested label
+ */
+struct metal_switch* metal_switch_get(char *label);
+
+/*!
+ * @brief Get the interrupt controller for a switch
+ * @param sw The handle for the switch
+ * @return The interrupt controller handle
+ */
+inline struct metal_interrupt*
+ metal_switch_interrupt_controller(struct metal_switch *sw) { return sw->vtable->interrupt_controller(sw); }
+
+/*!
+ * @brief Get the interrupt id for a switch
+ * @param sw The handle for the switch
+ * @return The interrupt ID for the switch
+ */
+inline int metal_switch_get_interrupt_id(struct metal_switch *sw) { return sw->vtable->get_interrupt_id(sw); }
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h
new file mode 100644
index 000000000..eeae1f60b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h
@@ -0,0 +1,36 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__TIMER_H
+#define METAL__TIMER_H
+
+/*!
+ * @file timer.h
+ * @brief API for reading and manipulating the machine timer
+ */
+
+/*!
+ * @brief Read the machine cycle count
+ * @param hartid The hart ID to read the cycle count of
+ * @param cyclecount The variable to hold the value
+ * @return 0 upon success
+ */
+int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount);
+
+/*!
+ * @brief Get the machine timebase frequency
+ * @param hartid The hart ID to read the timebase of
+ * @param timebase The variable to hold the value
+ * @return 0 upon success
+ */
+int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase);
+
+/*!
+ * @brief Set the machine timer tick interval in seconds
+ * @param hartid The hart ID to read the timebase of
+ * @param second The number of seconds to set the tick interval to
+ * @return 0 upon success
+ */
+int metal_timer_set_tick(int hartid, int second);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h
new file mode 100644
index 000000000..d2583e3be
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h
@@ -0,0 +1,23 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__TTY_H
+#define METAL__TTY_H
+
+/*!
+ * @file tty.h
+ * @brief API for emulated serial teriminals
+ */
+
+/*!
+ * @brief Write a character to the default output device
+ *
+ * Write a character to the default output device, which for most
+ * targets is the UART serial port.
+ *
+ * @param c The character to write to the terminal
+ * @return 0 on success, or -1 on failure.
+ */
+int metal_tty_putc(unsigned char c);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h
new file mode 100644
index 000000000..611792a6c
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h
@@ -0,0 +1,94 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__UART_H
+#define METAL__UART_H
+
+/*!
+ * @file uart.h
+ * @brief API for UART serial ports
+ */
+
+#include <metal/interrupt.h>
+
+struct metal_uart;
+
+struct metal_uart_vtable {
+ void (*init)(struct metal_uart *uart, int baud_rate);
+ int (*putc)(struct metal_uart *uart, unsigned char c);
+ int (*getc)(struct metal_uart *uart, unsigned char *c);
+ int (*get_baud_rate)(struct metal_uart *uart);
+ int (*set_baud_rate)(struct metal_uart *uart, int baud_rate);
+ struct metal_interrupt* (*controller_interrupt)(struct metal_uart *uart);
+ int (*get_interrupt_id)(struct metal_uart *uart);
+};
+
+/*!
+ * @brief Handle for a UART serial device
+ */
+struct metal_uart {
+ const struct metal_uart_vtable *vtable;
+};
+
+/*!
+ * @brief Initialize UART device
+
+ * Initialize the UART device described by the UART handle. This function must be called before any
+ * other method on the UART can be invoked. It is invalid to initialize a UART more than once.
+ *
+ * @param uart The UART device handle
+ * @param baud_rate the baud rate to set the UART to
+ */
+inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uart->vtable->init(uart, baud_rate); }
+
+/*!
+ * @brief Output a character over the UART
+ * @param uart The UART device handle
+ * @param c The character to send over the UART
+ * @return 0 upon success
+ */
+inline int metal_uart_putc(struct metal_uart *uart, unsigned char c) { return uart->vtable->putc(uart, c); }
+
+/*!
+ * @brief Read a character sent over the UART
+ * @param uart The UART device handle
+ * @param c The varible to hold the read character
+ * @return 0 upon success
+ */
+inline int metal_uart_getc(struct metal_uart *uart, unsigned char *c) { return uart->vtable->getc(uart, c); }
+
+/*!
+ * @brief Get the baud rate of the UART peripheral
+ * @param uart The UART device handle
+ * @return The current baud rate of the UART
+ */
+inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtable->get_baud_rate(uart); }
+
+/*!
+ * @brief Set the baud rate of the UART peripheral
+ * @param uart The UART device handle
+ * @param baud_rate The baud rate to configure
+ * @return the new baud rate of the UART
+ */
+inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { return uart->vtable->set_baud_rate(uart, baud_rate); }
+
+/*!
+ * @brief Get the interrupt controller of the UART peripheral
+ *
+ * Get the interrupt controller for the UART peripheral. The interrupt
+ * controller must be initialized before any interrupts can be registered
+ * or enabled with it.
+ *
+ * @param uart The UART device handle
+ * @return The handle for the UART interrupt controller
+ */
+inline struct metal_interrupt* metal_uart_interrupt_controller(struct metal_uart *uart) { return uart->vtable->controller_interrupt(uart); }
+
+/*!
+ * @brief Get the interrupt ID of the UART controller
+ * @param uart The UART device handle
+ * @return The UART interrupt id
+ */
+inline int metal_uart_get_interrupt_id(struct metal_uart *uart) { return uart->vtable->get_interrupt_id(uart); }
+
+#endif