diff options
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp')
49 files changed, 5651 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts new file mode 100644 index 000000000..970d3be72 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts @@ -0,0 +1,209 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sifive,hifive1-revb"; + model = "sifive,hifive1-revb"; + + chosen { + stdout-path = "/soc/serial@10013000:115200"; + metal,entry = <&spi0 0x10000>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "sifive,fe310-g000"; + L6: cpu@0 { + clocks = <&hfclk>; + compatible = "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&spi0>; + reg = <0>; + riscv,isa = "rv32imac"; + riscv,pmpregions = <8>; + sifive,dtim = <&dtim>; + status = "okay"; + timebase-frequency = <1000000>; + hardware-exec-breakpoint-count = <4>; + hlic: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + compatible = "sifive,hifive1"; + ranges; + hfxoscin: clock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + }; + hfxoscout: clock@1 { + compatible = "sifive,fe310-g000,hfxosc"; + clocks = <&hfxoscin>; + reg = <&prci 0x4>; + reg-names = "config"; + }; + hfroscin: clock@2 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <72000000>; + }; + hfroscout: clock@3 { + compatible = "sifive,fe310-g000,hfrosc"; + clocks = <&hfroscin>; + reg = <&prci 0x0>; + reg-names = "config"; + }; + hfclk: clock@4 { + compatible = "sifive,fe310-g000,pll"; + clocks = <&hfxoscout &hfroscout>; + clock-names = "pllref", "pllsel0"; + reg = <&prci 0x8 &prci 0xc>; + reg-names = "config", "divider"; + clock-frequency = <16000000>; + }; + + lfroscin: clock@5 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32000000>; + }; + lfclk: clock@6 { + compatible = "sifive,fe310-g000,lfrosc"; + clocks = <&lfroscin>; + reg = <&aon 0x70>; + reg-names = "config"; + }; + + aon: aon@10000000 { + compatible = "sifive,aon0"; + reg = <0x10000000 0x8000>; + reg-names = "mem"; + }; + + prci: prci@10008000 { + compatible = "sifive,fe310-g000,prci"; + reg = <0x10008000 0x8000>; + reg-names = "mem"; + }; + + clint: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&hlic 3 &hlic 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + local-external-interrupts-0 { + compatible = "sifive,local-external-interrupts0"; + interrupt-parent = <&hlic>; + interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>; + }; + plic: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = <&hlic 11>; + reg = <0xc000000 0x4000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <26>; + }; + global-external-interrupts { + compatile = "sifive,global-external-interrupts0"; + interrupt-parent = <&plic>; + interrupts = <1 2 3 4>; + }; + + debug-controller@0 { + compatible = "sifive,debug-011", "riscv,debug-011"; + interrupts-extended = <&hlic 65535>; + reg = <0x0 0x100>; + reg-names = "control"; + }; + + maskrom@1000 { + reg = <0x1000 0x2000>; + reg-names = "mem"; + }; + otp@20000 { + reg = <0x20000 0x2000 0x10010000 0x1000>; + reg-names = "mem", "control"; + }; + + dtim: dtim@80000000 { + compatible = "sifive,dtim0"; + reg = <0x80000000 0x4000>; + reg-names = "mem"; + }; + + pwm@10015000 { + compatible = "sifive,pwm0"; + interrupt-parent = <&plic>; + interrupts = <23 24 25 26>; + reg = <0x10015000 0x1000>; + reg-names = "control"; + }; + gpio0: gpio@10012000 { + compatible = "sifive,gpio0"; + interrupt-parent = <&plic>; + interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>; + reg = <0x10012000 0x1000>; + reg-names = "control"; + }; + uart0: serial@10013000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <5>; + reg = <0x10013000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x30000 0x30000>; + }; + spi0: spi@10014000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <6>; + reg = <0x10014000 0x1000 0x20000000 0x7A120>; + reg-names = "control", "mem"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0003C 0x0003C>; + }; + i2c0: i2c@10016000 { + compatible = "sifive,i2c0"; + interrupt-parent = <&plic>; + interrupts = <52>; + reg = <0x10016000 0x1000>; + reg-names = "control"; + }; + led@0red { + compatible = "sifive,gpio-leds"; + label = "LD0red"; + gpios = <&gpio0 22>; + linux,default-trigger = "none"; + }; + led@0green { + compatible = "sifive,gpio-leds"; + label = "LD0green"; + gpios = <&gpio0 19>; + linux,default-trigger = "none"; + }; + led@0blue { + compatible = "sifive,gpio-leds"; + label = "LD0blue"; + gpios = <&gpio0 21>; + linux,default-trigger = "none"; + }; + }; +}; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist new file mode 100644 index 000000000..921dd83ac --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist @@ -0,0 +1,54 @@ +zero +ra +sp +gp +tp +t0 +t1 +t2 +fp +s1 +a0 +a1 +a2 +a3 +a4 +a5 +a6 +a7 +s2 +s3 +s4 +s5 +s6 +s7 +s8 +s9 +s10 +s11 +t3 +t4 +t5 +t6 +pc +mstatus +misa +mie +mtvec +mscratch +mepc +mcause +mtval +mip +mvendorid +marchid +mimpid +mhartid +tselect +tdata1 +tdata2 +tdata3 +dcsr +dpc +dscratch +priv 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 diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h new file mode 100644 index 000000000..8c0cd048b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-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/metal-platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h new file mode 100644 index 000000000..4ecd3e336 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-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/metal.default.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds new file mode 100644 index 000000000..7070af7e8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds @@ -0,0 +1,236 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +OUTPUT_ARCH("riscv") + +ENTRY(_enter) + +MEMORY +{ + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 + flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + itim_init PT_LOAD; + ram PT_NULL; + itim PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x4; + PROVIDE(__metal_boot_hart = 0); + PROVIDE(__metal_chicken_bit = 0); + + + .init : + { + KEEP (*(.text.metal.init.enter)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >flash AT>flash :flash + + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.itim .itim.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >flash AT>flash :flash + + + . = ALIGN(4); + + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + + .litimalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_itim_source_start = . ); + } >flash AT>flash :flash + + + .ditimalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_itim_target_start = . ); + } >ram AT>flash :ram_init + + + .itim : + { + *(.itim .itim.*) + } >flash AT>flash :flash + + + . = ALIGN(8); + PROVIDE( metal_segment_itim_target_end = . ); + + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + PROVIDE( metal_segment_data_source_start = . ); + } >flash AT>flash :flash + + + .dalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_data_target_start = . ); + } >ram AT>flash :ram_init + + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>flash :ram_init + + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + PROVIDE( metal_segment_data_target_end = . ); + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + PROVIDE( metal_segment_bss_target_start = . ); + + + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + PROVIDE( metal_segment_bss_target_end = . ); + + .stack : + { + . = ALIGN(16); + metal_segment_stack_begin = .; + . += __stack_size; + . = ALIGN(16); + _sp = .; + PROVIDE(metal_segment_stack_end = .); + __freertos_irq_stack_top = .; + } >ram AT>ram :ram + + + .heap : + { + PROVIDE( metal_segment_heap_target_start = . ); + . = __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + } >ram AT>ram :ram + + +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h new file mode 100644 index 000000000..f76dbd632 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.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 */ |