From 2fedeff3328346fcd97e8b8e68176e62a1ed7ff9 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Thu, 15 Jul 2021 18:40:22 -0700 Subject: [PATCH] Update BSP and SDK for HiFive board (#645) * Update BSP and SDK for HiFive board This commit also adds demo start and success/failure output messages. --- .../.cproject | 269 +- .../.project | 606 +- .../.settings/language.settings.xml | 40 +- .../FreeRTOSConfig.h | 207 +- .../SiFive_HiFive1_RTOS_demo.url | 10 +- .../blinky_demo/main_blinky.c | 394 +- .../bsp/README.md | 13 + .../bsp/core.dts | 262 + .../bsp/design.dts | 215 +- .../bsp/design.svd | 3169 ++++++++++ .../bsp/install/include/metal/atomic.h | 259 + .../bsp/install/include/metal/button.h | 16 +- .../bsp/install/include/metal/cache.h | 82 +- .../bsp/install/include/metal/clock.h | 119 +- .../bsp/install/include/metal/compiler.h | 15 +- .../bsp/install/include/metal/cpu.h | 138 +- .../bsp/install/include/metal/csr.h | 32 + .../include/metal/drivers/fixed-clock.h | 2 +- .../metal/drivers/fixed-factor-clock.h | 2 +- .../include/metal/drivers/riscv_clint0.h | 3 + .../install/include/metal/drivers/riscv_cpu.h | 263 +- .../include/metal/drivers/riscv_plic0.h | 8 +- .../include/metal/drivers/sifive_buserror0.h | 184 + .../include/metal/drivers/sifive_ccache0.h | 140 + .../include/metal/drivers/sifive_clic0.h | 32 +- .../metal/drivers/sifive_fe310-g000_hfrosc.h | 4 +- .../metal/drivers/sifive_fe310-g000_lfrosc.h | 21 + .../metal/drivers/sifive_fe310-g000_prci.h | 8 +- .../metal/drivers/sifive_fu540-c000_l2.h | 23 - .../metal/drivers/sifive_gpio-buttons.h | 4 +- .../include/metal/drivers/sifive_gpio-leds.h | 4 +- .../metal/drivers/sifive_gpio-switches.h | 4 +- .../include/metal/drivers/sifive_gpio0.h | 2 +- .../include/metal/drivers/sifive_i2c0.h | 24 + .../include/metal/drivers/sifive_l2pf0.h | 78 + .../sifive_local-external-interrupts0.h | 1 - .../include/metal/drivers/sifive_pwm0.h | 29 + .../include/metal/drivers/sifive_rtc0.h | 26 + .../include/metal/drivers/sifive_simuart0.h | 29 + .../include/metal/drivers/sifive_spi0.h | 4 +- .../include/metal/drivers/sifive_test0.h | 1 - .../include/metal/drivers/sifive_trace.h | 23 + .../include/metal/drivers/sifive_uart0.h | 9 +- .../include/metal/drivers/sifive_wdog0.h | 26 + .../install/include/metal/drivers/ucb_htif0.h | 48 + .../bsp/install/include/metal/gpio.h | 194 +- .../bsp/install/include/metal/hpm.h | 146 + .../bsp/install/include/metal/i2c.h | 112 + .../bsp/install/include/metal/init.h | 130 + .../bsp/install/include/metal/interrupt.h | 520 +- .../bsp/install/include/metal/io.h | 11 +- .../bsp/install/include/metal/itim.h | 3 +- .../bsp/install/include/metal/led.h | 23 +- .../bsp/install/include/metal/lim.h | 20 + .../bsp/install/include/metal/lock.h | 62 +- .../bsp/install/include/metal/machine.h | 1082 +++- .../install/include/metal/machine/inline.h | 285 +- .../install/include/metal/machine/platform.h | 95 +- .../bsp/install/include/metal/memory.h | 40 +- .../bsp/install/include/metal/pmp.h | 40 +- .../bsp/install/include/metal/privilege.h | 138 +- .../bsp/install/include/metal/pwm.h | 162 + .../bsp/install/include/metal/rtc.h | 137 + .../bsp/install/include/metal/scrub.h | 13 + .../bsp/install/include/metal/shutdown.h | 11 +- .../bsp/install/include/metal/spi.h | 45 +- .../bsp/install/include/metal/switch.h | 17 +- .../bsp/install/include/metal/time.h | 21 + .../bsp/install/include/metal/timer.h | 5 +- .../bsp/install/include/metal/tty.h | 16 +- .../bsp/install/include/metal/uart.h | 149 +- .../bsp/install/include/metal/watchdog.h | 168 + .../bsp/metal-inline.h | 285 +- .../bsp/metal-platform.h | 95 +- .../bsp/metal.default.lds | 436 +- .../bsp/metal.freertos.lds | 327 + .../bsp/metal.h | 1082 +++- .../bsp/metal.ramrodata.lds | 306 + .../bsp/metal.scratchpad.lds | 294 + .../bsp/settings.mk | 13 + .../freedom-metal/.clang-format | 5 + .../freedom-metal/.travis.yml | 35 + .../freedom-metal/Doxyfile | 2537 ++++++++ .../freedom-metal/LICENSE | 3 + .../freedom-metal/LICENSE.Apache2 | 202 + .../freedom-metal/LICENSE.MIT | 21 + .../freedom-metal/Makefile.am | 238 + .../freedom-metal/Makefile.in | 1443 +++++ .../freedom-metal/README.md | 4 + .../freedom-metal/aclocal.m4 | 1268 ++++ .../freedom-metal/ar-lib | 270 + .../freedom-metal/build.wake | 150 + .../freedom-metal/compile | 347 ++ .../freedom-metal/config.guess | 1441 +++++ .../freedom-metal/config.sub | 1813 ++++++ .../freedom-metal/configure | 5491 +++++++++++++++++ .../freedom-metal/configure.ac | 97 + .../freedom-metal/depcomp | 791 +++ .../doc/link_to_docs_in_github.url | 5 - .../freedom-metal/gloss/crt0.S | 90 +- .../freedom-metal/gloss/nanosleep.c | 8 +- .../freedom-metal/gloss/synchronize_harts.c | 59 - .../freedom-metal/gloss/sys_access.c | 8 +- .../freedom-metal/gloss/sys_chdir.c | 8 +- .../freedom-metal/gloss/sys_chmod.c | 8 +- .../freedom-metal/gloss/sys_chown.c | 10 +- .../freedom-metal/gloss/sys_clock_gettime.c | 60 + .../freedom-metal/gloss/sys_close.c | 8 +- .../freedom-metal/gloss/sys_execve.c | 8 +- .../freedom-metal/gloss/sys_exit.c | 9 +- .../freedom-metal/gloss/sys_faccessat.c | 8 +- .../freedom-metal/gloss/sys_fork.c | 8 +- .../freedom-metal/gloss/sys_fstat.c | 8 +- .../freedom-metal/gloss/sys_fstatat.c | 8 +- .../freedom-metal/gloss/sys_ftime.c | 8 +- .../freedom-metal/gloss/sys_getcwd.c | 9 +- .../freedom-metal/gloss/sys_getpid.c | 6 +- .../freedom-metal/gloss/sys_gettimeofday.c | 7 +- .../freedom-metal/gloss/sys_isatty.c | 6 +- .../freedom-metal/gloss/sys_kill.c | 8 +- .../freedom-metal/gloss/sys_link.c | 7 +- .../freedom-metal/gloss/sys_lseek.c | 10 +- .../freedom-metal/gloss/sys_lstat.c | 7 +- .../freedom-metal/gloss/sys_open.c | 8 +- .../freedom-metal/gloss/sys_openat.c | 8 +- .../freedom-metal/gloss/sys_read.c | 10 +- .../freedom-metal/gloss/sys_sbrk.c | 52 +- .../freedom-metal/gloss/sys_stat.c | 8 +- .../freedom-metal/gloss/sys_sysconf.c | 16 +- .../freedom-metal/gloss/sys_times.c | 73 +- .../freedom-metal/gloss/sys_unlink.c | 8 +- .../freedom-metal/gloss/sys_utime.c | 8 +- .../freedom-metal/gloss/sys_wait.c | 7 +- .../freedom-metal/gloss/sys_write.c | 25 +- .../freedom-metal/install-git-hooks | 9 + .../freedom-metal/install-sh | 508 ++ .../freedom-metal/m4/ax_check_compile_flag.m4 | 53 + .../freedom-metal/metal/atomic.h | 259 + .../freedom-metal/metal/button.h | 16 +- .../freedom-metal/metal/cache.h | 56 +- .../freedom-metal/metal/clock.h | 52 +- .../freedom-metal/metal/compiler.h | 15 +- .../freedom-metal/metal/cpu.h | 132 +- .../freedom-metal/metal/csr.h | 32 + .../freedom-metal/metal/drivers/fixed-clock.h | 2 +- .../metal/drivers/fixed-factor-clock.h | 2 +- .../metal/drivers/riscv_clint0.h | 3 + .../freedom-metal/metal/drivers/riscv_cpu.h | 248 +- .../freedom-metal/metal/drivers/riscv_plic0.h | 8 +- .../metal/drivers/sifive_buserror0.h | 184 + .../metal/drivers/sifive_ccache0.h | 141 +- .../metal/drivers/sifive_clic0.h | 33 +- .../metal/drivers/sifive_fe310-g000_hfrosc.h | 4 +- .../metal/drivers/sifive_fe310-g000_lfrosc.h | 2 +- .../metal/drivers/sifive_fe310-g000_prci.h | 7 +- .../metal/drivers/sifive_fu540-c000_l2.h | 23 - .../metal/drivers/sifive_gpio-buttons.h | 4 +- .../metal/drivers/sifive_gpio-leds.h | 4 +- .../metal/drivers/sifive_gpio-switches.h | 4 +- .../metal/drivers/sifive_gpio0.h | 2 +- .../freedom-metal/metal/drivers/sifive_i2c0.h | 24 + .../metal/drivers/sifive_l2pf0.h | 78 + .../sifive_local-external-interrupts0.h | 1 - .../freedom-metal/metal/drivers/sifive_pwm0.h | 29 + .../freedom-metal/metal/drivers/sifive_rtc0.h | 3 +- .../metal/drivers/sifive_simuart0.h | 29 + .../freedom-metal/metal/drivers/sifive_spi0.h | 2 +- .../metal/drivers/sifive_test0.h | 1 - .../metal/drivers/sifive_uart0.h | 7 +- .../metal/drivers/sifive_wdog0.h | 4 +- .../freedom-metal/metal/drivers/ucb_htif0.h | 48 + .../freedom-metal/metal/gpio.h | 103 +- .../freedom-metal/metal/hpm.h | 146 + .../freedom-metal/metal/i2c.h | 112 + .../freedom-metal/metal/init.h | 130 + .../freedom-metal/metal/interrupt.h | 269 +- .../freedom-metal/metal/io.h | 9 +- .../freedom-metal/metal/itim.h | 3 +- .../freedom-metal/metal/led.h | 23 +- .../freedom-metal/metal/lim.h | 20 + .../freedom-metal/metal/lock.h | 37 +- .../freedom-metal/metal/memory.h | 36 +- .../freedom-metal/metal/pmp.h | 29 +- .../freedom-metal/metal/privilege.h | 136 +- .../freedom-metal/metal/pwm.h | 162 + .../freedom-metal/metal/rtc.h | 38 +- .../freedom-metal/metal/scrub.h | 13 + .../freedom-metal/metal/shutdown.h | 11 +- .../freedom-metal/metal/spi.h | 31 +- .../freedom-metal/metal/switch.h | 17 +- .../freedom-metal/metal/time.h | 3 + .../freedom-metal/metal/timer.h | 5 +- .../freedom-metal/metal/tty.h | 17 - .../freedom-metal/metal/uart.h | 133 +- .../freedom-metal/metal/watchdog.h | 107 +- .../freedom-metal/missing | 215 + .../freedom-metal/scripts/check-format | 19 + .../freedom-metal/scripts/format | 8 + .../freedom-metal/scripts/git-version | 21 + .../freedom-metal/src/atomic.c | 19 + .../freedom-metal/src/button.c | 12 +- .../freedom-metal/src/cache.c | 138 +- .../freedom-metal/src/clock.c | 18 +- .../freedom-metal/src/cpu.c | 52 +- .../freedom-metal/src/drivers/fixed-clock.c | 9 +- .../src/drivers/fixed-factor-clock.c | 17 +- .../freedom-metal/src/drivers/inline.c | 1 - .../freedom-metal/src/drivers/riscv_clint0.c | 259 +- .../freedom-metal/src/drivers/riscv_cpu.c | 859 ++- .../freedom-metal/src/drivers/riscv_plic0.c | 335 +- .../src/drivers/sifive_buserror0.c | 257 + .../src/drivers/sifive_ccache0.c | 322 +- .../freedom-metal/src/drivers/sifive_clic0.c | 741 ++- .../src/drivers/sifive_fe310-g000_hfrosc.c | 24 +- .../src/drivers/sifive_fe310-g000_hfxosc.c | 22 +- .../src/drivers/sifive_fe310-g000_lfrosc.c | 26 +- .../src/drivers/sifive_fe310-g000_pll.c | 348 +- .../src/drivers/sifive_fe310-g000_prci.c | 7 +- .../src/drivers/sifive_fu540-c000_l2.c | 84 - .../sifive_global-external-interrupts0.c | 139 +- .../src/drivers/sifive_gpio-buttons.c | 26 +- .../src/drivers/sifive_gpio-leds.c | 47 +- .../src/drivers/sifive_gpio-switches.c | 26 +- .../freedom-metal/src/drivers/sifive_gpio0.c | 268 +- .../freedom-metal/src/drivers/sifive_i2c0.c | 428 ++ .../freedom-metal/src/drivers/sifive_l2pf0.c | 164 + .../sifive_local-external-interrupts0.c | 128 +- .../freedom-metal/src/drivers/sifive_pwm0.c | 340 + .../freedom-metal/src/drivers/sifive_rtc0.c | 46 +- .../src/drivers/sifive_simuart0.c | 79 + .../freedom-metal/src/drivers/sifive_spi0.c | 203 +- .../freedom-metal/src/drivers/sifive_test0.c | 12 +- .../freedom-metal/src/drivers/sifive_trace.c | 9 +- .../freedom-metal/src/drivers/sifive_uart0.c | 209 +- .../freedom-metal/src/drivers/sifive_wdog0.c | 139 +- .../freedom-metal/src/drivers/ucb_htif0.c | 128 + .../freedom-metal/src/entry.S | 50 +- .../freedom-metal/src/gpio.c | 44 +- .../freedom-metal/src/hpm.c | 345 ++ .../freedom-metal/src/i2c.c | 28 + .../freedom-metal/src/init.c | 72 + .../freedom-metal/src/interrupt.c | 99 +- .../freedom-metal/src/led.c | 17 +- .../freedom-metal/src/memory.c | 31 +- .../freedom-metal/src/pmp.c | 317 +- .../freedom-metal/src/privilege.c | 78 +- .../freedom-metal/src/pwm.c | 36 + .../freedom-metal/src/rtc.c | 18 +- .../freedom-metal/src/scrub.S | 132 + .../freedom-metal/src/shutdown.c | 14 +- .../freedom-metal/src/spi.c | 13 +- .../freedom-metal/src/switch.c | 11 +- .../freedom-metal/src/synchronize_harts.c | 40 +- .../freedom-metal/src/time.c | 18 +- .../freedom-metal/src/timer.c | 71 +- .../freedom-metal/src/trap.S | 15 + .../freedom-metal/src/tty.c | 47 +- .../freedom-metal/src/uart.c | 33 +- .../freedom-metal/src/watchdog.c | 37 + .../full_demo/RegTest.S | 532 +- .../full_demo/main_full.c | 619 +- .../main.c | 542 +- lexicon.txt | 1 + 263 files changed, 36551 insertions(+), 6623 deletions(-) create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h delete mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.Apache2 create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.MIT create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.am create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.in create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/README.md create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/aclocal.m4 create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/ar-lib create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/build.wake create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/compile create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.guess create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.sub create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure.ac create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/depcomp delete mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url delete mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_clock_gettime.c create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-git-hooks create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-sh create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/m4/ax_check_compile_flag.m4 create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/atomic.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/csr.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_buserror0.h delete mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_i2c0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_l2pf0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_pwm0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_simuart0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/ucb_htif0.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/hpm.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/i2c.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/init.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lim.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pwm.h create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/scrub.h create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/missing create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/check-format create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/format create mode 100755 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/git-version create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/atomic.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_buserror0.c delete mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_i2c0.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_l2pf0.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_pwm0.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_simuart0.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/ucb_htif0.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/hpm.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/i2c.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/init.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pwm.c create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/scrub.S create mode 100644 FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/watchdog.c diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject index 648ec1c9f..baa18f1aa 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject @@ -1,176 +1,93 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project index f22f74077..f5bd48af5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project @@ -1,303 +1,303 @@ - - - RTOSDemo - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - FreeRTOS_Source - 2 - FREERTOS_ROOT/FreeRTOS/Source - - - full_demo/Common_Demo_Tasks - 2 - FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal - - - full_demo/Common_Demo_Tasks/include - 2 - FREERTOS_ROOT/FreeRTOS/Demo/Common/include - - - - - 1570727806810 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-event_groups.c - - - - 1570727806825 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-list.c - - - - 1570727806841 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-queue.c - - - - 1570727806841 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-stream_buffer.c - - - - 1570727806841 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-timers.c - - - - 1570727806856 - FreeRTOS_Source - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-tasks.c - - - - 1570727892841 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-event_groups.h - - - - 1570727892856 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-FreeRTOS.h - - - - 1570727892856 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-message_buffer.h - - - - 1570727892856 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-queue.h - - - - 1570727892872 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-semphr.h - - - - 1570727892872 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-stream_buffer.h - - - - 1570727892888 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-task.h - - - - 1570727892888 - FreeRTOS_Source/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-timers.h - - - - 1570727962643 - FreeRTOS_Source/portable - 9 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-MemMang - - - - 1570727962643 - FreeRTOS_Source/portable - 9 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-GCC - - - - 1571005814144 - full_demo/Common_Demo_Tasks - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-TimerDemo.c - - - - 1571005814150 - full_demo/Common_Demo_Tasks - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-blocktim.c - - - - 1571005814159 - full_demo/Common_Demo_Tasks - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-dynamic.c - - - - 1571005814167 - full_demo/Common_Demo_Tasks - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-TaskNotify.c - - - - 1570727992991 - FreeRTOS_Source/portable/GCC - 9 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-RISC-V - - - - 1570727979500 - FreeRTOS_Source/portable/MemMang - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-heap_4.c - - - - 1571005832815 - full_demo/Common_Demo_Tasks/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-TimerDemo.h - - - - 1571005832820 - full_demo/Common_Demo_Tasks/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-blocktim.h - - - - 1571005832824 - full_demo/Common_Demo_Tasks/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-dynamic.h - - - - 1571005832829 - full_demo/Common_Demo_Tasks/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-MessageBufferDemo.h - - - - 1571005832835 - full_demo/Common_Demo_Tasks/include - 5 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-TaskNotify.h - - - - 1570728021983 - FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions - 9 - - org.eclipse.ui.ide.multiFilter - 1.0-name-matches-false-false-RV32I_CLINT_no_extensions - - - - - - FREERTOS_ROOT - $%7BPARENT-3-PROJECT_LOC%7D - - - + + + RTOSDemo + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + FreeRTOS_Source + 2 + FREERTOS_ROOT/FreeRTOS/Source + + + full_demo/Common_Demo_Tasks + 2 + FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal + + + full_demo/Common_Demo_Tasks/include + 2 + FREERTOS_ROOT/FreeRTOS/Demo/Common/include + + + + + 1570727806810 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-event_groups.c + + + + 1570727806825 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-list.c + + + + 1570727806841 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-queue.c + + + + 1570727806841 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-stream_buffer.c + + + + 1570727806841 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-timers.c + + + + 1570727806856 + FreeRTOS_Source + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-tasks.c + + + + 1570727892841 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-event_groups.h + + + + 1570727892856 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-FreeRTOS.h + + + + 1570727892856 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-message_buffer.h + + + + 1570727892856 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-queue.h + + + + 1570727892872 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-semphr.h + + + + 1570727892872 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-stream_buffer.h + + + + 1570727892888 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-task.h + + + + 1570727892888 + FreeRTOS_Source/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-timers.h + + + + 1570727962643 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MemMang + + + + 1570727962643 + FreeRTOS_Source/portable + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-GCC + + + + 1571005814144 + full_demo/Common_Demo_Tasks + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-TimerDemo.c + + + + 1571005814150 + full_demo/Common_Demo_Tasks + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-blocktim.c + + + + 1571005814159 + full_demo/Common_Demo_Tasks + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-dynamic.c + + + + 1571005814167 + full_demo/Common_Demo_Tasks + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-TaskNotify.c + + + + 1570727992991 + FreeRTOS_Source/portable/GCC + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-RISC-V + + + + 1570727979500 + FreeRTOS_Source/portable/MemMang + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-heap_4.c + + + + 1571005832815 + full_demo/Common_Demo_Tasks/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-TimerDemo.h + + + + 1571005832820 + full_demo/Common_Demo_Tasks/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-blocktim.h + + + + 1571005832824 + full_demo/Common_Demo_Tasks/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-dynamic.h + + + + 1571005832829 + full_demo/Common_Demo_Tasks/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-MessageBufferDemo.h + + + + 1571005832835 + full_demo/Common_Demo_Tasks/include + 5 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-TaskNotify.h + + + + 1570728021983 + FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions + 9 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-RV32I_CLINT_no_extensions + + + + + + FREERTOS_ROOT + $%7BPARENT-3-PROJECT_LOC%7D + + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml index 49f601efa..b1990cea1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml @@ -1,26 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h index 6f5106c9a..9ea57c84f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h @@ -1,102 +1,105 @@ -/* - * FreeRTOS V202104.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ -#define CLINT_CTRL_ADDR ( 0x02000000UL ) -#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL ) -#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL ) -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 1 -#define configCPU_CLOCK_HZ ( 32768 ) -#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) -#define configMAX_PRIORITIES ( 7 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */ -#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 ) -#define configMAX_TASK_NAME_LEN ( 16 ) -#define configUSE_TRACE_FACILITY 0 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 0 -#define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_MALLOC_FAILED_HOOK 1 -#define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) - -/* Software timer definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) -#define configTIMER_QUEUE_LENGTH 8 -#define configTIMER_TASK_STACK_DEPTH ( 160 ) - -/* Task priorities. Allow these to be overridden. */ -#ifndef uartPRIMARY_PRIORITY - #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) -#endif - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_eTaskGetState 1 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 1 -#define INCLUDE_xTaskGetHandle 1 -#define INCLUDE_xSemaphoreGetMutexHolder 1 - -/* Normal assert() semantics without relying on the provision of an assert.h -header file. */ -void vAssertCalled( void ); -#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled() - -#endif /* FREERTOS_CONFIG_H */ +/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ +#define CLINT_CTRL_ADDR ( 0x02000000UL ) +#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL ) +#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL ) +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( 32768 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 7 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 8 +#define configTIMER_TASK_STACK_DEPTH ( 160 ) + +/* Task priorities. Allow these to be overridden. */ +#ifndef uartPRIMARY_PRIORITY + #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) +#endif + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +void vAssertCalled( void ); +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled() + +/* Map to the platform write function. */ +#define configPRINT_STRING( pcString ) write( STDOUT_FILENO, pcString, strlen( pcString ) ) + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url index 809b91304..34f8fc0bc 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url @@ -1,5 +1,5 @@ -[InternetShortcut] -URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html -IDList= -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,2 +[InternetShortcut] +URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c index de0a85bf3..e4e572e1f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c @@ -1,197 +1,197 @@ -/* - * FreeRTOS V202104.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -/****************************************************************************** - * NOTE 1: This project provides two demo applications. A simple blinky - * style project, and a more comprehensive test and demo application. The - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select - * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY - * in main.c. This file implements the simply blinky style version. - * - * NOTE 2: This file only contains the source code that is specific to the - * blinky demo. Generic functions, such FreeRTOS hook functions, and functions - * required to configure the hardware are defined in main.c. - ****************************************************************************** - * - * main_blinky() creates one queue, and two tasks. It then starts the - * scheduler. - * - * The Queue Send Task: - * The queue send task is implemented by the prvQueueSendTask() function in - * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly - * block for 1000 milliseconds, before sending the value 100 to the queue that - * was created within main_blinky(). Once the value is sent, the task loops - * back around to block for another 1000 milliseconds...and so on. - * - * The Queue Receive Task: - * The queue receive task is implemented by the prvQueueReceiveTask() function - * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly - * blocks on attempts to read data from the queue that was created within - * main_blinky(). When data is received, the task checks the value of the - * data, and if the value equals the expected 100, toggles an LED. The 'block - * time' parameter passed to the queue receive function specifies that the task - * should be held in the Blocked state indefinitely to wait for data to be - * available on the queue. The queue receive task will only leave the Blocked - * state when the queue send task writes to the queue. As the queue send task - * writes to the queue every 1000 milliseconds, the queue receive task leaves - * the Blocked state every 1000 milliseconds, and therefore toggles the LED - * every 200 milliseconds. - */ - -/* Standard includes. */ -#include -#include -#include - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" - -/* Priorities used by the tasks. */ -#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) - -/* The rate at which data is sent to the queue. The 200ms value is converted -to ticks using the pdMS_TO_TICKS() macro. */ -#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 ) - -/* The maximum number items the queue can hold. The priority of the receiving -task is above the priority of the sending task, so the receiving task will -preempt the sending task and remove the queue items each time the sending task -writes to the queue. Therefore the queue will never have more than one item in -it at any time, and even with a queue length of 1, the sending task will never -find the queue full. */ -#define mainQUEUE_LENGTH ( 1 ) - -/*-----------------------------------------------------------*/ - -/* - * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in - * main.c. - */ -void main_blinky( void ); - -/* - * The tasks as described in the comments at the top of this file. - */ -static void prvQueueReceiveTask( void *pvParameters ); -static void prvQueueSendTask( void *pvParameters ); - -/*-----------------------------------------------------------*/ - -/* The queue used by both tasks. */ -static QueueHandle_t xQueue = NULL; - -/*-----------------------------------------------------------*/ - -void main_blinky( void ) -{ - /* Create the queue. */ - xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); - - if( xQueue != NULL ) - { - /* Start the two tasks as described in the comments at the top of this - file. */ - xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ - "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ - configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ - NULL, /* The parameter passed to the task - not used in this case. */ - mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ - NULL ); /* The task handle is not required, so NULL is passed. */ - - xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); - - /* Start the tasks and timer running. */ - vTaskStartScheduler(); - } - - /* If all is well, the scheduler will now be running, and the following - line will never be reached. If the following line does execute, then - there was insufficient FreeRTOS heap memory available for the Idle and/or - timer tasks to be created. See the memory management section on the - FreeRTOS web site for more details on the FreeRTOS heap - http://www.freertos.org/a00111.html. */ - for( ;; ); -} -/*-----------------------------------------------------------*/ - -static void prvQueueSendTask( void *pvParameters ) -{ -TickType_t xNextWakeTime; -const unsigned long ulValueToSend = 100UL; -BaseType_t xReturned; - - /* Remove compiler warning about unused parameter. */ - ( void ) pvParameters; - - /* Initialise xNextWakeTime - this only needs to be done once. */ - xNextWakeTime = xTaskGetTickCount(); - - for( ;; ) - { - /* Place this task in the blocked state until it is time to run again. */ - vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); - - /* Send to the queue - causing the queue receive task to unblock and - toggle the LED. 0 is used as the block time so the sending operation - will not block - it shouldn't need to block as the queue should always - be empty at this point in the code. */ - xReturned = xQueueSend( xQueue, &ulValueToSend, 0U ); - configASSERT( xReturned == pdPASS ); - } -} -/*-----------------------------------------------------------*/ - -static void prvQueueReceiveTask( void *pvParameters ) -{ -unsigned long ulReceivedValue; -const unsigned long ulExpectedValue = 100UL; -extern void vToggleLED( void ); - - /* Remove compiler warning about unused parameter. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Wait until something arrives in the queue - this task will block - indefinitely provided INCLUDE_vTaskSuspend is set to 1 in - FreeRTOSConfig.h. */ - xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); - - /* To get here something must have been received from the queue, but - is it the expected value? If it is, toggle the LED. */ - if( ulReceivedValue == ulExpectedValue ) - { - vToggleLED(); - ulReceivedValue = 0U; - } - } -} -/*-----------------------------------------------------------*/ - +/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky + * style project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * blinky demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 1000 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 1000 milliseconds...and so on. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles an LED. The 'block + * time' parameter passed to the queue receive function specifies that the task + * should be held in the Blocked state indefinitely to wait for data to be + * available on the queue. The queue receive task will only leave the Blocked + * state when the queue send task writes to the queue. As the queue send task + * writes to the queue every 1000 milliseconds, the queue receive task leaves + * the Blocked state every 1000 milliseconds, and therefore toggles the LED + * every 200 milliseconds. + */ + +/* Standard includes. */ +#include +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Priorities used by the tasks. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the pdMS_TO_TICKS() macro. */ +#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 ) + +/* The maximum number items the queue can hold. The priority of the receiving +task is above the priority of the sending task, so the receiving task will +preempt the sending task and remove the queue items each time the sending task +writes to the queue. Therefore the queue will never have more than one item in +it at any time, and even with a queue length of 1, the sending task will never +find the queue full. */ +#define mainQUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* + * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in + * main.c. + */ +void main_blinky( void ); + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static QueueHandle_t xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + NULL, /* The parameter passed to the task - not used in this case. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the Idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details on the FreeRTOS heap + http://www.freertos.org/a00111.html. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +TickType_t xNextWakeTime; +const unsigned long ulValueToSend = 100UL; +BaseType_t xReturned; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xReturned = xQueueSend( xQueue, &ulValueToSend, 0U ); + configASSERT( xReturned == pdPASS ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; +const unsigned long ulExpectedValue = 100UL; +extern void vToggleLED( void ); + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == ulExpectedValue ) + { + vToggleLED(); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md new file mode 100644 index 000000000..f5abca5bf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md @@ -0,0 +1,13 @@ +HiFive1 Rev B is a low-cost, Arduino-compatible development board featuring the Freedom E310. It’s the best way to start prototyping and developing your RISC‑V applications. + +This target is ideal for getting familiar with the RISC-V ISA instruction set and the freedom-metal libraries. It supports: + +- 1 hart with RV32IMAC core +- 4 hardware breakpoints +- Physical Memory Protection with 8 regions +- 16 local interrupts signal that can be connected to off core complex devices +- Up to 127 PLIC interrupt signals that can be connected to off core complex devices, with 7 priority levels +- GPIO memory with 16 interrupt lines +- SPI memory with 1 interrupt line +- Serial port with 1 interrupt line +- 1 RGB LEDS diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts new file mode 100644 index 000000000..f68e58441 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts @@ -0,0 +1,262 @@ +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sifive,hifive1-revb"; + model = "sifive,hifive1-revb"; + 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,itim = <&itim>; + sifive,dtim = <&dtim>; + status = "okay"; + timebase-frequency = <16000000>; + 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>; + }; + lfrosc: clock@5 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + psdlfaltclk: clock@6 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + lfclk: clock@7 { + compatible = "sifive,fe310-g000,lfrosc"; + clocks = <&lfrosc &psdlfaltclk>; + clock-names = "lfrosc", "psdlfaltclk"; + reg = <&aon 0x70 &aon 0x7C>; + reg-names = "config", "mux"; + }; + debug-controller@0 { + compatible = "sifive,debug-011", "riscv,debug-011"; + interrupts-extended = <&hlic 65535>; + reg = <0x0 0x1000>; + reg-names = "control"; + }; + /* Missing: Error device */ + maskrom@1000 { + reg = <0x1000 0x2000>; + reg-names = "mem"; + }; + otp@20000 { + reg = <0x20000 0x2000 0x10010000 0x1000>; + reg-names = "mem", "control"; + }; + clint: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&hlic 3 &hlic 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + itim: itim@8000000 { + compatible = "sifive,itim0"; + reg = <0x8000000 0x2000>; + reg-names = "mem"; + }; + 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 = <52>; + }; + aon: aon@10000000 { + compatible = "sifive,aon0"; + reg = <0x10000000 0x8000>; + reg-names = "mem"; + interrupt-parent = <&plic>; + interrupts = <1 2>; + clocks = <&lfclk>; + }; + prci: prci@10008000 { + compatible = "sifive,fe310-g000,prci"; + reg = <0x10008000 0x8000>; + reg-names = "mem"; + }; + gpio0: gpio@10012000 { + compatible = "sifive,gpio0"; + interrupt-parent = <&plic>; + interrupts = <8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + 23 24 25 26 27 28 29 30 31 32 33 34 35 36 + 27 28 29>; + reg = <0x10012000 0x1000>; + reg-names = "control"; + }; + led@0 { + compatible = "sifive,gpio-leds"; + label = "LD0red"; + gpios = <&gpio0 22>; + linux,default-trigger = "none"; + }; + led@1 { + compatible = "sifive,gpio-leds"; + label = "LD0green"; + gpios = <&gpio0 19>; + linux,default-trigger = "none"; + }; + led@2 { + compatible = "sifive,gpio-leds"; + label = "LD0blue"; + gpios = <&gpio0 21>; + linux,default-trigger = "none"; + }; + uart0: serial@10013000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <3>; + reg = <0x10013000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x30000>; + }; + spi0: spi@10014000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <5>; + reg = <0x10014000 0x1000 0x20000000 0x7A120>; + reg-names = "control", "mem"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0>; + #address-cells = <1>; + #size-cells = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x20000000 0x424000>; + }; + }; + pwm0: pwm@10015000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <8>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <40 41 42 43>; + reg = <0x10015000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0F 0x0F>; + }; + i2c0: i2c@10016000 { + compatible = "sifive,i2c0"; + interrupt-parent = <&plic>; + interrupts = <52>; + reg = <0x10016000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x3000>; + }; + uart1: serial@10023000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <4>; + reg = <0x10023000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x840000>; + }; + spi1: spi@10024000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <6>; + reg = <0x10024000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0003C>; + }; + pwm1: pwm@10025000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <44 45 46 47>; + reg = <0x10025000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x780000 0x780000>; + }; + spi2: spi@10034000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <7>; + reg = <0x10034000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0xFC000000>; + }; + pwm2: pwm@10035000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <48 49 50 51>; + reg = <0x10035000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x3C00 0x3C00>; + }; + dtim: dtim@80000000 { + compatible = "sifive,dtim0"; + reg = <0x80000000 0x4000>; + reg-names = "mem"; + }; + }; +}; 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 index 970d3be72..098c25c4b 100644 --- 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 @@ -1,209 +1,10 @@ -/dts-v1/; - +/include/ "core.dts" / { - #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"; - }; - }; + chosen { + metal,entry = <&spi0 1 65536>; + metal,boothart = <&L6>; + stdout-path = "/soc/serial@10013000:115200"; + metal,itim = <&itim 0 0>; + metal,ram = <&dtim 0 0>; + }; }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd new file mode 100644 index 000000000..3ad2768bd --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd @@ -0,0 +1,3169 @@ + + + sifive_hifive1_revb + 0.1 + From sifive,hifive1-revb,model device generator + 8 + 32 + 32 + read-write + + + riscv_clint0_0 + From riscv,clint0,control peripheral generator + 0x2000000 + + 0 + 0x10000 + registers + + + + msip_0 + MSIP Register for hart 0 + 0x0 + + + mtimecmp_0 + MTIMECMP Register for hart 0 + 0x4000 + 64 + + + mtime + MTIME Register + 0xBFF8 + 64 + + + + + riscv_plic0_0 + From riscv,plic0,control peripheral generator + 0xC000000 + + 0 + 0x4000000 + registers + + + + priority_1 + PRIORITY Register for interrupt id 1 + 0x4 + + + priority_2 + PRIORITY Register for interrupt id 2 + 0x8 + + + priority_3 + PRIORITY Register for interrupt id 3 + 0xC + + + priority_4 + PRIORITY Register for interrupt id 4 + 0x10 + + + priority_5 + PRIORITY Register for interrupt id 5 + 0x14 + + + priority_6 + PRIORITY Register for interrupt id 6 + 0x18 + + + priority_7 + PRIORITY Register for interrupt id 7 + 0x1C + + + priority_8 + PRIORITY Register for interrupt id 8 + 0x20 + + + priority_9 + PRIORITY Register for interrupt id 9 + 0x24 + + + priority_10 + PRIORITY Register for interrupt id 10 + 0x28 + + + priority_11 + PRIORITY Register for interrupt id 11 + 0x2C + + + priority_12 + PRIORITY Register for interrupt id 12 + 0x30 + + + priority_13 + PRIORITY Register for interrupt id 13 + 0x34 + + + priority_14 + PRIORITY Register for interrupt id 14 + 0x38 + + + priority_15 + PRIORITY Register for interrupt id 15 + 0x3C + + + priority_16 + PRIORITY Register for interrupt id 16 + 0x40 + + + priority_17 + PRIORITY Register for interrupt id 17 + 0x44 + + + priority_18 + PRIORITY Register for interrupt id 18 + 0x48 + + + priority_19 + PRIORITY Register for interrupt id 19 + 0x4C + + + priority_20 + PRIORITY Register for interrupt id 20 + 0x50 + + + priority_21 + PRIORITY Register for interrupt id 21 + 0x54 + + + priority_22 + PRIORITY Register for interrupt id 22 + 0x58 + + + priority_23 + PRIORITY Register for interrupt id 23 + 0x5C + + + priority_24 + PRIORITY Register for interrupt id 24 + 0x60 + + + priority_25 + PRIORITY Register for interrupt id 25 + 0x64 + + + priority_26 + PRIORITY Register for interrupt id 26 + 0x68 + + + priority_27 + PRIORITY Register for interrupt id 27 + 0x6C + + + priority_28 + PRIORITY Register for interrupt id 28 + 0x70 + + + priority_29 + PRIORITY Register for interrupt id 29 + 0x74 + + + priority_30 + PRIORITY Register for interrupt id 30 + 0x78 + + + priority_31 + PRIORITY Register for interrupt id 31 + 0x7C + + + priority_32 + PRIORITY Register for interrupt id 32 + 0x80 + + + priority_33 + PRIORITY Register for interrupt id 33 + 0x84 + + + priority_34 + PRIORITY Register for interrupt id 34 + 0x88 + + + priority_35 + PRIORITY Register for interrupt id 35 + 0x8C + + + priority_36 + PRIORITY Register for interrupt id 36 + 0x90 + + + priority_37 + PRIORITY Register for interrupt id 37 + 0x94 + + + priority_38 + PRIORITY Register for interrupt id 38 + 0x98 + + + priority_39 + PRIORITY Register for interrupt id 39 + 0x9C + + + priority_40 + PRIORITY Register for interrupt id 40 + 0xA0 + + + priority_41 + PRIORITY Register for interrupt id 41 + 0xA4 + + + priority_42 + PRIORITY Register for interrupt id 42 + 0xA8 + + + priority_43 + PRIORITY Register for interrupt id 43 + 0xAC + + + priority_44 + PRIORITY Register for interrupt id 44 + 0xB0 + + + priority_45 + PRIORITY Register for interrupt id 45 + 0xB4 + + + priority_46 + PRIORITY Register for interrupt id 46 + 0xB8 + + + priority_47 + PRIORITY Register for interrupt id 47 + 0xBC + + + priority_48 + PRIORITY Register for interrupt id 48 + 0xC0 + + + priority_49 + PRIORITY Register for interrupt id 49 + 0xC4 + + + priority_50 + PRIORITY Register for interrupt id 50 + 0xC8 + + + priority_51 + PRIORITY Register for interrupt id 51 + 0xCC + + + priority_52 + PRIORITY Register for interrupt id 52 + 0xD0 + + + pending_0 + PENDING Register for interrupt ids 31 to 0 + 0x1000 + + + pending_1 + PENDING Register for interrupt ids 52 to 32 + 0x1004 + + + enable_0_0 + ENABLE Register for interrupt ids 31 to 0 for hart 0 + 0x2000 + + + enable_1_0 + ENABLE Register for interrupt ids 52 to 32 for hart 0 + 0x2004 + + + threshold_0 + PRIORITY THRESHOLD Register for hart 0 + 0x200000 + + + claimplete_0 + CLAIM and COMPLETE Register for hart 0 + 0x200004 + + + + + sifive_aon0_0 + From sifive,aon0,mem peripheral generator + 0x10000000 + + 0 + 0x8000 + registers + + + + backup_0 + Backup Register 0 + 0x80 + + + backup_1 + Backup Register 1 + 0x84 + + + backup_2 + Backup Register 2 + 0x88 + + + backup_3 + Backup Register 3 + 0x8C + + + backup_4 + Backup Register 4 + 0x90 + + + backup_5 + Backup Register 5 + 0x94 + + + backup_6 + Backup Register 6 + 0x98 + + + backup_7 + Backup Register 7 + 0x9C + + + backup_8 + Backup Register 8 + 0xA0 + + + backup_9 + Backup Register 9 + 0xA4 + + + backup_10 + Backup Register 10 + 0xA8 + + + backup_11 + Backup Register 11 + 0xAC + + + backup_12 + Backup Register 12 + 0xB0 + + + backup_13 + Backup Register 13 + 0xB4 + + + backup_14 + Backup Register 14 + 0xB8 + + + backup_15 + Backup Register 15 + 0xBC + + + wdogcfg + wdog Configuration + 0x0 + + + wdogscale + Counter scale value. + [3:0] + read-write + + + wdogrsten + Controls whether the comparator output can set the wdogrst bit and hence cause a full reset. + [8:8] + read-write + + + wdogzerocmp + Reset counter to zero after match. + [9:9] + read-write + + + wdogenalways + Enable Always - run continuously + [12:12] + read-write + + + wdogcoreawake + Increment the watchdog counter if the processor is not asleep + [13:13] + read-write + + + wdogip0 + Interrupt 0 Pending + [28:28] + read-write + + + + + wdogcount + Counter Register + 0x8 + + + wdogs + Scaled value of Counter + 0x10 + + + wdogfeed + Feed register + 0x18 + + + wdogkey + Key Register + 0x1C + + + wdogcmp0 + Comparator 0 + 0x20 + + + rtccfg + rtc Configuration + 0x40 + + + rtcscale + Counter scale value. + [3:0] + read-write + + + rtcenalways + Enable Always - run continuously + [12:12] + read-write + + + rtcip0 + Interrupt 0 Pending + [28:28] + read-write + + + + + rtccountlo + Low bits of Counter + 0x48 + + + rtccounthi + High bits of Counter + 0x4C + + + rtcs + Scaled value of Counter + 0x50 + + + rtccmp0 + Comparator 0 + 0x60 + + + pmuwakeupi0 + Wakeup program instruction 0 + 0x100 + + + pmuwakeupi1 + Wakeup program instruction 1 + 0x104 + + + pmuwakeupi2 + Wakeup program instruction 2 + 0x108 + + + pmuwakeupi3 + Wakeup program instruction 3 + 0x10C + + + pmuwakeupi4 + Wakeup program instruction 4 + 0x110 + + + pmuwakeupi5 + Wakeup program instruction 5 + 0x114 + + + pmuwakeupi6 + Wakeup program instruction 6 + 0x118 + + + pmuwakeupi7 + Wakeup program instruction 7 + 0x11C + + + pmusleepi0 + Sleep program instruction 0 + 0x120 + + + pmusleepi1 + Sleep program instruction 1 + 0x124 + + + pmusleepi2 + Sleep program instruction 2 + 0x128 + + + pmusleepi3 + Sleep program instruction 3 + 0x12C + + + pmusleepi4 + Sleep program instruction 4 + 0x130 + + + pmusleepi5 + Sleep program instruction 5 + 0x134 + + + pmusleepi6 + Sleep program instruction 6 + 0x138 + + + pmusleepi7 + Sleep program instruction 7 + 0x13C + + + pmuie + PMU Interrupt Enables + 0x140 + + + pmucause + PMU Wakeup Cause + 0x144 + + + pmusleep + Initiate PMU Sleep Sequence + 0x148 + + + pmukey + PMU Key. Reads as 1 when PMU is unlocked + 0x14C + + + aoncfg + AON Block Configuration Information + 0x300 + + + has_bandgap + Bandgap feature is present + [0:0] + read-only + + + has_bod + Brownout detector feature is present + [1:1] + read-only + + + has_lfrosc + Low Frequency Ring Oscillator feature is present + [2:2] + read-only + + + has_lfrcosc + Low Frequency RC Oscillator feature is present + [3:3] + read-only + + + has_lfxosc + Low Frequency Crystal Oscillator feature is present + [4:4] + read-only + + + has_por + Power-On-Reset feature is present + [5:5] + read-only + + + has_ldo + Low Dropout Regulator feature is present + [6:6] + read-only + + + + + lfrosccfg + Ring Oscillator Configuration and Status + 0x70 + + + lfroscdiv + Ring Oscillator Divider Register + [5:0] + read-write + + + lfrosctrim + Ring Oscillator Trim Register + [20:16] + read-write + + + lfroscen + Ring Oscillator Enable + [30:30] + read-write + + + lfroscrdy + Ring Oscillator Ready + [31:31] + read-only + + + + + lfclkmux + Low-Frequency Clock Mux Control and Status + 0x7C + + + lfextclk_sel + Low Frequency Clock Source Selector + [0:0] + read-write + + + internal + Use internal LF clock source + 0 + + + external + Use external LF clock source + 1 + + + + + lfextclk_mux_status + Setting of the aon_lfclksel pin + [31:31] + read-only + + + external + Use external LF clock source + 0 + + + sw + Use clock source selected by lfextclk_sel + 1 + + + + + + + + + sifive_fe310_g000_prci_0 + From sifive,fe310-g000,prci,mem peripheral generator + 0x10008000 + + 0 + 0x8000 + registers + + + + hfrosccfg + Ring Oscillator Configuration and Status + 0x0 + + + hfroscdiv + Ring Oscillator Divider Register + [5:0] + read-write + + + hfrosctrim + Ring Oscillator Trim Register + [20:16] + read-write + + + hfroscen + Ring Oscillator Enable + [30:30] + read-write + + + hfroscrdy + Ring Oscillator Ready + [31:31] + read-only + + + + + hfxosccfg + Crystal Oscillator Configuration and Status + 0x4 + + + hfxoscen + Crystal Oscillator Enable + [30:30] + read-write + + + hfxoscrdy + Crystal Oscillator Ready + [31:31] + read-only + + + + + pllcfg + PLL Configuration and Status + 0x8 + + + pllr + PLL R Value + [2:0] + read-write + + + pllf + PLL F Value + [9:4] + read-write + + + pllq + PLL Q Value + [11:10] + read-write + + + pllsel + PLL Select + [16:16] + read-write + + + pllrefsel + PLL Reference Select + [17:17] + read-write + + + pllbypass + PLL Bypass + [18:18] + read-write + + + plllock + PLL Lock + [31:31] + read-only + + + + + plloutdiv + PLL Final Divide Configuration + 0xC + + + plloutdiv + PLL Final Divider Value + [5:0] + read-write + + + plloutdivby1 + PLL Final Divide By 1 + [13:8] + read-write + + + + + procmoncfg + Process Monitor Configuration and Status + 0xF0 + + + procmon_div_sel + Proccess Monitor Divider + [4:0] + read-write + + + procmon_delay_sel + Process Monitor Delay Selector + [12:8] + read-write + + + procmon_en + Process Monitor Enable + [16:16] + read-write + + + procomon_sel + Process Monitor Select + [25:24] + read-write + + + + + + + sifive_gpio0_0 + From sifive,gpio0,control peripheral generator + 0x10012000 + + 0 + 0x1000 + registers + + + + input_val + Pin value + 0x0 + + + input_en + Pin input enable + 0x4 + + + output_en + Pin output enable + 0x8 + + + output_val + Output value + 0xC + + + pue + Internal pull-up enable + 0x10 + + + ds + Pin drive strength + 0x14 + + + rise_ie + Rise interrupt enable + 0x18 + + + rise_ip + Rise interrupt pending + 0x1C + + + fall_ie + Fall interrupt enable + 0x20 + + + fall_ip + Fall interrupt pending + 0x24 + + + high_ie + High interrupt enable + 0x28 + + + high_ip + High interrupt pending + 0x2C + + + low_ie + Low interrupt enable + 0x30 + + + low_ip + Low interrupt pending + 0x34 + + + iof_en + I/O function enable + 0x38 + + + iof_sel + I/O function select + 0x3C + + + out_xor + Output XOR (invert) + 0x40 + + + + + sifive_uart0_0 + From sifive,uart0,control peripheral generator + 0x10013000 + + 0 + 0x1000 + registers + + + + txdata + Transmit data register + 0x0 + + + data + Transmit data + [7:0] + read-write + + + full + Transmit FIFO full + [31:31] + read-only + + + + + rxdata + Receive data register + 0x4 + + + data + Received data + [7:0] + read-only + + + empty + Receive FIFO empty + [31:31] + read-only + + + + + txctrl + Transmit control register + 0x8 + + + txen + Transmit enable + [0:0] + read-write + + + nstop + Number of stop bits + [1:1] + read-write + + + txcnt + Transmit watermark level + [18:16] + read-write + + + + + rxctrl + Receive control register + 0xC + + + rxen + Receive enable + [0:0] + read-write + + + rxcnt + Receive watermark level + [18:16] + read-write + + + + + ie + UART interrupt enable + 0x10 + + + txwm + Transmit watermark interrupt enable + [0:0] + read-write + + + rxwm + Receive watermark interrupt enable + [1:1] + read-write + + + + + ip + UART interrupt pending + 0x14 + + + txwm + Transmit watermark interrupt pending + [0:0] + read-only + + + rxwm + Receive watermark interrupt pending + [1:1] + read-only + + + + + div + Baud rate divisor + 0x18 + + + div + Baud rate divisor. + [15:0] + read-write + + + + + + + sifive_spi0_0 + From sifive,spi0,control peripheral generator + 0x10014000 + + 0 + 0x1000 + registers + + + + sckdiv + Serial clock divisor + 0x0 + + + div + Divisor for serial clock. + [11:0] + read-write + + + + + sckmode + Serial clock mode + 0x4 + + + pha + Serial clock phase + [0:0] + read-write + + + pol + Serial clock polarity + [1:1] + read-write + + + + + csid + Chip select ID + 0x10 + + + csid + Chip select ID. + [31:0] + read-write + + + + + csdef + Chip select default + 0x14 + + + csdef + Chip select default value. Reset to all-1s. + [31:0] + read-write + + + + + csmode + Chip select mode + 0x18 + + + mode + Chip select mode + [1:0] + read-write + + + + + delay0 + Delay control 0 + 0x28 + + + cssck + CS to SCK Delay + [7:0] + read-write + + + sckcs + SCK to CS Delay + [23:16] + read-write + + + + + delay1 + Delay control 1 + 0x2C + + + intercs + Minimum CS inactive time + [7:0] + read-write + + + interxfr + Maximum interframe delay + [23:16] + read-write + + + + + extradel + SPI extra sampling delay to increase the SPI frequency + 0x38 + + + coarse + Coarse grain sample delay (multiples of system clocks) + [11:0] + read-write + + + fine + Fine grain sample delay (multiples of process-specific buffer delay) + [16:12] + read-write + + + + + sampledel + Number of delay stages from slave to the SPI controller + 0x3C + + + sd + Number of delay stages from slave to SPI controller + [4:0] + read-write + + + + + fmt + Frame format + 0x40 + + + proto + SPI protocol + [1:0] + read-write + + + endian + SPI endianness + [2:2] + read-write + + + dir + SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise. + [3:3] + read-write + + + len + Number of bits per frame + [19:16] + read-write + + + + + txdata + Tx FIFO Data + 0x48 + + + data + Transmit data + [7:0] + read-write + + + full + FIFO full flag + [31:31] + read-only + + + + + rxdata + Rx FIFO data + 0x4C + + + data + Received data + [7:0] + read-only + + + empty + FIFO empty flag + [31:31] + read-write + + + + + txmark + Tx FIFO watermark + 0x50 + + + txmark + Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise. + [2:0] + read-write + + + + + rxmark + Rx FIFO watermark + 0x54 + + + rxmark + Receive watermark + [2:0] + read-write + + + + + fctrl + SPI flash interface control + 0x60 + + + en + SPI Flash Mode Select + [0:0] + read-write + + + + + ffmt + SPI flash instruction format + 0x64 + + + cmd_en + Enable sending of command + [0:0] + read-write + + + addr_len + Number of address bytes (0 to 4) + [3:1] + read-write + + + pad_cnt + Number of dummy cycles + [7:4] + read-write + + + cmd_proto + Protocol for transmitting command + [9:8] + read-write + + + addr_proto + Protocol for transmitting address and padding + [11:10] + read-write + + + data_proto + Protocol for receiving data bytes + [13:12] + read-write + + + cmd_code + Value of command byte + [23:16] + read-write + + + pad_code + First 8 bits to transmit during dummy cycles + [31:24] + read-write + + + + + ie + SPI interrupt enable + 0x70 + + + txwm + Transmit watermark enable + [0:0] + read-write + + + rxwm + Receive watermark enable + [1:1] + read-write + + + + + ip + SPI interrupt pending + 0x74 + + + txwm + Transmit watermark pending + [0:0] + read-only + + + rxwm + Receive watermark pending + [1:1] + read-only + + + + + + + sifive_pwm0_0 + From sifive,pwm0,control peripheral generator + 0x10015000 + + 0 + 0x1000 + registers + + + + pwmcfg + PWM configuration register + 0x0 + + + pwmscale + PWM Counter scale + [3:0] + read-write + + + pwmsticky + PWM Sticky - disallow clearing pwmcmpXip bits + [8:8] + read-write + + + pwmzerocmp + PWM Zero - counter resets to zero after match + [9:9] + read-write + + + pwmdeglitch + PWM Deglitch - latch pwmcmpXip within same cycle + [10:10] + read-write + + + pwmenalways + PWM enable always - run continuously + [12:12] + read-write + + + pwmenoneshot + PWM enable one shot - run one cycle + [13:13] + read-write + + + pwmcmp0center + PWM0 Compare Center + [16:16] + read-write + + + pwmcmp1center + PWM1 Compare Center + [17:17] + read-write + + + pwmcmp2center + PWM2 Compare Center + [18:18] + read-write + + + pwmcmp3center + PWM3 Compare Center + [19:19] + read-write + + + pwmcmp0invert + PWM0 Invert + [20:20] + read-write + + + pwmcmp1invert + PWM1 Invert + [21:21] + read-write + + + pwmcmp2invert + PWM2 Invert + [22:22] + read-write + + + pwmcmp3invert + PWM3 Invert + [23:23] + read-write + + + pwmcmp0gang + PWM0/PWM1 Compare Gang + [24:24] + read-write + + + pwmcmp1gang + PWM1/PWM2 Compare Gang + [25:25] + read-write + + + pwmcmp2gang + PWM2/PWM3 Compare Gang + [26:26] + read-write + + + pwmcmp3gang + PWM3/PWM0 Compare Gang + [27:27] + read-write + + + pwmcmp0ip + PWM0 Interrupt Pending + [28:28] + read-write + + + pwmcmp1ip + PWM1 Interrupt Pending + [29:29] + read-write + + + pwmcmp2ip + PWM2 Interrupt Pending + [30:30] + read-write + + + pwmcmp3ip + PWM3 Interrupt Pending + [31:31] + read-write + + + + + pwmcount + PWM count register + 0x8 + + + pwmcount + PWM count register. + [30:0] + read-write + + + + + pwms + Scaled PWM count register + 0x10 + + + pwms + Scaled PWM count register. + [15:0] + read-write + + + + + pwmcmp0 + PWM 0 compare register + 0x20 + + + pwmcmp0 + PWM 0 Compare Value + [15:0] + read-write + + + + + pwmcmp1 + PWM 1 compare register + 0x24 + + + pwmcmp1 + PWM 1 Compare Value + [15:0] + read-write + + + + + pwmcmp2 + PWM 2 compare register + 0x28 + + + pwmcmp2 + PWM 2 Compare Value + [15:0] + read-write + + + + + pwmcmp3 + PWM 3 compare register + 0x2C + + + pwmcmp3 + PWM 3 Compare Value + [15:0] + read-write + + + + + + + sifive_i2c0_0 + From sifive,i2c0,control peripheral generator + 0x10016000 + + 0 + 0x1000 + registers + + + + prescale_low + Clock Prescale register lo-byte + 0x0 + + + prescale_high + Clock Prescale register hi-byte + 0x4 + + + control + Control register + 0x8 + + + en + I2C core enable bit + [6:6] + read-write + + + ien + I2C core interrupt enable bit + [7:7] + read-write + + + + + transmit__receive + Transmit and receive data byte register + 0xC + + + command__status + Command write and status read register + 0x10 + + + wr_iack__rd_if + Clear interrupt and Interrupt pending + [0:0] + read-write + + + wr_res__rd_tip + Reserved and Transfer in progress + [1:1] + read-write + + + wr_res__rd_res + Reserved and Reserved + [2:2] + read-write + + + wr_ack__rd_res + Send ACK/NACK and Reserved + [3:3] + read-write + + + wr_txd__rd_res + Transmit data and Reserved + [4:4] + read-write + + + wr_rxd__rd_al + Receive data and Arbitration lost + [5:5] + read-write + + + wr_sto__rd_busy + Generate stop and I2C bus busy + [6:6] + read-write + + + wr_sta__rd_rxack + Generate start and Got ACK/NACK + [7:7] + read-write + + + + + + + sifive_uart0_1 + From sifive,uart0,control peripheral generator + 0x10023000 + + 0 + 0x1000 + registers + + + + txdata + Transmit data register + 0x0 + + + data + Transmit data + [7:0] + read-write + + + full + Transmit FIFO full + [31:31] + read-only + + + + + rxdata + Receive data register + 0x4 + + + data + Received data + [7:0] + read-only + + + empty + Receive FIFO empty + [31:31] + read-only + + + + + txctrl + Transmit control register + 0x8 + + + txen + Transmit enable + [0:0] + read-write + + + nstop + Number of stop bits + [1:1] + read-write + + + txcnt + Transmit watermark level + [18:16] + read-write + + + + + rxctrl + Receive control register + 0xC + + + rxen + Receive enable + [0:0] + read-write + + + rxcnt + Receive watermark level + [18:16] + read-write + + + + + ie + UART interrupt enable + 0x10 + + + txwm + Transmit watermark interrupt enable + [0:0] + read-write + + + rxwm + Receive watermark interrupt enable + [1:1] + read-write + + + + + ip + UART interrupt pending + 0x14 + + + txwm + Transmit watermark interrupt pending + [0:0] + read-only + + + rxwm + Receive watermark interrupt pending + [1:1] + read-only + + + + + div + Baud rate divisor + 0x18 + + + div + Baud rate divisor. + [15:0] + read-write + + + + + + + sifive_spi0_1 + From sifive,spi0,control peripheral generator + 0x10024000 + + 0 + 0x1000 + registers + + + + sckdiv + Serial clock divisor + 0x0 + + + div + Divisor for serial clock. + [11:0] + read-write + + + + + sckmode + Serial clock mode + 0x4 + + + pha + Serial clock phase + [0:0] + read-write + + + pol + Serial clock polarity + [1:1] + read-write + + + + + csid + Chip select ID + 0x10 + + + csid + Chip select ID. + [31:0] + read-write + + + + + csdef + Chip select default + 0x14 + + + csdef + Chip select default value. Reset to all-1s. + [31:0] + read-write + + + + + csmode + Chip select mode + 0x18 + + + mode + Chip select mode + [1:0] + read-write + + + + + delay0 + Delay control 0 + 0x28 + + + cssck + CS to SCK Delay + [7:0] + read-write + + + sckcs + SCK to CS Delay + [23:16] + read-write + + + + + delay1 + Delay control 1 + 0x2C + + + intercs + Minimum CS inactive time + [7:0] + read-write + + + interxfr + Maximum interframe delay + [23:16] + read-write + + + + + extradel + SPI extra sampling delay to increase the SPI frequency + 0x38 + + + coarse + Coarse grain sample delay (multiples of system clocks) + [11:0] + read-write + + + fine + Fine grain sample delay (multiples of process-specific buffer delay) + [16:12] + read-write + + + + + sampledel + Number of delay stages from slave to the SPI controller + 0x3C + + + sd + Number of delay stages from slave to SPI controller + [4:0] + read-write + + + + + fmt + Frame format + 0x40 + + + proto + SPI protocol + [1:0] + read-write + + + endian + SPI endianness + [2:2] + read-write + + + dir + SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise. + [3:3] + read-write + + + len + Number of bits per frame + [19:16] + read-write + + + + + txdata + Tx FIFO Data + 0x48 + + + data + Transmit data + [7:0] + read-write + + + full + FIFO full flag + [31:31] + read-only + + + + + rxdata + Rx FIFO data + 0x4C + + + data + Received data + [7:0] + read-only + + + empty + FIFO empty flag + [31:31] + read-write + + + + + txmark + Tx FIFO watermark + 0x50 + + + txmark + Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise. + [2:0] + read-write + + + + + rxmark + Rx FIFO watermark + 0x54 + + + rxmark + Receive watermark + [2:0] + read-write + + + + + fctrl + SPI flash interface control + 0x60 + + + en + SPI Flash Mode Select + [0:0] + read-write + + + + + ffmt + SPI flash instruction format + 0x64 + + + cmd_en + Enable sending of command + [0:0] + read-write + + + addr_len + Number of address bytes (0 to 4) + [3:1] + read-write + + + pad_cnt + Number of dummy cycles + [7:4] + read-write + + + cmd_proto + Protocol for transmitting command + [9:8] + read-write + + + addr_proto + Protocol for transmitting address and padding + [11:10] + read-write + + + data_proto + Protocol for receiving data bytes + [13:12] + read-write + + + cmd_code + Value of command byte + [23:16] + read-write + + + pad_code + First 8 bits to transmit during dummy cycles + [31:24] + read-write + + + + + ie + SPI interrupt enable + 0x70 + + + txwm + Transmit watermark enable + [0:0] + read-write + + + rxwm + Receive watermark enable + [1:1] + read-write + + + + + ip + SPI interrupt pending + 0x74 + + + txwm + Transmit watermark pending + [0:0] + read-only + + + rxwm + Receive watermark pending + [1:1] + read-only + + + + + + + sifive_pwm0_1 + From sifive,pwm0,control peripheral generator + 0x10025000 + + 0 + 0x1000 + registers + + + + pwmcfg + PWM configuration register + 0x0 + + + pwmscale + PWM Counter scale + [3:0] + read-write + + + pwmsticky + PWM Sticky - disallow clearing pwmcmpXip bits + [8:8] + read-write + + + pwmzerocmp + PWM Zero - counter resets to zero after match + [9:9] + read-write + + + pwmdeglitch + PWM Deglitch - latch pwmcmpXip within same cycle + [10:10] + read-write + + + pwmenalways + PWM enable always - run continuously + [12:12] + read-write + + + pwmenoneshot + PWM enable one shot - run one cycle + [13:13] + read-write + + + pwmcmp0center + PWM0 Compare Center + [16:16] + read-write + + + pwmcmp1center + PWM1 Compare Center + [17:17] + read-write + + + pwmcmp2center + PWM2 Compare Center + [18:18] + read-write + + + pwmcmp3center + PWM3 Compare Center + [19:19] + read-write + + + pwmcmp0invert + PWM0 Invert + [20:20] + read-write + + + pwmcmp1invert + PWM1 Invert + [21:21] + read-write + + + pwmcmp2invert + PWM2 Invert + [22:22] + read-write + + + pwmcmp3invert + PWM3 Invert + [23:23] + read-write + + + pwmcmp0gang + PWM0/PWM1 Compare Gang + [24:24] + read-write + + + pwmcmp1gang + PWM1/PWM2 Compare Gang + [25:25] + read-write + + + pwmcmp2gang + PWM2/PWM3 Compare Gang + [26:26] + read-write + + + pwmcmp3gang + PWM3/PWM0 Compare Gang + [27:27] + read-write + + + pwmcmp0ip + PWM0 Interrupt Pending + [28:28] + read-write + + + pwmcmp1ip + PWM1 Interrupt Pending + [29:29] + read-write + + + pwmcmp2ip + PWM2 Interrupt Pending + [30:30] + read-write + + + pwmcmp3ip + PWM3 Interrupt Pending + [31:31] + read-write + + + + + pwmcount + PWM count register + 0x8 + + + pwmcount + PWM count register. + [30:0] + read-write + + + + + pwms + Scaled PWM count register + 0x10 + + + pwms + Scaled PWM count register. + [15:0] + read-write + + + + + pwmcmp0 + PWM 0 compare register + 0x20 + + + pwmcmp0 + PWM 0 Compare Value + [15:0] + read-write + + + + + pwmcmp1 + PWM 1 compare register + 0x24 + + + pwmcmp1 + PWM 1 Compare Value + [15:0] + read-write + + + + + pwmcmp2 + PWM 2 compare register + 0x28 + + + pwmcmp2 + PWM 2 Compare Value + [15:0] + read-write + + + + + pwmcmp3 + PWM 3 compare register + 0x2C + + + pwmcmp3 + PWM 3 Compare Value + [15:0] + read-write + + + + + + + sifive_spi0_2 + From sifive,spi0,control peripheral generator + 0x10034000 + + 0 + 0x1000 + registers + + + + sckdiv + Serial clock divisor + 0x0 + + + div + Divisor for serial clock. + [11:0] + read-write + + + + + sckmode + Serial clock mode + 0x4 + + + pha + Serial clock phase + [0:0] + read-write + + + pol + Serial clock polarity + [1:1] + read-write + + + + + csid + Chip select ID + 0x10 + + + csid + Chip select ID. + [31:0] + read-write + + + + + csdef + Chip select default + 0x14 + + + csdef + Chip select default value. Reset to all-1s. + [31:0] + read-write + + + + + csmode + Chip select mode + 0x18 + + + mode + Chip select mode + [1:0] + read-write + + + + + delay0 + Delay control 0 + 0x28 + + + cssck + CS to SCK Delay + [7:0] + read-write + + + sckcs + SCK to CS Delay + [23:16] + read-write + + + + + delay1 + Delay control 1 + 0x2C + + + intercs + Minimum CS inactive time + [7:0] + read-write + + + interxfr + Maximum interframe delay + [23:16] + read-write + + + + + extradel + SPI extra sampling delay to increase the SPI frequency + 0x38 + + + coarse + Coarse grain sample delay (multiples of system clocks) + [11:0] + read-write + + + fine + Fine grain sample delay (multiples of process-specific buffer delay) + [16:12] + read-write + + + + + sampledel + Number of delay stages from slave to the SPI controller + 0x3C + + + sd + Number of delay stages from slave to SPI controller + [4:0] + read-write + + + + + fmt + Frame format + 0x40 + + + proto + SPI protocol + [1:0] + read-write + + + endian + SPI endianness + [2:2] + read-write + + + dir + SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise. + [3:3] + read-write + + + len + Number of bits per frame + [19:16] + read-write + + + + + txdata + Tx FIFO Data + 0x48 + + + data + Transmit data + [7:0] + read-write + + + full + FIFO full flag + [31:31] + read-only + + + + + rxdata + Rx FIFO data + 0x4C + + + data + Received data + [7:0] + read-only + + + empty + FIFO empty flag + [31:31] + read-write + + + + + txmark + Tx FIFO watermark + 0x50 + + + txmark + Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise. + [2:0] + read-write + + + + + rxmark + Rx FIFO watermark + 0x54 + + + rxmark + Receive watermark + [2:0] + read-write + + + + + fctrl + SPI flash interface control + 0x60 + + + en + SPI Flash Mode Select + [0:0] + read-write + + + + + ffmt + SPI flash instruction format + 0x64 + + + cmd_en + Enable sending of command + [0:0] + read-write + + + addr_len + Number of address bytes (0 to 4) + [3:1] + read-write + + + pad_cnt + Number of dummy cycles + [7:4] + read-write + + + cmd_proto + Protocol for transmitting command + [9:8] + read-write + + + addr_proto + Protocol for transmitting address and padding + [11:10] + read-write + + + data_proto + Protocol for receiving data bytes + [13:12] + read-write + + + cmd_code + Value of command byte + [23:16] + read-write + + + pad_code + First 8 bits to transmit during dummy cycles + [31:24] + read-write + + + + + ie + SPI interrupt enable + 0x70 + + + txwm + Transmit watermark enable + [0:0] + read-write + + + rxwm + Receive watermark enable + [1:1] + read-write + + + + + ip + SPI interrupt pending + 0x74 + + + txwm + Transmit watermark pending + [0:0] + read-only + + + rxwm + Receive watermark pending + [1:1] + read-only + + + + + + + sifive_pwm0_2 + From sifive,pwm0,control peripheral generator + 0x10035000 + + 0 + 0x1000 + registers + + + + pwmcfg + PWM configuration register + 0x0 + + + pwmscale + PWM Counter scale + [3:0] + read-write + + + pwmsticky + PWM Sticky - disallow clearing pwmcmpXip bits + [8:8] + read-write + + + pwmzerocmp + PWM Zero - counter resets to zero after match + [9:9] + read-write + + + pwmdeglitch + PWM Deglitch - latch pwmcmpXip within same cycle + [10:10] + read-write + + + pwmenalways + PWM enable always - run continuously + [12:12] + read-write + + + pwmenoneshot + PWM enable one shot - run one cycle + [13:13] + read-write + + + pwmcmp0center + PWM0 Compare Center + [16:16] + read-write + + + pwmcmp1center + PWM1 Compare Center + [17:17] + read-write + + + pwmcmp2center + PWM2 Compare Center + [18:18] + read-write + + + pwmcmp3center + PWM3 Compare Center + [19:19] + read-write + + + pwmcmp0invert + PWM0 Invert + [20:20] + read-write + + + pwmcmp1invert + PWM1 Invert + [21:21] + read-write + + + pwmcmp2invert + PWM2 Invert + [22:22] + read-write + + + pwmcmp3invert + PWM3 Invert + [23:23] + read-write + + + pwmcmp0gang + PWM0/PWM1 Compare Gang + [24:24] + read-write + + + pwmcmp1gang + PWM1/PWM2 Compare Gang + [25:25] + read-write + + + pwmcmp2gang + PWM2/PWM3 Compare Gang + [26:26] + read-write + + + pwmcmp3gang + PWM3/PWM0 Compare Gang + [27:27] + read-write + + + pwmcmp0ip + PWM0 Interrupt Pending + [28:28] + read-write + + + pwmcmp1ip + PWM1 Interrupt Pending + [29:29] + read-write + + + pwmcmp2ip + PWM2 Interrupt Pending + [30:30] + read-write + + + pwmcmp3ip + PWM3 Interrupt Pending + [31:31] + read-write + + + + + pwmcount + PWM count register + 0x8 + + + pwmcount + PWM count register. + [30:0] + read-write + + + + + pwms + Scaled PWM count register + 0x10 + + + pwms + Scaled PWM count register. + [15:0] + read-write + + + + + pwmcmp0 + PWM 0 compare register + 0x20 + + + pwmcmp0 + PWM 0 Compare Value + [15:0] + read-write + + + + + pwmcmp1 + PWM 1 compare register + 0x24 + + + pwmcmp1 + PWM 1 Compare Value + [15:0] + read-write + + + + + pwmcmp2 + PWM 2 compare register + 0x28 + + + pwmcmp2 + PWM 2 Compare Value + [15:0] + read-write + + + + + pwmcmp3 + PWM 3 compare register + 0x2C + + + pwmcmp3 + PWM 3 Compare Value + [15:0] + read-write + + + + + + + \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h new file mode 100644 index 000000000..32a33abd7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h @@ -0,0 +1,259 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__ATOMIC_H +#define METAL__ATOMIC_H + +#include + +#include + +typedef volatile int32_t metal_atomic_t; + +#define METAL_ATOMIC_DECLARE(name) \ + __attribute((section(".data.atomics"))) metal_atomic_t name + +#define _METAL_STORE_AMO_ACCESS_FAULT 7 + +/* This macro stores the memory address in mtval like a normal store/amo access + * fault, triggers a trap, and then if execution returns, returns 0 as an + * arbitrary choice */ +#define _METAL_TRAP_AMO_ACCESS(addr) \ + __asm__("csrw mtval, %[atomic]" ::[atomic] "r"(a)); \ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); \ + return 0; + +/*! + * @brief Check if the platform supports atomic operations + * + * @return 1 if atomic operations are supported, 0 if not + */ +__inline__ int32_t metal_atomic_available(void) { +#ifdef __riscv_atomic + return 1; +#else + return 0; +#endif +} + +/*! + * @brief Atomically increment a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to increment + * @param increment the amount to increment the value + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_add(metal_atomic_t *a, int32_t increment) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoadd.w %[old], %[increment], (%[atomic])" + : [old] "=r"(old) + : [increment] "r"(increment), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-AND a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-AND + * @param mask the bitmask to AND + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_and(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoand.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-OR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-OR + * @param mask the bitmask to OR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_or(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically swap a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param new_value the value to store in the metal_atomic_t + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_swap(metal_atomic_t *a, int32_t new_value) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoswap.w %[old], %[newval], (%[atomic])" + : [old] "=r"(old) + : [newval] "r"(new_value), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-XOR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-XOR + * @param mask the bitmask to XOR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_xor(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoxor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the greater of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_max(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomax.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) + * greater of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_max_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomaxu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the lesser of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_min(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomin.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) lesser + * of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_min_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amominu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +#endif /* METAL__ATOMIC_H */ 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 index 0c26f435a..bef645967 100644 --- 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 @@ -15,7 +15,8 @@ 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); + struct metal_interrupt *(*interrupt_controller)( + struct metal_button *button); int (*get_interrupt_id)(struct metal_button *button); }; @@ -35,8 +36,7 @@ struct metal_button { * @param label The DeviceTree label for the button * @return A handle for the button */ -struct metal_button* metal_button_get(char *label); - +struct metal_button *metal_button_get(char *label); /*! * @brief Get the interrupt controller for a button @@ -45,8 +45,10 @@ struct metal_button* metal_button_get(char *label); * @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); } +__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 @@ -54,6 +56,8 @@ inline struct metal_interrupt* * @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); } +__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 index a8a60ada6..673a8b13e 100644 --- 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 @@ -1,4 +1,4 @@ -/* Copyright 2018 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #ifndef METAL__CACHE_H @@ -9,40 +9,58 @@ * * @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); -}; +#include /*! * @brief a handle for a cache + * Note: To be deprecated in next release. */ struct metal_cache { - const struct __metal_cache_vtable *vtable; + uint8_t __no_empty_structs; }; +/*! + * @brief Initialize L2 cache controller. + * Enables all available cache ways. + * @param None + * @return 0 If no error + */ +int metal_l2cache_init(void); + +/*! + * @brief Get the current number of enabled L2 cache ways + * @param None + * @return The current number of enabled L2 cache ways + */ +int metal_l2cache_get_enabled_ways(void); + +/*! + * @brief Enable the requested number of L2 cache ways + * @param ways Number of ways to enable + * @return 0 if the ways are successfully enabled + */ +int metal_l2cache_set_enabled_ways(int ways); + /*! * @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. + * Note: API to be deprecated in next release. */ -inline void metal_cache_init(struct metal_cache *cache, int ways) { - return cache->vtable->init(cache, ways); +__inline__ void metal_cache_init(struct metal_cache *cache, int ways) { + metal_l2cache_init(); } /*! * @brief Get the current number of enabled cache ways * @param cache The handle for the cache * @return The current number of enabled cache ways + * Note: API to be deprecated in next release. */ -inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { - return cache->vtable->get_enabled_ways(cache); +__inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { + return metal_l2cache_get_enabled_ways(); } /*! @@ -50,9 +68,41 @@ inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { * @param cache The handle for the cache * @param ways The number of ways to enabled * @return 0 if the ways are successfully enabled + * Note: API to be deprecated in next release. */ -inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { - return cache->vtable->set_enabled_ways(cache, ways); +__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, + int ways) { + return metal_l2cache_set_enabled_ways(ways); } +/*! + * @brief Check if dcache is supported on the core + * @param hartid The core to check + * @return 1 if dcache is present + */ +int metal_dcache_l1_available(int hartid); + +/*! + * @brief Flush dcache for L1 on the requested core with write back + * @param hartid The core to flush + * @param address The virtual address of cacheline to invalidate + * @return None + */ +void metal_dcache_l1_flush(int hartid, uintptr_t address); + +/*! + * @brief Discard dcache for L1 on the requested core with no write back + * @param hartid The core to discard + * @param address The virtual address of cacheline to invalidate + * @return None + */ +void metal_dcache_l1_discard(int hartid, uintptr_t address); + +/*! + * @brief Check if icache is supported on the core + * @param hartid The core to check + * @return 1 if icache is present + */ +int metal_icache_l1_available(int hartid); + #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 index 277841e01..cfe29f6b7 100644 --- 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 @@ -4,11 +4,12 @@ #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. + * The clock interface allows for controlling the rate of various clocks in the + * system. */ struct metal_clock; @@ -22,37 +23,82 @@ struct __metal_clock_vtable { }; /*! - * @brief Function signature of clock pre-rate change callbacks + * @brief Function signature of clock rate change callbacks */ -typedef void (*metal_clock_pre_rate_change_callback)(void *priv); +typedef void (*metal_clock_rate_change_callback)(void *priv); + +struct _metal_clock_callback_t; +struct _metal_clock_callback_t { + /* The callback function */ + metal_clock_rate_change_callback callback; + + /* Private data for the callback function */ + void *priv; + + struct _metal_clock_callback_t *_next; +}; /*! - * @brief Function signature of clock post-rate change callbacks + * @brief Type for the linked list of callbacks for clock rate changes */ -typedef void (*metal_clock_post_rate_change_callback)(void *priv); +typedef struct _metal_clock_callback_t metal_clock_callback; + +/*! + * @brief Call all callbacks in the linked list, if any are registered + */ +__inline__ void +_metal_clock_call_all_callbacks(const metal_clock_callback *const list) { + const metal_clock_callback *current = list; + while (current) { + current->callback(current->priv); + current = current->_next; + } +} + +/*! + * @brief Append a callback to the linked list and return the head of the list + */ +__inline__ metal_clock_callback * +_metal_clock_append_to_callbacks(metal_clock_callback *list, + metal_clock_callback *const cb) { + cb->_next = NULL; + + if (!list) { + return cb; + } + + metal_clock_callback *current = list; + + while ((current->_next) != NULL) { + current = current->_next; + } + + current->_next = cb; + + return list; +} /*! * @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. + * 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. + * 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; + /* Pre-rate change callback linked list */ + metal_clock_callback *_pre_rate_change_callback; - /* Post-rate change callback */ - metal_clock_post_rate_change_callback _post_rate_change_callback; - void *_post_rate_change_callback_priv; + /* Post-rate change callback linked list */ + metal_clock_callback *_post_rate_change_callback; }; /*! @@ -61,7 +107,9 @@ struct metal_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); } +__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 @@ -74,18 +122,15 @@ inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk- * 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. + * 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); +__inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) { + _metal_clock_call_all_callbacks(clk->_pre_rate_change_callback); 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); + _metal_clock_call_all_callbacks(clk->_post_rate_change_callback); return out; } @@ -95,12 +140,12 @@ inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) * * @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; +__inline__ void +metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_pre_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_pre_rate_change_callback, cb); } /*! @@ -108,12 +153,12 @@ inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *cl * * @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; +__inline__ void +metal_clock_register_post_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_post_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_post_rate_change_callback, cb); } #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 index 62c0ea975..80ca5fee4 100644 --- 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 @@ -4,18 +4,19 @@ #ifndef METAL__COMPILER_H #define METAL__COMPILER_H -#define __METAL_DECLARE_VTABLE(type) \ - extern const struct type type; +#define __METAL_DECLARE_VTABLE(type) extern const struct type type; -#define __METAL_DEFINE_VTABLE(type) \ - const struct type type +#define __METAL_DEFINE_VTABLE(type) const struct type type -#define __METAL_GET_FIELD(reg, mask) \ +#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))) +#define __METAL_SET_FIELD(reg, mask, val) \ + (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) + +#define __METAL_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define __METAL_MAX(a, b) ((a) > (b) ? (a) : (b)) void _metal_trap(int ecode); 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 index 453bd12de..98d7e6680 100644 --- 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 @@ -9,33 +9,35 @@ #ifndef METAL__CPU_H #define METAL__CPU_H -#include #include +#include struct metal_cpu; /*! * @brief Function signature for exception handlers */ -typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode); +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 (*mcycle_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); + 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); + 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); + 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); + struct metal_buserror *(*get_buserror)(struct metal_cpu *cpu); }; /*! @brief A device handle for a CPU hart @@ -49,17 +51,17 @@ struct metal_cpu { * @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); +struct metal_cpu *metal_cpu_get(unsigned 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(); +int metal_cpu_get_current_hartid(void); /*! @brief Get the number of CPU harts - * + * * @return The number of CPU harts */ -int metal_cpu_get_num_harts(); +int metal_cpu_get_num_harts(void); /*! @brief Get the CPU cycle count timer value * @@ -68,8 +70,9 @@ int metal_cpu_get_num_harts(); * @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); } +__inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) { + return cpu->vtable->mcycle_get(cpu); +} /*! @brief Get the timebase of the CPU * @@ -78,8 +81,9 @@ inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) * @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); } +__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 * @@ -90,8 +94,9 @@ inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) * @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); } +__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 * @@ -103,20 +108,24 @@ inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) * @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); } +__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. + * 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); } +__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 * @@ -125,20 +134,23 @@ inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal * @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); } +__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. + * 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); } +__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 * @@ -147,8 +159,9 @@ inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct me * @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); } +__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 @@ -161,8 +174,9 @@ inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) * @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); } +__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 @@ -175,8 +189,9 @@ inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) * @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); } +__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 @@ -190,8 +205,9 @@ inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) * @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); } +__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 @@ -204,22 +220,26 @@ inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) * @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); } +__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. + * + * 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); } +__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 @@ -237,8 +257,10 @@ inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_ * @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); } +__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. @@ -249,8 +271,9 @@ inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc * @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); } +__inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) { + return cpu->vtable->get_epc(cpu); +} /*! * @brief Set the exception program counter @@ -265,7 +288,20 @@ inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) * @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); } +__inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, + uintptr_t epc) { + return cpu->vtable->set_epc(cpu, epc); +} + +/*! + * @brief Get the handle for the hart's bus error unit + * + * @param cpu The CPU device handle + * @return A pointer to the bus error unit handle + */ +__inline__ struct metal_buserror * +metal_cpu_get_buserror(struct metal_cpu *cpu) { + return cpu->vtable->get_buserror(cpu); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h new file mode 100644 index 000000000..8375d8a44 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h @@ -0,0 +1,32 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__CSR_H +#define METAL__CSR_H + +#include +#include +#include + +/*! + * @file csr.h + * @brief A collection of APIs for get and set CSR registers + */ + +/*! + * @brief Read a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to read from + * @param value Variable name of uintprt_t type to get the value + */ +#define METAL_CPU_GET_CSR(reg, value) \ + __asm__ volatile("csrr %0, " #reg : "=r"(value)); + +/*! + * @brief Write to a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to write to + * @param value Variable name of uintprt_t type to set the value + */ +#define METAL_CPU_SET_CSR(reg, value) \ + __asm__ volatile("csrw " #reg ", %0" : : "r"(value)); + +#endif // METAL__CSR_H 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 index 2647c5981..b25f54144 100644 --- 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 @@ -6,8 +6,8 @@ struct __metal_driver_fixed_clock; -#include #include +#include struct __metal_driver_vtable_fixed_clock { struct __metal_clock_vtable clock; 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 index 936ce8d77..84e4fd580 100644 --- 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 @@ -6,8 +6,8 @@ struct __metal_driver_fixed_factor_clock; -#include #include +#include struct __metal_driver_vtable_fixed_factor_clock { struct __metal_clock_vtable clock; 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 index 08d571e1c..ceda473e2 100644 --- 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 @@ -21,4 +21,7 @@ struct __metal_driver_riscv_clint0 { }; #undef __METAL_MACHINE_MACROS +int __metal_driver_riscv_clint0_command_request( + struct metal_interrupt *controller, int command, void *data); + #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 index eb1e5b8ca..f3005f01f 100644 --- 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 @@ -4,148 +4,154 @@ #ifndef METAL__DRIVERS__RISCV_CPU_H #define METAL__DRIVERS__RISCV_CPU_H -#include -#include #include +#include +#include -#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_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_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_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 +#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 +#define METAL_MCAUSE_INTR 0x80000000UL +#define METAL_MCAUSE_CAUSE 0x000003FFUL #else -#define METAL_MCAUSE_INTR 0x8000000000000000UL -#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL +#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_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(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 */ +#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 +#define METAL_LOCAL_INTERRUPT(X) \ + (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */ +#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE + +#define METAL_INSN_LENGTH_MASK 3 +#define METAL_INSN_NOT_COMPRESSED 3 typedef enum { - METAL_MACHINE_PRIVILEGE_MODE, - METAL_SUPERVISOR_PRIVILEGE_MODE, - METAL_USER_PRIVILEGE_MODE, + 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_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_CSW = (METAL_INTERRUPT_ID_BASE + 12), + 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_BEU = 128, } 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_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_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; + metal_interrupt_handler_t handler; void *sub_int; void *exint_data; } __metal_interrupt_data; @@ -154,30 +160,15 @@ typedef struct __metal_interrupt_data { 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; + 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_vector_mode __metal_controller_interrupt_vector_mode(void); +void __metal_controller_interrupt_vector(metal_vector_mode mode, + void *vec_table); __METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) @@ -186,18 +177,20 @@ struct __metal_driver_riscv_cpu_intc { int init_done; uintptr_t metal_mtvec_table[METAL_MAX_MI]; __metal_interrupt_data metal_int_table[METAL_MAX_MI]; + __metal_interrupt_data metal_int_beu; metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; }; /* CPU driver*/ struct __metal_driver_vtable_cpu { - struct metal_cpu_vtable cpu_vtable; + struct metal_cpu_vtable cpu_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) struct __metal_driver_cpu { struct metal_cpu cpu; + unsigned int hpm_count; /* Available HPM counters per 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 index 159ee6d69..fac76fbc3 100644 --- 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 @@ -7,10 +7,10 @@ #include #include -#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 +#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; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h new file mode 100644 index 000000000..20972109b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h @@ -0,0 +1,184 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_BUSERROR0_H +#define METAL__DRIVERS__SIFIVE_BUSERROR0_H + +/*! + * @file sifive_buserror0.h + * + * @brief API for configuring the SiFive Bus Error Unit + */ + +#include +#include +#include + +/*! + * @brief The set of possible events handled by a SiFive Bus Error Unit + */ +typedef enum { + /*! @brief No event or error has been detected */ + METAL_BUSERROR_EVENT_NONE = 0, + + /*! @brief A correctable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR = (1 << 2), + /*! @brief An uncorrectable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR = (1 << 3), + /*! @brief A TileLink load or store bus error has occurred */ + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR = (1 << 5), + /*! @brief A correctable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR = (1 << 6), + /*! @brief An uncorrectable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR = (1 << 7), + + /*! @brief Used to set/clear all interrupts or query/clear all accrued + events */ + METAL_BUSERROR_EVENT_ALL = + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR | + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR, + /*! @brief A synonym of METAL_BUSERROR_EVENT_ALL */ + METAL_BUSERROR_EVENT_ANY = METAL_BUSERROR_EVENT_ALL, + + /*! @brief A value which is impossible for the bus error unit to report. + * Indicates an error has occurred if provided as a return value. */ + METAL_BUSERROR_EVENT_INVALID = (1 << 8), +} metal_buserror_event_t; + +/*! + * @brief The handle for a bus error unit + */ +struct metal_buserror { + uint8_t __no_empty_structs; +}; + +/*! + * @brief Enable bus error events + * + * Enabling bus error events causes them to be registered as accrued and, + * if the corresponding interrupt is inabled, trigger interrupts. + * + * @param beu The bus error unit handle + * @param events A mask of error events to enable + * @param enabled True if the mask should be enabled, false if they should be + * disabled + * @return 0 upon success + */ +int metal_buserror_set_event_enabled(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get enabled bus error events + * @param beu The bus error unit handle + * @return A mask of all enabled events + */ +metal_buserror_event_t +metal_buserror_get_event_enabled(struct metal_buserror *beu); + +/*! + * @brief Enable or disable the platform interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_platform_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Enable or disable the hart-local interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_local_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get the error event which caused the most recent interrupt + * + * This method should be called from within the interrupt handler for the bus + * error unit interrupt + * + * @param beu The bus error unit handle + * @return The event which caused the interrupt + */ +metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu); + +/*! + * @brief Clear the cause register for the bus error unit + * + * This method should be called from within the interrupt handler for the bus + * error unit to un-latch the cause register for the next event + * + * @param beu The bus error unit handle + * @return 0 upon success + */ +int metal_buserror_clear_cause(struct metal_buserror *beu); + +/*! + * @brief Get the physical address of the error event + * + * This method should be called from within the interrupt handler for the bus + * error unit. + * + * @param beu The bus error unit handle + * @return The address of the error event + */ +uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu); + +/*! + * @brief Returns true if the event is set in the accrued register + * + * @param beu The bus error unit handle + * @param event The event to query + * @return True if the event is set in the accrued register + */ +bool metal_buserror_is_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief Clear the given event from the accrued register + * + * @param beu The bus error unit handle + * @param event The event to clear + * @return 0 upon success + */ +int metal_buserror_clear_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief get the platform-level interrupt parent of the bus error unit + * + * @param beu The bus error unit handle + * @return A pointer to the interrupt parent + */ +struct metal_interrupt * +metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu); + +/*! + * @brief Get the platform-level interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu); + +/*! + * @brief Get the hart-local interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h new file mode 100644 index 000000000..13a47c0b9 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h @@ -0,0 +1,140 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H +#define METAL__DRIVERS__SIFIVE_CCACHE0_H + +/*! + * @file sifive_ccache0.h + * + * @brief API for configuring the SiFive L2 cache controller + */ + +#include +#include + +/*! @brief Cache configuration data */ +typedef struct { + uint32_t num_bank; + uint32_t num_ways; + uint32_t num_sets; + uint32_t block_size; +} sifive_ccache0_config; + +/*! @brief Set of values for ECC error type */ +typedef enum { + SIFIVE_CCACHE0_DATA = 0, + SIFIVE_CCACHE0_DIR = 1, +} sifive_ccache0_ecc_errtype_t; + +/*! @brief Initialize cache controller, enables all available + * cache-ways. + * Note: If LIM is in use, corresponding cache ways are not enabled. + * @param None. + * @return 0 If no error.*/ +int sifive_ccache0_init(void); + +/*! @brief Get cache configuration data. + * @param config User specified data buffer. + * @return None.*/ +void sifive_ccache0_get_config(sifive_ccache0_config *config); + +/*! @brief Get currently active cache ways. + * @param None. + * @return Number of cache ways enabled.*/ +uint32_t sifive_ccache0_get_enabled_ways(void); + +/*! @brief Enable specified cache ways. + * @param ways Number of ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_enabled_ways(uint32_t ways); + +/*! @brief Inject ECC error into data or meta-data. + * @param bitindex Bit index to be corrupted on next cache operation. + * @param type ECC error target location. + * @return None.*/ +void sifive_ccache0_inject_ecc_error(uint32_t bitindex, + sifive_ccache0_ecc_errtype_t type); + +/*! @brief Flush out entire cache block containing given address. + * @param flush_addr Address for the cache block to be flushed. + * @return None.*/ +void sifive_ccache0_flush(uintptr_t flush_addr); + +/*! @brief Get most recently ECC corrected address. + * @param type ECC error target location. + * @return Last corrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fix_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Corrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fix_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get address location of most recent uncorrected ECC error. + * @param type ECC error target location. + * @return Last uncorrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fail_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were not corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Uncorrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fail_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get currently active way enable mask value for the given master ID. + * @param master_id Cache controller master ID. + * @return Way enable mask. */ +uint64_t sifive_ccache0_get_way_mask(uint32_t master_id); + +/*! @brief Set way enable mask for the given master ID. + * @param master_id Cache controller master ID. + * @param waymask Specify ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_way_mask(uint32_t master_id, uint64_t waymask); + +/*! @brief Select cache performance events to be counted. + * @param counter Cache performance monitor counter index. + * @param mask Event selection mask. + * @return None.*/ +void sifive_ccache0_set_pmevent_selector(uint32_t counter, uint64_t mask); + +/*! @brief Get currently set events for the given counter index. + * @param counter Cache performance monitor counter index. + * @return Event selection mask.*/ +uint64_t sifive_ccache0_get_pmevent_selector(uint32_t counter); + +/*! @brief Clears specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return None.*/ +void sifive_ccache0_clr_pmevent_counter(uint32_t counter); + +/*! @brief Reads specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return Counter value.*/ +uint64_t sifive_ccache0_get_pmevent_counter(uint32_t counter); + +/*! @brief Select cache clients to be excluded from performance monitoring. + * @param mask Client disable mask. + * @return None.*/ +void sifive_ccache0_set_client_filter(uint64_t mask); + +/*! @brief Get currently set cache client disable mask. + * @param None. + * @return Client disable mask.*/ +uint64_t sifive_ccache0_get_client_filter(void); + +/*! @brief Get interrupt IDs for the cache controller. + * @param src Interrupt trigger source index. + * @return Interrupt id.*/ +int sifive_ccache0_get_interrupt_id(uint32_t src); + +/*! @brief Get interrupt controller of the cache. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param None. + * @return Handle for the interrupt controller.*/ +struct metal_interrupt *sifive_ccache0_interrupt_controller(void); + +#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 index db9674625..b8ff82271 100644 --- 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 @@ -7,21 +7,21 @@ #include #include -#define METAL_CLIC_MAX_NMBITS 2 -#define METAL_CLIC_MAX_NLBITS 8 -#define METAL_CLIC_MAX_NVBITS 1 +#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_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_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) +#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1) struct __metal_driver_vtable_sifive_clic0 { struct metal_interrupt_vtable clic_vtable; @@ -34,9 +34,15 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) struct __metal_driver_sifive_clic0 { struct metal_interrupt controller; int init_done; - metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; + struct { + } __attribute__((aligned(64))); + metal_interrupt_vector_handler_t + metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; }; #undef __METAL_MACHINE_MACROS +int __metal_driver_sifive_clic0_command_request( + struct metal_interrupt *controller, int command, void *data); + #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 index d311f0cf2..d60d3a3bd 100644 --- 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 @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H #define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H -#include -#include #include +#include +#include #include struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h new file mode 100644 index 000000000..2650584ad --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h @@ -0,0 +1,21 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_lfrosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc) + +struct __metal_driver_sifive_fe310_g000_lfrosc { + 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 index 87c9ca985..4fca30167 100644 --- 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 @@ -10,14 +10,16 @@ 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); + 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 { + const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable; }; #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 deleted file mode 100644 index 8c3cf907e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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 -#include - -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_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h index a0caeaba8..7227eee02 100644 --- 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 @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H #define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H -#include #include #include +#include struct __metal_driver_vtable_sifive_button { - struct metal_button_vtable button_vtable; + struct metal_button_vtable button_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) 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 index a8dacf116..abfca01c2 100644 --- 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 @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H #define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H +#include #include #include -#include struct __metal_driver_vtable_sifive_led { - struct metal_led_vtable led_vtable; + struct metal_led_vtable led_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) 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 index c9c7839e9..be55a0446 100644 --- 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 @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H #define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H +#include #include #include -#include struct __metal_driver_vtable_sifive_switch { - struct metal_switch_vtable switch_vtable; + struct metal_switch_vtable switch_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) 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 index cc56dc722..50314222d 100644 --- 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 @@ -11,7 +11,7 @@ struct __metal_driver_vtable_sifive_gpio0 { const struct __metal_gpio_vtable gpio; }; -//struct __metal_driver_sifive_gpio0; +// struct __metal_driver_sifive_gpio0; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h new file mode 100644 index 000000000..8fbbe21e1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h @@ -0,0 +1,24 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_I2C0_H +#define METAL__DRIVERS__SIFIVE_I2C0_H + +#include +#include + +struct __metal_driver_vtable_sifive_i2c0 { + const struct metal_i2c_vtable i2c; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_i2c0) + +struct __metal_driver_sifive_i2c0 { + struct metal_i2c i2c; + unsigned int init_done; + unsigned int baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h new file mode 100644 index 000000000..63c8e6536 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h @@ -0,0 +1,78 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_L2PF0_H +#define METAL__DRIVERS__SIFIVE_L2PF0_H + +/*! + * @file sifive_l2pf0.h + * + * @brief API for configuring the SiFive L2 prefetcher. + */ + +#include + +/*! @brief L2 prefetcher configuration */ +typedef struct { + /* Enable L2 hardware prefetcher */ + uint8_t HwPrefetchEnable; + + /* Only works when CrossPageEn === 0. + Cross Page optimization disable: + 0 -> Entry goes into Pause state while crossing Page boundary. + Next time when the demand miss happens on the same page, it doesn’t need + to train again. 1 -> The entry is invalidated in case of a cross page. */ + uint8_t CrossPageOptmDisable; + + /* Enable prefetches to cross pages */ + uint8_t CrossPageEn; + + /* Age-out mechanism enable */ + uint8_t AgeOutEn; + + uint32_t PrefetchDistance; + + uint32_t MaxAllowedDistance; + + /* Linear to exponential threshold */ + uint32_t LinToExpThreshold; + + /* No. of non-matching loads to edge out an entry */ + uint32_t NumLdsToAgeOut; + + /* Threshold no. of Fullness (L2 MSHRs used/ total available) to stop + * sending hits */ + uint32_t QFullnessThreshold; + + /* Threshold no. of CacheHits for evicting SPF entry */ + uint32_t HitCacheThreshold; + + /* Threshold no. of MSHR hits for increasing SPF distance */ + uint32_t hitMSHRThreshold; + + /* Size of the comparison window for address matching */ + uint32_t Window; + +} sifive_l2pf0_config; + +/*! @brief Enable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_enable(void); + +/*! @brief Disable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_disable(void); + +/*! @brief Get currently active L2 prefetcher configuration. + * @param config Pointer to user specified configuration structure. + * @return None.*/ +void sifive_l2pf0_get_config(sifive_l2pf0_config *config); + +/*! @brief Enables fine grain access to L2 prefetcher configuration. + * @param config Pointer to user structure with values to be set. + * @return None.*/ +void sifive_l2pf0_set_config(sifive_l2pf0_config *config); + +#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 index aa8d63078..320ab10d2 100644 --- 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 @@ -18,5 +18,4 @@ struct __metal_driver_sifive_local_external_interrupts0 { int init_done; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h new file mode 100644 index 000000000..caa774401 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_PWM0_H +#define METAL__DRIVERS__SIFIVE_PWM0_H + +#include +#include + +struct __metal_driver_vtable_sifive_pwm0 { + const struct metal_pwm_vtable pwm; +}; + +/* Max possible PWM channel count */ +#define METAL_MAX_PWM_CHANNELS 16 + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_pwm0) + +struct __metal_driver_sifive_pwm0 { + struct metal_pwm pwm; + unsigned int max_count; + unsigned int count_val; + unsigned int freq; + unsigned int duty[METAL_MAX_PWM_CHANNELS]; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h new file mode 100644 index 000000000..a35ab9a09 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h @@ -0,0 +1,26 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_RTC0_H +#define METAL__DRIVERS__SIFIVE_RTC0_H + +#include +#include + +#include +#include +#include + +struct __metal_driver_vtable_sifive_rtc0 { + const struct metal_rtc_vtable rtc; +}; + +struct __metal_driver_sifive_rtc0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_rtc0) + +struct __metal_driver_sifive_rtc0 { + const struct metal_rtc rtc; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h new file mode 100644 index 000000000..f6b739143 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_SIMUART0_H +#define METAL__DRIVERS__SIFIVE_SIMUART0_H + +#include +#include +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_simuart0 { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_simuart0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_simuart0) + +struct __metal_driver_sifive_simuart0 { + struct metal_uart uart; + unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#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 index 90d4c831e..73527944b 100644 --- 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 @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_SPI0_H #define METAL__DRIVERS__SIFIVE_SPI0_H -#include #include #include +#include #include #include @@ -19,6 +19,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0) struct __metal_driver_sifive_spi0 { struct metal_spi spi; unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; }; #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 index e87db2c83..debd3fb9d 100644 --- 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 @@ -17,5 +17,4 @@ 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_trace.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h new file mode 100644 index 000000000..3c67522f4 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h @@ -0,0 +1,23 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_TRACE_H +#define METAL__DRIVERS__SIFIVE_TRACE_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_trace { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_trace; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_trace) + +struct __metal_driver_sifive_trace { + struct metal_uart uart; +}; + +#endif /* METAL__DRIVERS__SIFIVE_TRACE_H */ 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 index 11d954002..2b38e4631 100644 --- 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 @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_UART0_H #define METAL__DRIVERS__SIFIVE_UART0_H -#include -#include #include +#include +#include +#include #include #include -#include struct __metal_driver_vtable_sifive_uart0 { const struct metal_uart_vtable uart; @@ -22,7 +22,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0) struct __metal_driver_sifive_uart0 { struct metal_uart uart; unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h new file mode 100644 index 000000000..bb3424584 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h @@ -0,0 +1,26 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_WDOG0_H +#define METAL__DRIVERS__SIFIVE_WDOG0_H + +#include +#include + +#include +#include +#include + +struct __metal_driver_vtable_sifive_wdog0 { + const struct metal_watchdog_vtable watchdog; +}; + +struct __metal_driver_sifive_wdog0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_wdog0) + +struct __metal_driver_sifive_wdog0 { + const struct metal_watchdog watchdog; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h new file mode 100644 index 000000000..210d0819b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h @@ -0,0 +1,48 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__UCB_HTIF0_H +#define METAL__DRIVERS__UCB_HTIF0_H + +#include +#include +#include + +struct __metal_driver_vtable_ucb_htif0_shutdown { + const struct __metal_shutdown_vtable shutdown; +}; + +struct __metal_driver_vtable_ucb_htif0_uart { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_ucb_htif0; + +void __metal_driver_ucb_htif0_exit(const struct __metal_shutdown *test, + int code) __attribute__((noreturn)); + +void __metal_driver_ucb_htif0_init(struct metal_uart *uart, int baud_rate); +int __metal_driver_ucb_htif0_putc(struct metal_uart *uart, int c); +int __metal_driver_ucb_htif0_getc(struct metal_uart *uart, int *c); +int __metal_driver_ucb_htif0_get_baud_rate(struct metal_uart *guart); +int __metal_driver_ucb_htif0_set_baud_rate(struct metal_uart *guart, + int baud_rate); +struct metal_interrupt * +__metal_driver_ucb_htif0_interrupt_controller(struct metal_uart *uart); +int __metal_driver_ucb_htif0_get_interrupt_id(struct metal_uart *uart); + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_shutdown) + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_uart) + +struct __metal_driver_ucb_htif0_shutdown { + struct __metal_shutdown shutdown; + const struct __metal_driver_vtable_ucb_htif0_shutdown *vtable; +}; + +struct __metal_driver_ucb_htif0_uart { + struct metal_uart uart; + const struct __metal_driver_vtable_ucb_htif0_uart *vtable; +}; + +#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 index 513687dd7..df9adb451 100644 --- 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 @@ -5,6 +5,7 @@ #define METAL__GPIO_H #include +#include /*! * @file gpio.h @@ -15,20 +16,37 @@ struct metal_gpio; struct __metal_gpio_vtable { int (*disable_input)(struct metal_gpio *, long pins); + int (*enable_input)(struct metal_gpio *, long pins); + long (*input)(struct metal_gpio *); long (*output)(struct metal_gpio *); + int (*disable_output)(struct metal_gpio *, long pins); 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); + int (*disable_io)(struct metal_gpio *, long pins); + int (*config_int)(struct metal_gpio *, long pins, int intr_type); + int (*clear_int)(struct metal_gpio *, long pins, int intr_type); + struct metal_interrupt *(*interrupt_controller)(struct metal_gpio *gpio); + int (*get_interrupt_id)(struct metal_gpio *gpio, int pin); }; +#define METAL_GPIO_INT_DISABLE 0 +#define METAL_GPIO_INT_RISING 1 +#define METAL_GPIO_INT_FALLING 2 +#define METAL_GPIO_INT_BOTH_EDGE 3 +#define METAL_GPIO_INT_LOW 4 +#define METAL_GPIO_INT_HIGH 5 +#define METAL_GPIO_INT_BOTH_LEVEL 6 +#define METAL_GPIO_INT_MAX 7 + /*! * @struct metal_gpio * @brief The handle for a GPIO interface */ struct metal_gpio { - const struct __metal_gpio_vtable *vtable; + const struct __metal_gpio_vtable *vtable; }; /*! @@ -36,7 +54,21 @@ struct metal_gpio { * @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); +struct metal_gpio *metal_gpio_get_device(unsigned int device_num); + +/*! + * @brief enable 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 enabled + */ +__inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->enable_input(gpio, (1 << pin)); +} /*! * @brief Disable input on a pin @@ -44,9 +76,9 @@ struct metal_gpio *metal_gpio_get_device(int device_num); * @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; +__inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->disable_input(gpio, (1 << pin)); @@ -58,14 +90,28 @@ inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { * @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; +__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 Disable 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 disabled + */ +__inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->disable_output(gpio, (1 << pin)); +} + /*! * @brief Set the output value of a GPIO pin * @param gpio The handle for the GPIO interface @@ -73,15 +119,15 @@ inline int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) { * @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; +__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)); + if (value == 0) { + return gpio->vtable->output_clear(gpio, (1 << pin)); } else { - return gpio->vtable->output_set(gpio, (1 << pin)); + return gpio->vtable->output_set(gpio, (1 << pin)); } } @@ -91,17 +137,37 @@ inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { * @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; +__inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 0; + } + + long value = gpio->vtable->input(gpio); + + if (value & (1 << pin)) { + return 1; + } else { + return 0; + } +} + +/*! + * @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_output_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 0; } long value = gpio->vtable->output(gpio); - if(value & (1 << pin)) { - return 1; + if (value & (1 << pin)) { + return 1; } else { - return 0; + return 0; } } @@ -111,9 +177,9 @@ inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) { * @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; +__inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->output_clear(gpio, (1 << pin)); @@ -125,9 +191,9 @@ inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { * @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; +__inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->output_toggle(gpio, (1 << pin)); @@ -140,12 +206,82 @@ inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { * @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; +__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)); } +/*! + * @brief Disables the pinmux for a GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to disable pinmux on + * @return 0 if the pinmux is successfully set + */ +__inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->disable_io(gpio, (1 << pin)); +} + +/*! + * @brief Config gpio interrupt type + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to enable gpio interrupt + * @param intr_type The interrupt type + * @return 0 if the interrupt mode is setup properly + */ +__inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; + } + + return gpio->vtable->config_int(gpio, (1 << pin), intr_type); +} + +/*! + * @brief Clear gpio interrupt status + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to clear gpio interrupt + * @param intr_type The interrupt type to be clear + * @return 0 if the interrupt is cleared + */ +__inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; + } + + return gpio->vtable->clear_int(gpio, (1 << pin), intr_type); +} + +/*! + * @brief Get the interrupt controller for a gpio + * + * @param gpio The handle for the gpio + * @return A pointer to the interrupt controller responsible for handling + * gpio interrupts. + */ +__inline__ struct metal_interrupt * +metal_gpio_interrupt_controller(struct metal_gpio *gpio) { + return gpio->vtable->interrupt_controller(gpio); +} + +/*! + * @brief Get the interrupt id for a gpio + * + * @param gpio The handle for the gpio + * @param pin The bitmask for the pin to get gpio interrupt id + * @return The interrupt id corresponding to a gpio. + */ +__inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) { + return gpio->vtable->get_interrupt_id(gpio, pin); +} + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h new file mode 100644 index 000000000..290f7ec3f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h @@ -0,0 +1,146 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__HPM_H +#define METAL__HPM_H + +#include + +/*! @brief Macros for valid Event IDs */ +#define METAL_HPM_EVENTID_8 (1UL << 8) +#define METAL_HPM_EVENTID_9 (1UL << 9) +#define METAL_HPM_EVENTID_10 (1UL << 10) +#define METAL_HPM_EVENTID_11 (1UL << 11) +#define METAL_HPM_EVENTID_12 (1UL << 12) +#define METAL_HPM_EVENTID_13 (1UL << 13) +#define METAL_HPM_EVENTID_14 (1UL << 14) +#define METAL_HPM_EVENTID_15 (1UL << 15) +#define METAL_HPM_EVENTID_16 (1UL << 16) +#define METAL_HPM_EVENTID_17 (1UL << 17) +#define METAL_HPM_EVENTID_18 (1UL << 18) +#define METAL_HPM_EVENTID_19 (1UL << 19) +#define METAL_HPM_EVENTID_20 (1UL << 20) +#define METAL_HPM_EVENTID_21 (1UL << 21) +#define METAL_HPM_EVENTID_22 (1UL << 22) +#define METAL_HPM_EVENTID_23 (1UL << 23) +#define METAL_HPM_EVENTID_24 (1UL << 24) +#define METAL_HPM_EVENTID_25 (1UL << 25) +#define METAL_HPM_EVENTID_26 (1UL << 26) +#define METAL_HPM_EVENTID_27 (1UL << 27) +#define METAL_HPM_EVENTID_28 (1UL << 28) +#define METAL_HPM_EVENTID_29 (1UL << 29) +#define METAL_HPM_EVENTID_30 (1UL << 30) +#define METAL_HPM_EVENTID_31 (1UL << 31) + +/*! @brief Macros for valid Event Class */ +#define METAL_HPM_EVENTCLASS_0 (0UL) +#define METAL_HPM_EVENTCLASS_1 (1UL) +#define METAL_HPM_EVENTCLASS_2 (2UL) +#define METAL_HPM_EVENTCLASS_3 (3UL) +#define METAL_HPM_EVENTCLASS_4 (4UL) +#define METAL_HPM_EVENTCLASS_5 (5UL) +#define METAL_HPM_EVENTCLASS_6 (6UL) +#define METAL_HPM_EVENTCLASS_7 (7UL) +#define METAL_HPM_EVENTCLASS_8 (8UL) + +/*! @brief Enums for available HPM counters */ +typedef enum { + METAL_HPM_CYCLE = 0, + METAL_HPM_TIME = 1, + METAL_HPM_INSTRET = 2, + METAL_HPM_COUNTER_3 = 3, + METAL_HPM_COUNTER_4 = 4, + METAL_HPM_COUNTER_5 = 5, + METAL_HPM_COUNTER_6 = 6, + METAL_HPM_COUNTER_7 = 7, + METAL_HPM_COUNTER_8 = 8, + METAL_HPM_COUNTER_9 = 9, + METAL_HPM_COUNTER_10 = 10, + METAL_HPM_COUNTER_11 = 11, + METAL_HPM_COUNTER_12 = 12, + METAL_HPM_COUNTER_13 = 13, + METAL_HPM_COUNTER_14 = 14, + METAL_HPM_COUNTER_15 = 15, + METAL_HPM_COUNTER_16 = 16, + METAL_HPM_COUNTER_17 = 17, + METAL_HPM_COUNTER_18 = 18, + METAL_HPM_COUNTER_19 = 19, + METAL_HPM_COUNTER_20 = 20, + METAL_HPM_COUNTER_21 = 21, + METAL_HPM_COUNTER_22 = 22, + METAL_HPM_COUNTER_23 = 23, + METAL_HPM_COUNTER_24 = 24, + METAL_HPM_COUNTER_25 = 25, + METAL_HPM_COUNTER_26 = 26, + METAL_HPM_COUNTER_27 = 27, + METAL_HPM_COUNTER_28 = 28, + METAL_HPM_COUNTER_29 = 29, + METAL_HPM_COUNTER_30 = 30, + METAL_HPM_COUNTER_31 = 31 +} metal_hpm_counter; + +/*! @brief Initialize hardware performance monitor counters. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_init(struct metal_cpu *cpu); + +/*! @brief Disables hardware performance monitor counters. + * Note - Disabled HPM counters may reduce power consumption. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_disable(struct metal_cpu *cpu); + +/*! @brief Set events which will cause the specified counter to increment. + * Counter will start incrementing from the moment events are set. + * @param cpu The CPU device handle. + * @param counter Hardware counter to be incremented by selected events. + * @param bitmask Bit-mask to select events for a particular counter, + * refer core reference manual for selection of events. + * Event bit mask is partitioned as follows: + * [XLEN-1:8] - Event selection mask [7:0] - Event class + * @return 0 If no error.*/ +int metal_hpm_set_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Get events selection mask set for specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Event selection bit mask. refer core reference manual for details.*/ +unsigned int metal_hpm_get_event(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clear event selector bits as per specified bit-mask. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clr_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Enable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_enable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Disable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_disable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Reads current value of specified hardware counter. + * Note: 'mtime' register is memory mapped into CLINT block. + * Use CLINT APIs to access this register. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Current value of hardware counter on success, 0 on failure.*/ +unsigned long long metal_hpm_read_counter(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clears off specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clear_counter(struct metal_cpu *cpu, metal_hpm_counter counter); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h new file mode 100644 index 000000000..baf62e5d6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h @@ -0,0 +1,112 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__I2C_H +#define METAL__I2C_H + +/*! @brief Enums to enable/disable stop condition. */ +typedef enum { + METAL_I2C_STOP_DISABLE = 0, + METAL_I2C_STOP_ENABLE = 1 +} metal_i2c_stop_bit_t; + +/*! @brief Enums to set up I2C device modes. */ +typedef enum { METAL_I2C_SLAVE = 0, METAL_I2C_MASTER = 1 } metal_i2c_mode_t; + +struct metal_i2c; + +struct metal_i2c_vtable { + void (*init)(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode); + int (*write)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*read)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*transfer)(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen); + int (*get_baud_rate)(struct metal_i2c *i2c); + int (*set_baud_rate)(struct metal_i2c *i2c, unsigned int baud_rate); +}; + +/*! @brief A handle for a I2C device. */ +struct metal_i2c { + const struct metal_i2c_vtable *vtable; +}; + +/*! @brief Get a handle for a I2C device. + * @param device_num The index of the desired I2C device. + * @return A handle to the I2C device, or NULL if the device does not exist.*/ +struct metal_i2c *metal_i2c_get_device(unsigned int device_num); + +/*! @brief Initialize a I2C device with a certain baud rate. + * @param i2c The handle for the I2C device to initialize. + * @param baud_rate The baud rate for the I2C device to operate at. + * @param mode I2C operation mode. + */ +inline void metal_i2c_init(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode) { + i2c->vtable->init(i2c, baud_rate, mode); +} + +/*! @brief Perform a I2C write. + * @param i2c The handle for the I2C device to perform the write operation. + * @param addr The I2C slave address for the write operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to send over the I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the write succeeds. + */ +inline int metal_i2c_write(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->write(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Perform a I2C read. + * @param i2c The handle for the I2C device to perform the read operation. + * @param addr The I2C slave address for the read operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to store data from I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the read succeeds. + */ +inline int metal_i2c_read(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->read(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Performs back to back I2C write and read operations. + * @param i2c The handle for the I2C device to perform the transfer operation. + * @param addr The I2C slave address for the transfer operation. + * @param txbuf The data buffer to be transmitted over I2C bus. + * @param txlen The number of bytes to write over I2C. + * @param rxbuf The buffer to store data received over I2C bus. + * @param rxlen The number of bytes to read over I2C. + * @return 0 if the transfer succeeds. + */ +inline int metal_i2c_transfer(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen) { + return i2c->vtable->transfer(i2c, addr, txbuf, txlen, rxbuf, rxlen); +} + +/*! @brief Get the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @return The baud rate in Hz. + */ +inline int metal_i2c_get_baud_rate(struct metal_i2c *i2c) { + return i2c->vtable->get_baud_rate(i2c); +} + +/*! @brief Set the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @param baud_rate The desired baud rate of the I2C device. + * @return 0 If the baud rate is successfully changed. + */ +inline int metal_i2c_set_baud_rate(struct metal_i2c *i2c, int baud_rate) { + return i2c->vtable->set_baud_rate(i2c, baud_rate); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h new file mode 100644 index 000000000..0214d0add --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h @@ -0,0 +1,130 @@ +/* Copyright 2019 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL_INIT +#define METAL_INIT + +/*! + * @file init.h + * API for Metal constructors and destructors + */ + +typedef void (*metal_constructor_t)(void); +typedef void (*metal_destructor_t)(void); + +#define METAL_INIT_HIGHEST_PRIORITY 0 +#define METAL_INIT_DEFAULT_PRIORITY 5000 +#define METAL_INIT_LOWEST_PRIORITY 9999 + +/*! @def METAL_CONSTRUCTOR + * @brief Define a Metal constructor + * + * Functions defined with METAL_CONSTRUCTOR will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR(function_name) \ + METAL_CONSTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_CONSTRUCTOR_PRIO + * @brief Define a Metal constructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_CONSTRUCTOR_PRIO will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __METAL_CONSTRUCTOR_PRIO(function_name, priority) + +/* We use this wrapper for METAL_CONSTRUCTOR_PRIORITY so that macros passed + * as 'priority' are expanded before being stringified by the # operator. + * If we don't do this, then + * METAL_CONSTRUCTOR(my_fn_name, METAL_INIT_DEFAULT_PRIORITY) + * results in .metal.init_array.METAL_INIT_DEFAULT_PRIORITY instead of + * .metal.init_array.5000 */ +#define __METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.ctors"))) void function_name(void); \ + __attribute__((section(".metal.init_array." #priority))) \ + metal_constructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! @def METAL_DESTRUCTOR + * @brief Define a Metal destructor + * + * Functions defined with METAL_DESTRUCTOR will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR(function_name) \ + METAL_DESTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_DESTRUCTOR_PRIO + * @brief Define a Metal destructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_DESTRUCTOR_PRIO will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __METAL_DESTRUCTOR_PRIO(function_name, priority) +#define __METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.dtors"))) void function_name(void); \ + __attribute__((section(".metal.fini_array." #priority))) \ + metal_destructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! + * @brief Call all Metal constructors + * + * Devices supported by Metal may define Metal constructors to perform + * initialization before main. This function iterates over the constructors + * and calls them in turn. + * + * You can add your own constructors to the functions called by metal_init() + * by defining functions with the METAL_CONSTRUCTOR() macro. + * + * This function is called before main by default by metal_init_run(). + */ +void metal_init(void); + +/*! + * @brief Call all Metal destructors + * + * Devices supported by Metal may define Metal destructors to perform + * initialization on exit. This function iterates over the destructors + * and calls them in turn. + * + * You can add your own destructors to the functions called by metal_fini() + * by defining functions with the METAL_DESTRUCTOR() macro. + * + * This function is called on exit by default by metal_fini_run(). + */ +void metal_fini(void); + +/*! + * @brief Weak function to call metal_init() before main + * + * This function calls metal_init() before main by default. If you wish to + * replace or augment this call to the Metal constructors, you can redefine + * metal_init_run() + */ +void metal_init_run(void); + +/*! + * @brief Weak function to call metal_fini() before main + * + * This function calls metal_fini() at exit by default. If you wish to + * replace or augment this call to the Metal destructors, you can redefine + * metal_fini_run() + */ +void metal_fini_run(void); + +#endif /* METAL_INIT */ 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 index 43f587aca..11df019de 100644 --- 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 @@ -10,34 +10,105 @@ #include +/*! + * @brief Possible interrupt controllers + */ +typedef enum metal_interrupt_controller_ { + METAL_CPU_CONTROLLER = 0, + METAL_CLINT_CONTROLLER = 1, + METAL_CLIC_CONTROLLER = 2, + METAL_PLIC_CONTROLLER = 3 +} metal_intr_cntrl_type; + /*! * @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_SELECTIVE_NONVECTOR_MODE = 2, + METAL_SELECTIVE_VECTOR_MODE = 3, + METAL_HARDWARE_VECTOR_MODE = 4 } metal_vector_mode; +/*! + * @brief Possible mode of privilege interrupts to operate + */ +typedef enum metal_intr_priv_mode_ { + METAL_INTR_PRIV_M_MODE = 0, + METAL_INTR_PRIV_MU_MODE = 1, + METAL_INTR_PRIV_MSU_MODE = 2 +} metal_intr_priv_mode; + +/*! + * @brief The bitmask of hart context + */ +typedef struct metal_affinity_ { + unsigned long bitmask; +} metal_affinity; + +#define for_each_metal_affinity(bit, metal_affinity) \ + for (bit = 0; metal_affinity.bitmask; bit++, metal_affinity.bitmask >>= 1) + +#define metal_affinity_set_val(metal_affinity, val) \ + metal_affinity.bitmask = val; + +#define metal_affinity_set_bit(metal_affinity, bit, val) \ + metal_affinity.bitmask |= ((val & 0x1) << bit); + /*! * @brief Function signature for interrupt callback handlers */ -typedef void (*metal_interrupt_handler_t) (int, void *); +typedef void (*metal_interrupt_handler_t)(int, void *); +typedef void (*metal_interrupt_vector_handler_t)(void); struct metal_interrupt; struct metal_interrupt_vtable { void (*interrupt_init)(struct metal_interrupt *controller); + int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, + metal_vector_mode mode); + metal_vector_mode (*interrupt_get_vector_mode)( + struct metal_interrupt *controller); + int (*interrupt_set_privilege)(struct metal_interrupt *controller, + metal_intr_priv_mode priv); + metal_intr_priv_mode (*interrupt_get_privilege)( + struct metal_interrupt *controller); + int (*interrupt_clear)(struct metal_interrupt *controller, int id); + int (*interrupt_set)(struct metal_interrupt *controller, int id); int (*interrupt_register)(struct metal_interrupt *controller, int id, - metal_interrupt_handler_t isr, void *priv_data); + metal_interrupt_handler_t isr, void *priv_data); + int (*interrupt_vector_register)(struct metal_interrupt *controller, int id, + metal_interrupt_vector_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_enable)(struct metal_interrupt *controller, int id); 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); + unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller); + int (*interrupt_set_threshold)(struct metal_interrupt *controller, + unsigned int threshold); + unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, + int id); + int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, + unsigned int priority); + unsigned int (*interrupt_get_preemptive_level)( + struct metal_interrupt *controller, int id); + int (*interrupt_set_preemptive_level)(struct metal_interrupt *controller, + int id, unsigned int level); + int (*command_request)(struct metal_interrupt *controller, int cmd, + void *data); + int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, + unsigned long long time); + metal_affinity (*interrupt_affinity_enable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_disable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_set_threshold)( + struct metal_interrupt *controller, metal_affinity bitmask, + unsigned int threshold); + unsigned int (*interrupt_affinity_get_threshold)( + struct metal_interrupt *controller, int context_id); }; /*! @@ -56,11 +127,104 @@ struct metal_interrupt { * * @param controller The handle for the interrupt controller */ -inline void metal_interrupt_init(struct metal_interrupt *controller) -{ - return controller->vtable->interrupt_init(controller); +__inline__ void metal_interrupt_init(struct metal_interrupt *controller) { + controller->vtable->interrupt_init(controller); } +/*! + * @brief Get the handle for an given interrupt controller type + * @param cntrl The type ofinterrupt controller + * @param id The instance of the interrupt controller + * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or + * NULL if none is found for the requested label + */ +struct metal_interrupt * +metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, int id); + +/*! + * @brief Configure vector mode for an interrupt controller + * + * Configure vector mode for an interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param mode The vector mode of the interrupt controller. + * @return 0 upon success + */ +__inline__ int +metal_interrupt_set_vector_mode(struct metal_interrupt *controller, + metal_vector_mode mode) { + return controller->vtable->interrupt_set_vector_mode(controller, mode); +} + +/*! + * @brief Get vector mode of a given an interrupt controller + * + * Configure vector mode for an interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param mode The vector mode of the interrupt controller. + * @return The interrupt vector mode + */ +__inline__ metal_vector_mode +metal_interrupt_get_vector_mode(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_vector_mode(controller); +} + +/*! + * @brief Configure privilege mode a of given interrupt controller + * + * Configure privilege mode for a given interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param privilege The privilege mode of the interrupt controller. + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, + metal_intr_priv_mode privilege) { + return controller->vtable->interrupt_set_privilege(controller, privilege); +} + +/*! + * @brief Get privilege mode a of given interrupt controller + * + * Get privilege mode for a given interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @return The interrupt privilege mode + */ +__inline__ metal_intr_priv_mode +metal_interrupt_get_privilege(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_privilege(controller); +} + +/*! + * @brief clear an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to trigger + * @return 0 upon success + */ +__inline__ int metal_interrupt_clear(struct metal_interrupt *controller, + int id) { + return controller->vtable->interrupt_clear(controller, id); +} + +/*! + * @brief Set an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to trigger + * @return 0 upon success + */ +__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) { + return controller->vtable->interrupt_set(controller, id); +} /*! * @brief Register an interrupt handler @@ -70,12 +234,27 @@ inline void metal_interrupt_init(struct metal_interrupt *controller) * @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); +__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 Register an interrupt vector handler + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to register + * @param handler The interrupt vector handler callback + * @param priv_data Private data for the interrupt handler + * @return 0 upon success + */ +__inline__ int metal_interrupt_register_vector_handler( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t handler, void *priv_data) { + return controller->vtable->interrupt_vector_register(controller, id, + handler, priv_data); } /*! @@ -84,8 +263,8 @@ inline int metal_interrupt_register_handler(struct metal_interrupt *controller, * @param id The interrupt ID to enable * @return 0 upon success */ -inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_enable(controller, id); } @@ -95,22 +274,100 @@ inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) * @param id The interrupt ID to disable * @return 0 upon success */ -inline int metal_interrupt_disable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_disable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_disable(controller, id); } +/*! + * @brief Set interrupt threshold level + * @param controller The handle for the interrupt controller + * @param threshold The interrupt threshold level + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int level) { + return controller->vtable->interrupt_set_threshold(controller, level); +} + +/*! + * @brief Get an interrupt threshold level + * @param controller The handle for the interrupt controller + * @return The interrupt threshold level + */ +__inline__ unsigned int +metal_interrupt_get_threshold(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_threshold(controller); +} + +/*! + * @brief Set an interrupt priority level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @param priority The interrupt priority level + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) { + return controller->vtable->interrupt_set_priority(controller, id, priority); +} + +/*! + * @brief Get an interrupt priority level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return The interrupt priority level + */ +__inline__ unsigned int +metal_interrupt_get_priority(struct metal_interrupt *controller, int id) { + return controller->vtable->interrupt_get_priority(controller, id); +} + +/*! + * @brief Set preemptive level and priority for a given interrupt ID + * + * Set the preemptive level and priority for a given interrupt ID. + * + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @param level The interrupt level and priority are encoded together + * @return 0 upon success + */ +__inline__ int +metal_interrupt_set_preemptive_level(struct metal_interrupt *controller, int id, + unsigned int level) { + if (controller->vtable->interrupt_set_preemptive_level) + return controller->vtable->interrupt_set_preemptive_level(controller, + id, level); + else + return 0; +} + +/*! + * @brief Get an interrupt preemptive level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return The interrupt level + */ +__inline__ unsigned int +metal_interrupt_get_preemptive_level(struct metal_interrupt *controller, + int id) { + if (controller->vtable->interrupt_get_preemptive_level) + return controller->vtable->interrupt_get_preemptive_level(controller, + id); + else + return 0; +} + /*! * @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); +__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, + int id) { + return controller->vtable->interrupt_vector_enable(controller, id); } /*! @@ -119,16 +376,215 @@ inline int metal_interrupt_vector_enable(struct metal_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) -{ +__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) -{ +/*! + * @brief Default interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void); + +/*! + * @brief Metal Software interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_software_interrupt_vector_handler(void); + +/*! + * @brief Metal Timer interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_timer_interrupt_vector_handler(void); + +/*! + * @brief Metal External interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_external_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 0 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 1 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 2 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 3 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 4 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 5 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 6 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 7 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 8 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 9 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 10 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 11 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 12 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 13 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 14 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 15 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void); + +/* 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); } +/*! + * @brief Enable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to enable + * @param id The interrupt ID to enable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_enable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_enable(controller, bitmask, + id); +} + +/*! + * @brief Disable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to disable + * @param id The interrupt ID to disable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_disable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_disable(controller, bitmask, + id); +} + +/*! + * @brief Set interrupt threshold level for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to set threshold + * @param threshold The interrupt threshold level + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_set_threshold(struct metal_interrupt *controller, + metal_affinity bitmask, + unsigned int level) { + return controller->vtable->interrupt_affinity_set_threshold(controller, + bitmask, level); +} + +/*! + * @brief Get an interrupt threshold level from the hart context + * @param controller The handle for the interrupt controller + * @param context_id The hart context ID to get threshold + * @return The interrupt threshold level + */ +__inline__ unsigned int +metal_interrupt_affinity_get_threshold(struct metal_interrupt *controller, + int context_id) { + return controller->vtable->interrupt_affinity_get_threshold(controller, + context_id); +} #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 index 450054142..f1df85518 100644 --- 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 @@ -5,18 +5,19 @@ #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)) +#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"); +#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 char __metal_io_u8; typedef unsigned short __metal_io_u16; -typedef unsigned int __metal_io_u32; +typedef unsigned int __metal_io_u32; #if __riscv_xlen >= 64 -typedef unsigned long __metal_io_u64; +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 index 1a2a05b8b..3decefff2 100644 --- 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 @@ -9,13 +9,12 @@ * 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"))) +#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 index a430b84c2..da2555fb8 100644 --- 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 @@ -31,38 +31,47 @@ struct metal_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); +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 + * @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); +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); } +__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); } +__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); } +__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); } +__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/lim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h new file mode 100644 index 000000000..1e573cad6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h @@ -0,0 +1,20 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LIM_H +#define METAL__LIM_H + +/*! @file lim.h + * + * API for manipulating LIM allocation + */ + +/*! @def METAL_PLACE_IN_LIM + * @brief Link a function into the LIM + * + * Link a function into the LIM (Loosely Integrated + * Memory) if the LIM is present on the target device. + */ +#define METAL_PLACE_IN_LIM __attribute__((section(".lim"))) + +#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 index d863aa96e..e591eaefa 100644 --- 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 @@ -4,8 +4,9 @@ #ifndef METAL__LOCK_H #define METAL__LOCK_H -#include #include +#include +#include /*! * @file lock.h @@ -15,6 +16,9 @@ /* TODO: How can we make the exception code platform-independant? */ #define _METAL_STORE_AMO_ACCESS_FAULT 7 +#define METAL_LOCK_BACKOFF_CYCLES 32 +#define METAL_LOCK_BACKOFF_EXPONENT 2 + /*! * @def METAL_LOCK_DECLARE * @brief Declare a lock @@ -22,35 +26,36 @@ * 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 +#define METAL_LOCK_DECLARE(name) \ + __attribute__((section(".data.locks"))) struct metal_lock name /*! * @brief A handle for a lock */ struct metal_lock { - int _state; + 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. + * @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) { +__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) { + 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)) { + if (!metal_memory_supports_atomics(lock_mem)) { return 2; } @@ -70,23 +75,37 @@ inline int metal_lock_init(struct metal_lock *lock) { * 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) { +__inline__ int metal_lock_take(struct metal_lock *lock) { #ifdef __riscv_atomic int old = 1; int new = 1; - while(old != 0) { + int backoff = 1; + const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES; + + while (1) { __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])" - : [old] "=r" (old) - : [new] "r" (new), [state] "r" (&(lock->_state)) + : [old] "=r"(old) + : [new] "r"(new), [state] "r"(&(lock->_state)) : "memory"); + + if (old == 0) { + break; + } + + for (int i = 0; i < backoff; i++) { + __asm__ volatile(""); + } + + if (backoff < max_backoff) { + backoff *= METAL_LOCK_BACKOFF_EXPONENT; + } } return 0; #else /* Store the memory address in mtval like a normal store/amo access fault */ - __asm__ ("csrw mtval, %[state]" - :: [state] "r" (&(lock->_state))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); @@ -104,17 +123,16 @@ inline int metal_lock_take(struct metal_lock *lock) { * 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) { +__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"); + __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))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); 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 index f76dbd632..74c361b4b 100644 --- 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 @@ -9,15 +9,15 @@ #ifdef __METAL_MACHINE_MACROS -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_IF_METAL_H +#define MACROS_IF_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_SUBINTERRUPTS 53 #define __METAL_PLIC_NUM_PARENTS 1 @@ -31,12 +31,12 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #endif -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_IF_METAL_H*/ #else /* ! __METAL_MACHINE_MACROS */ -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_ELSE_METAL_H +#define MACROS_ELSE_METAL_H #define __METAL_CLINT_2000000_INTERRUPTS 2 @@ -46,7 +46,7 @@ #define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define METAL_MAX_PLIC_INTERRUPTS 1 @@ -55,20 +55,36 @@ #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_LOCAL_EXT_INTERRUPTS 0 #define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0 -#define __METAL_GPIO_10012000_INTERRUPTS 16 +#define __METAL_GPIO_10012000_INTERRUPTS 32 -#define METAL_MAX_GPIO_INTERRUPTS 16 +#define METAL_MAX_GPIO_INTERRUPTS 32 + +#define __METAL_I2C_10016000_INTERRUPTS 1 + +#define METAL_MAX_I2C0_INTERRUPTS 1 + +#define __METAL_PWM_10015000_INTERRUPTS 4 + +#define __METAL_PWM_10025000_INTERRUPTS 4 + +#define __METAL_PWM_10035000_INTERRUPTS 4 + +#define METAL_MAX_PWM0_INTERRUPTS 4 + +#define METAL_MAX_PWM0_NCMP 4 #define __METAL_SERIAL_10013000_INTERRUPTS 1 +#define __METAL_SERIAL_10023000_INTERRUPTS 1 + #define METAL_MAX_UART_INTERRUPTS 1 +#define METAL_MAX_SIMUART_INTERRUPTS 0 + #include #include @@ -76,79 +92,119 @@ #include #include #include -#include #include #include +#include +#include +#include #include #include +#include #include #include +#include #include #include /* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0; +extern struct __metal_driver_fixed_clock __metal_dt_clock_0; /* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; +extern struct __metal_driver_fixed_clock __metal_dt_clock_2; /* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; +extern struct __metal_driver_fixed_clock __metal_dt_clock_5; -struct metal_memory __metal_dt_mem_dtim_80000000; +/* From clock@6 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_6; -struct metal_memory __metal_dt_mem_spi_10014000; +extern struct metal_memory __metal_dt_mem_dtim_80000000; + +extern struct metal_memory __metal_dt_mem_itim_8000000; + +extern struct metal_memory __metal_dt_mem_spi_10014000; + +extern struct metal_memory __metal_dt_mem_spi_10024000; + +extern struct metal_memory __metal_dt_mem_spi_10034000; /* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; +extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; /* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; +extern struct __metal_driver_cpu __metal_dt_cpu_0; -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; +extern 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; +extern 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; +extern struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; +extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; +/* From led@0 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; +/* From led@1 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; +/* From led@2 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2; + +/* From i2c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; + +/* From pwm@10015000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; + +/* From pwm@10025000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000; + +/* From pwm@10035000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000; /* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10034000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; /* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From serial@10023000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000; /* From clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; +extern 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; +extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; + +/* From clock@7 */ +extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7; /* From clock@4 */ -struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; +extern 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; +extern 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) +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; @@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) { + return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY; + } else { return 0; } @@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c /* --------------------- sifive_clint0 ------------ */ -static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) +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; @@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met } } -static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) +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; @@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met } } -static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) +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; @@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter } } -static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) +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; @@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa } } -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 3; @@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte /* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 0; @@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) } } -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; + return 16000000; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) +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; @@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s } } -static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) +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; @@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) } } +static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return NULL; + } + else { + return NULL; + } +} + /* --------------------- sifive_plic0 ------------ */ -static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) +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; @@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta } } -static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) +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; @@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta } } -static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) +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; @@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr } } -static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) +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; @@ -312,120 +381,52 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup } } -static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) +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) +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; } } +static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid) +{ + if (hartid == 0) { + return 0; + } + else { + return -1; + } +} + + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- 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) +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; @@ -435,7 +436,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio * } } -static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) +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; @@ -445,7 +446,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio * } } -static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) +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; @@ -455,7 +456,7 @@ static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio * } } -static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +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; @@ -465,56 +466,104 @@ static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_par } } -static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) +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))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { return 9; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { return 10; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { return 11; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { return 12; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { return 13; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { return 14; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { return 15; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { return 16; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { return 17; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { return 18; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { return 19; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { return 20; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { return 21; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { return 22; } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + return 23; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) { + return 24; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) { + return 25; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) { + return 26; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) { + return 29; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) { + return 30; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) { + return 31; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) { + return 32; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) { + return 33; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) { + return 34; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) { + return 35; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) { + return 36; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) { + return 29; + } else { return 0; } @@ -526,15 +575,15 @@ static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio /* --------------------- sifive_gpio_led ------------ */ -static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *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) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } else { @@ -542,15 +591,15 @@ static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct met } } -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return 22; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return 19; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return 21; } else { @@ -558,15 +607,15 @@ static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) } } -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return "LD0red"; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return "LD0green"; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return "LD0blue"; } else { @@ -579,45 +628,430 @@ static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) /* --------------------- sifive_gpio_switch ------------ */ -/* --------------------- sifive_spi0 ------------ */ -static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) +/* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_pwm0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return __METAL_PWM_10015000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return __METAL_PWM_10025000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return __METAL_PWM_10035000_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx) +{ + if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) { + return 40; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) { + return 41; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) { + return 42; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) { + return 43; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) { + return 44; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) { + return 45; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) { + return 46; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) { + return 47; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) { + return 48; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) { + return 49; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) { + return 50; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) { + return 51; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 8; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 16; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 16; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 4; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_rtc0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return 2; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} + + +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 if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) +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 if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_SIZE; + } else { return 0; } } -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) { - return 60; + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { return 60; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 4227858432; + } + else { + return 0; + } } @@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_SIZE; + } else { return 0; } } -static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_MAX_UART_INTERRUPTS; + } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) { - return 5; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 3; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 4; + } + else { + return 0; + } } -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) { - return 196608; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 0; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return 196608; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 8650752; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return 1; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } } /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) +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) +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) +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) +static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; } @@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) +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) +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) +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_lfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_5.clock; + } + else { + return NULL; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_6.clock; + } + else { + return NULL; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 112; + } + else { + return 0; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 124; + } + else { + return 0; + } +} + + + /* --------------------- sifive_fe310_g000_pll ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) +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) +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) +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) +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( ) +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( ) +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( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ) { return 16000000; } @@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) /* --------------------- sifive_fe310_g000_prci ------------ */ -static inline long __metal_driver_sifive_fe310_g000_prci_base( ) +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( ) +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( ) +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 3 - -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); +__asm__ (".weak __metal_memory_table"); struct metal_memory *__metal_memory_table[] = { &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_itim_8000000, &__metal_dt_mem_spi_10014000}; /* From serial@10013000 */ @@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = { #define __METAL_DT_MAX_HARTS 1 -asm (".weak __metal_cpu_table"); +#define __METAL_CPU_0_ICACHE_HANDLE 1 + +__asm__ (".weak __metal_cpu_table"); struct __metal_driver_cpu *__metal_cpu_table[] = { &__metal_dt_cpu_0}; @@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = { #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"); +__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"); +__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"); +__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}; + &__metal_dt_led_0, + &__metal_dt_led_1, + &__metal_dt_led_2}; #define __METAL_DT_MAX_SWITCHES 0 -asm (".weak __metal_switch_table"); +__asm__ (".weak __metal_switch_table"); struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { NULL }; -#define __METAL_DT_MAX_SPIS 1 +#define __METAL_DT_MAX_I2CS 1 -asm (".weak __metal_spi_table"); +__asm__ (".weak __metal_i2c_table"); +struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = { + &__metal_dt_i2c_10016000}; + +#define __METAL_DT_MAX_PWMS 3 + +__asm__ (".weak __metal_pwm_table"); +struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = { + &__metal_dt_pwm_10015000, + &__metal_dt_pwm_10025000, + &__metal_dt_pwm_10035000}; + +#define __METAL_DT_MAX_RTCS 1 + +__asm__ (".weak __metal_rtc_table"); +struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = { + &__metal_dt_rtc_10000000}; + +#define __METAL_DT_MAX_SPIS 3 + +__asm__ (".weak __metal_spi_table"); struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; + +#define __METAL_DT_MAX_UARTS 2 + +__asm__ (".weak __metal_uart_table"); +struct __metal_driver_sifive_uart0 *__metal_uart_table[] = { + &__metal_dt_serial_10013000, + &__metal_dt_serial_10023000}; + +#define __METAL_DT_MAX_SIMUARTS 0 + +__asm__ (".weak __metal_simuart_table"); +struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = { + NULL }; +#define __METAL_DT_MAX_WDOGS 1 + +__asm__ (".weak __metal_wdog_table"); +struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = { + &__metal_dt_aon_10000000}; /* 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 /* MACROS_ELSE_METAL_H*/ #endif /* ! __METAL_MACHINE_MACROS */ 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 index 8c0cd048b..fd05ab065 100644 --- 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 @@ -5,128 +5,181 @@ #ifndef ASSEMBLY -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#ifndef METAL_INLINE_H +#define METAL_INLINE_H #include /* --------------------- fixed_clock ------------ */ -extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *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); +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); +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); +extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(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); +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); +extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid); + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- 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); +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); +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_i2c0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); + + +/* --------------------- sifive_pwm0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx); +extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm); + + +/* --------------------- sifive_rtc0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc); +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc); +extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc); +extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc); + + /* --------------------- 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); +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_trace ------------ */ + /* --------------------- 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); +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_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog); +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog); +extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog); /* --------------------- 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); +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); +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_lfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(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( ); +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 ------------ */ +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( ); /* From clock@0 */ @@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = { .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, }; +/* From clock@6 */ +struct __metal_driver_fixed_clock __metal_dt_clock_6 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + struct metal_memory __metal_dt_mem_dtim_80000000 = { ._base_address = 2147483648UL, ._size = 16384UL, @@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_itim_8000000 = { + ._base_address = 134217728UL, + ._size = 8192UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + struct metal_memory __metal_dt_mem_spi_10014000 = { ._base_address = 536870912UL, ._size = 500000UL, @@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_spi_10024000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10034000 = { + ._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, @@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { /* From cpu@0 */ struct __metal_driver_cpu __metal_dt_cpu_0 = { .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, + .hpm_count = 0, }; /* From interrupt_controller */ @@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { .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, -}; +struct metal_pmp __metal_dt_pmp; /* 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 = { +/* From led@0 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { +/* From led@1 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { +/* From led@2 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; + +/* From pwm@10015000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10025000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10035000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = { + .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc, +}; + /* From spi@10014000 */ struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, }; +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .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 serial@10023000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = { + .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog, +}; + /* From clock@3 */ struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, @@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock, }; +/* From clock@7 */ +struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.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, @@ -242,8 +376,9 @@ 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 = { + .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci, }; -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ +#endif /* 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 index 4ecd3e336..d517b5859 100644 --- 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 @@ -3,8 +3,8 @@ /* ----------------------------------- */ /* ----------------------------------- */ -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#ifndef METAL_PLATFORM_H +#define METAL_PLATFORM_H /* From clock@0 */ #define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL @@ -13,7 +13,10 @@ #define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL /* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL + +/* From clock@6 */ +#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL #define METAL_FIXED_CLOCK @@ -35,15 +38,18 @@ #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_C000000_RISCV_NDEV 53UL +#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL #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 +#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL +#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL +#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL +#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL +#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL /* From aon@10000000 */ #define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL @@ -111,6 +117,10 @@ #define METAL_SIFIVE_FE310_G000_HFXOSC +/* From clock@7 */ + +#define METAL_SIFIVE_FE310_G000_LFROSC + /* From prci@10008000 */ #define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL #define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL @@ -153,11 +163,11 @@ #define METAL_SIFIVE_GPIO0_IOF_SEL 60UL #define METAL_SIFIVE_GPIO0_OUT_XOR 64UL -/* From led@0red */ +/* From led@0 */ -/* From led@0green */ +/* From led@1 */ -/* From led@0blue */ +/* From led@2 */ #define METAL_SIFIVE_GPIO_LEDS @@ -176,16 +186,24 @@ #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 +/* From pwm@10025000 */ +#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_1_SIZE 4096UL + +/* From pwm@10035000 */ +#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_2_SIZE 4096UL + #define METAL_SIFIVE_PWM0 #define METAL_SIFIVE_PWM0_PWMCFG 0UL #define METAL_SIFIVE_PWM0_PWMCOUNT 8UL @@ -195,12 +213,37 @@ #define METAL_SIFIVE_PWM0_PWMCMP2 40UL #define METAL_SIFIVE_PWM0_PWMCMP3 44UL +/* 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_RTC0 +#define METAL_SIFIVE_RTC0_RTCCFG 64UL +#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL +#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL +#define METAL_SIFIVE_RTC0_RTCS 80UL +#define METAL_SIFIVE_RTC0_RTCCMP0 96UL + /* 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 +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + #define METAL_SIFIVE_SPI0 #define METAL_SIFIVE_SPI0_SCKDIV 0UL #define METAL_SIFIVE_SPI0_SCKMODE 4UL @@ -225,6 +268,12 @@ #define METAL_SIFIVE_UART0_10013000_SIZE 4096UL #define METAL_SIFIVE_UART0_0_SIZE 4096UL +/* From serial@10023000 */ +#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL +#define METAL_SIFIVE_UART0_1_SIZE 4096UL + #define METAL_SIFIVE_UART0 #define METAL_SIFIVE_UART0_TXDATA 0UL #define METAL_SIFIVE_UART0_RXDATA 4UL @@ -234,4 +283,20 @@ #define METAL_SIFIVE_UART0_IP 20UL #define METAL_SIFIVE_UART0_DIV 24UL -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ +/* 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_WDOG0 +#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL +#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL +#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL +#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL +#define METAL_SIFIVE_WDOG0_WDOGS 16UL +#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL +#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL +#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL + +#endif /* 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 index b62d8b25a..f009e9ecc 100644 --- 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 @@ -4,8 +4,8 @@ #ifndef METAL__MEMORY_H #define METAL__MEMORY_H -#include #include +#include /*! * @file memory.h @@ -14,20 +14,20 @@ */ struct _metal_memory_attributes { - int R : 1; - int W : 1; - int X : 1; - int C : 1; - int A : 1; + unsigned int R : 1; + unsigned int W : 1; + unsigned int X : 1; + unsigned int C : 1; + unsigned 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; + const uintptr_t _base_address; + const size_t _size; + const struct _metal_memory_attributes _attrs; }; /*! @@ -37,7 +37,8 @@ struct metal_memory { * 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 + * @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); @@ -46,8 +47,9 @@ struct metal_memory *metal_get_memory_from_address(const uintptr_t address); * @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; +__inline__ uintptr_t +metal_memory_get_base_address(const struct metal_memory *memory) { + return memory->_base_address; } /*! @@ -55,8 +57,8 @@ inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory * @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; +__inline__ size_t metal_memory_get_size(const struct metal_memory *memory) { + return memory->_size; } /*! @@ -64,8 +66,9 @@ inline size_t metal_memory_get_size(const struct metal_memory *memory) { * @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; +__inline__ int +metal_memory_supports_atomics(const struct metal_memory *memory) { + return memory->_attrs.A; } /*! @@ -73,9 +76,8 @@ inline int metal_memory_supports_atomics(const struct metal_memory *memory) { * @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; +__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 index 9121b10a1..38ab1b9a4 100644 --- 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 @@ -12,14 +12,14 @@ * 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. + * permissions. * * Additional information about the use and configuration rules for PMPs * can be found by reading the RISC-V Privileged Architecture Specification. */ -#include #include +#include struct metal_pmp; @@ -28,11 +28,11 @@ struct metal_pmp; */ enum metal_pmp_address_mode { /*! @brief Disable the PMP region */ - METAL_PMP_OFF = 0, + METAL_PMP_OFF = 0, /*! @brief Use Top-of-Range mode */ - METAL_PMP_TOR = 1, + METAL_PMP_TOR = 1, /*! @brief Use naturally-aligned 4-byte region mode */ - METAL_PMP_NA4 = 2, + METAL_PMP_NA4 = 2, /*! @brief Use naturally-aligned power-of-two mode */ METAL_PMP_NAPOT = 3 }; @@ -42,11 +42,11 @@ enum metal_pmp_address_mode { */ struct metal_pmp_config { /*! @brief Sets whether reads to the PMP region succeed */ - int R : 1; + unsigned int R : 1; /*! @brief Sets whether writes to the PMP region succeed */ - int W : 1; + unsigned int W : 1; /*! @brief Sets whether the PMP region is executable */ - int X : 1; + unsigned int X : 1; /*! @brief Sets the addressing mode of the PMP region */ enum metal_pmp_address_mode A : 2; @@ -56,7 +56,7 @@ struct metal_pmp_config { /*! @brief Sets whether the PMP region is locked */ enum metal_pmp_locked { METAL_PMP_UNLOCKED = 0, - METAL_PMP_LOCKED = 1 + METAL_PMP_LOCKED = 1 } L : 1; }; @@ -73,6 +73,11 @@ struct metal_pmp { */ struct metal_pmp *metal_pmp_get_device(void); +/*! + * @brief Get the number of pmp regions for the hartid + */ +int metal_pmp_num_regions(int hartid); + /*! * @brief Initialize the PMP * @param pmp The PMP device handle to be initialized @@ -96,9 +101,10 @@ void metal_pmp_init(struct metal_pmp *pmp); * @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); +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 @@ -106,7 +112,8 @@ int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct meta * @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); +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 @@ -123,7 +130,8 @@ int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); * @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); +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, + size_t address); /*! * @brief Get the address of a PMP region @@ -140,7 +148,8 @@ size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); * @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); +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 @@ -148,7 +157,8 @@ int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum * @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); +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 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 index c5212e5d1..522e7efe0 100644 --- 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 @@ -16,9 +16,9 @@ #include enum metal_privilege_mode { - METAL_PRIVILEGE_USER = 0, - METAL_PRIVILEGE_SUPERVISOR = 1, - METAL_PRIVELEGE_MACHINE = 3, + METAL_PRIVILEGE_USER = 0, + METAL_PRIVILEGE_SUPERVISOR = 1, + METAL_PRIVILEGE_MACHINE = 3, }; #if __riscv_xlen == 32 @@ -34,89 +34,89 @@ 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 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 t0; + metal_xreg_t t1; + metal_xreg_t t2; - metal_xreg_t s0; - metal_xreg_t s1; + 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; + 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 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 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; + 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 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 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 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 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; + 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)(); +typedef void (*metal_privilege_entry_point_t)(void); void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point); + 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/pwm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h new file mode 100644 index 000000000..600d5a02b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h @@ -0,0 +1,162 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PWM_H +#define METAL__PWM_H + +/*! @brief Enums for PWM running modes. */ +typedef enum { + METAL_PWM_CONTINUOUS = 0, + METAL_PWM_ONE_SHOT = 1 +} metal_pwm_run_mode_t; + +/*! @brief Enums for Phase correct PWM. */ +typedef enum { + METAL_PWM_PHASE_CORRECT_DISABLE = 0, + METAL_PWM_PHASE_CORRECT_ENABLE = 1, +} metal_pwm_phase_correct_t; + +/*! @brief Enums for Interrupts enable/disable. */ +typedef enum { + METAL_PWM_INTERRUPT_DISABLE = 0, + METAL_PWM_INTERRUPT_ENABLE = 1, +} metal_pwm_interrupt_t; + +struct metal_pwm; + +/*! @brief vtable for PWM. */ +struct metal_pwm_vtable { + int (*enable)(struct metal_pwm *pwm); + int (*disable)(struct metal_pwm *pwm); + int (*set_freq)(struct metal_pwm *pwm, unsigned int idx, unsigned int freq); + int (*set_duty)(struct metal_pwm *pwm, unsigned int idx, unsigned int duty, + metal_pwm_phase_correct_t phase_corr); + unsigned int (*get_duty)(struct metal_pwm *pwm, unsigned int idx); + unsigned int (*get_freq)(struct metal_pwm *pwm, unsigned int idx); + int (*trigger)(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode); + int (*stop)(struct metal_pwm *pwm, unsigned int idx); + int (*cfg_interrupt)(struct metal_pwm *pwm, metal_pwm_interrupt_t flag); + int (*clr_interrupt)(struct metal_pwm *pwm, unsigned int idx); + struct metal_interrupt *(*get_interrupt_controller)(struct metal_pwm *pwm); + int (*get_interrupt_id)(struct metal_pwm *pwm, unsigned int idx); +}; + +/*! @brief A handle for a PWM device. */ +struct metal_pwm { + const struct metal_pwm_vtable *vtable; +}; + +/*! @brief Gets a PWM device handle. + * @param device_num The index of the desired PWM device. + * @return A handle to the PWM device, or NULL if the device does not exist.*/ +struct metal_pwm *metal_pwm_get_device(unsigned int device_num); + +/*! @brief Enables PWM operation. + * @param pwm The handle for the PWM device to initialize. + * @return 0 If no error.*/ +inline int metal_pwm_enable(struct metal_pwm *pwm) { + return pwm->vtable->enable(pwm); +} + +/*! @brief Disables PWM operation. + * @param pwm The handle for the PWM device to be disabled. + * @return 0 If no error.*/ +inline int metal_pwm_disable(struct metal_pwm *pwm) { + return pwm->vtable->disable(pwm); +} + +/*! @brief Sets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param freq PWM frequency in Hz. + * @return 0 If no error.*/ +inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx, + unsigned int freq) { + return pwm->vtable->set_freq(pwm, idx, freq); +} + +/*! @brief Sets duty cycle in percent values [0 - 100] for a given PWM instance. + * Phase correct mode provides center aligned PWM waveform output. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param duty PWM duty cycle value. + * @param phase_corr Enable / Disable phase correct mode. + * @return 0 If no error.*/ +inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx, + unsigned int duty, + metal_pwm_phase_correct_t phase_corr) { + return pwm->vtable->set_duty(pwm, idx, duty, phase_corr); +} + +/*! @brief Gets duty cycle in percent values [0 - 100] for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM duty cycle value.*/ +inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_duty(pwm, idx); +} + +/*! @brief Gets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM frequency in Hz.*/ +inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_freq(pwm, idx); +} + +/*! @brief Starts a PWM instance in selected run mode (continuous/one shot). + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode) { + return pwm->vtable->trigger(pwm, idx, mode); +} + +/*! @brief Stops a running PWM instance in continuous mode. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->stop(pwm, idx); +} + +/*! @brief Enable or Disable PWM interrupts. + * @param pwm PWM device handle. + * @param flag PWM interrupt enable flag. + * @return 0 If no error.*/ +inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm, + metal_pwm_interrupt_t flag) { + return pwm->vtable->cfg_interrupt(pwm, flag); +} + +/*! @brief Clears pending interrupt flags. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->clr_interrupt(pwm, idx); +} + +/*! @brief Get the interrupt controller of the PWM peripheral. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param pwm PWM device handle. + * @return The handle for the PWM interrupt controller.*/ +inline struct metal_interrupt * +metal_pwm_interrupt_controller(struct metal_pwm *pwm) { + return pwm->vtable->get_interrupt_controller(pwm); +} + +/*! @brief Get the interrupt ID of the PWM peripheral. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return The PWM interrupt id.*/ +inline int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->get_interrupt_id(pwm, idx); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h new file mode 100644 index 000000000..e1b798268 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h @@ -0,0 +1,137 @@ +/* Copyright 2019 SiFive, Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__RTC_H +#define METAL__RTC_H + +#include + +/*! + * @file rtc.h + * @brief API for Real-Time Clocks + */ + +struct metal_rtc; + +/*! + * @brief List of RTC run behaviors + */ +enum metal_rtc_run_option { + METAL_RTC_STOP = 0, + METAL_RTC_RUN, +}; + +struct metal_rtc_vtable { + uint64_t (*get_rate)(const struct metal_rtc *const rtc); + uint64_t (*set_rate)(const struct metal_rtc *const rtc, + const uint64_t rate); + uint64_t (*get_compare)(const struct metal_rtc *const rtc); + uint64_t (*set_compare)(const struct metal_rtc *const rtc, + const uint64_t compare); + uint64_t (*get_count)(const struct metal_rtc *const rtc); + uint64_t (*set_count)(const struct metal_rtc *const rtc, + const uint64_t count); + int (*run)(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option); + struct metal_interrupt *(*get_interrupt)(const struct metal_rtc *const rtc); + int (*get_interrupt_id)(const struct metal_rtc *const rtc); +}; + +/*! + * @brief Handle for a Real-Time Clock + */ +struct metal_rtc { + const struct metal_rtc_vtable *vtable; +}; + +/*! + * @brief Get the rate of the RTC + * @return The rate in Hz + */ +inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc) { + return rtc->vtable->get_rate(rtc); +} + +/*! + * @brief Set (if possible) the rate of the RTC + * @return The new rate of the RTC (not guaranteed to be the same as requested) + */ +inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, + const uint64_t rate) { + return rtc->vtable->set_rate(rtc, rate); +} + +/*! + * @brief Get the compare value of the RTC + * @return The compare value + */ +inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc) { + return rtc->vtable->get_compare(rtc); +} + +/*! + * @brief Set the compare value of the RTC + * @return The set compare value (not guaranteed to be exactly the requested + * value) + * + * The RTC device might impose limits on the maximum compare value or the + * granularity of the compare value. + */ +inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, + const uint64_t compare) { + return rtc->vtable->set_compare(rtc, compare); +} + +/*! + * @brief Get the current count of the RTC + * @return The count + */ +inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc) { + return rtc->vtable->get_count(rtc); +} + +/*! + * @brief Set the current count of the RTC + * @return The set value of the count (not guaranteed to be exactly the + * requested value) + * + * The RTC device might impose limits on the maximum value of the count + */ +inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, + const uint64_t count) { + return rtc->vtable->set_count(rtc, count); +} + +/*! + * @brief Start or stop the RTC + * @return 0 if the RTC was successfully started/stopped + */ +inline int metal_rtc_run(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option) { + return rtc->vtable->run(rtc, option); +} + +/*! + * @brief Get the interrupt handle for the RTC compare + * @return The interrupt handle + */ +inline struct metal_interrupt * +metal_rtc_get_interrupt(const struct metal_rtc *const rtc) { + return rtc->vtable->get_interrupt(rtc); +} + +/*! + * @brief Get the interrupt ID for the RTC compare + * @return The interrupt ID + */ +inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc) { + return rtc->vtable->get_interrupt_id(rtc); +} + +/*! + * @brief Get the handle for an RTC by index + * @return The RTC handle, or NULL if none is available at that index + */ +struct metal_rtc *metal_rtc_get_device(int index); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h new file mode 100644 index 000000000..51683cc76 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h @@ -0,0 +1,13 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SCRUB_H +#define METAL__SCRUB_H + +/*! @brief Writes specified memory region with zeros. + * @param address Start memory address for zero-scrub. + * @param size Memory region size in bytes. + * @return None.*/ +void metal_mem_scrub(void *address, int size); + +#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 index 3bebfa742..7a43437b7 100644 --- 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 @@ -12,15 +12,20 @@ struct __metal_shutdown; struct __metal_shutdown_vtable { - void (*exit)(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); + 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); } +__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 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 index b011fe3ce..7e4b04ae2 100644 --- 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 @@ -9,11 +9,7 @@ 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; + 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; @@ -25,11 +21,24 @@ struct metal_spi_config { unsigned int cs_active_high : 1; /*! @brief The chip select ID to activate for the SPI transfer */ unsigned int csid; + /*! @brief The spi command frame number (cycles = num * frame_len) */ + unsigned int cmd_num; + /*! @brief The spi address frame number */ + unsigned int addr_num; + /*! @brief The spi dummy frame number */ + unsigned int dummy_num; + /*! @brief The Dual/Quad spi mode selection.*/ + enum { + MULTI_WIRE_ALL, + MULTI_WIRE_DATA_ONLY, + MULTI_WIRE_ADDR_DATA + } multi_wire; }; 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 (*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); }; @@ -42,23 +51,29 @@ struct metal_spi { /*! @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); +struct metal_spi *metal_spi_get_device(unsigned 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); } +__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. + * @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) { +__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); } @@ -66,13 +81,17 @@ inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *co * @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); } +__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); } +__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 index d1c35bc93..695b21ae3 100644 --- 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 @@ -15,7 +15,7 @@ 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); + struct metal_interrupt *(*interrupt_controller)(struct metal_switch *sw); int (*get_interrupt_id)(struct metal_switch *sw); }; @@ -29,23 +29,28 @@ struct metal_switch { /*! * @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 + * @return A handle to the switch, or NULL if none is found for the requested + * label */ -struct metal_switch* metal_switch_get(char *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); } +__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); } +__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/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h new file mode 100644 index 000000000..a5a880f0d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h @@ -0,0 +1,21 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TIME_H +#define METAL__TIME_H + +#include +#ifndef __SEGGER_LIBC__ +#include +#endif + +/*! + * @file time.h + * @brief API for dealing with time + */ + +int metal_gettimeofday(struct timeval *tp, void *tzp); + +time_t metal_time(void); + +#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 index eeae1f60b..5d5132de5 100644 --- 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 @@ -23,9 +23,10 @@ int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); * @param timebase The variable to hold the value * @return 0 upon success */ -int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase); +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 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 index d2583e3be..5d41783ae 100644 --- 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 @@ -14,10 +14,22 @@ * * 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); +int metal_tty_putc(int c); + +/*! + * @brief Get a byte from the default output device + * + * The default output device, is typically the UART serial port. + * + * This call is non-blocking, if nothing is ready c==-1 + * if something is ready, then c=[0x00 to 0xff] byte value. + * + * @return 0 on success, or -1 on failure. + */ +int metal_tty_getc(int *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 index 611792a6c..856970ac2 100644 --- 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 @@ -12,15 +12,25 @@ #include struct metal_uart; - +#undef getc +#undef putc 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 (*putc)(struct metal_uart *uart, int c); + int (*txready)(struct metal_uart *uart); + int (*getc)(struct metal_uart *uart, int *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); + struct metal_interrupt *(*controller_interrupt)(struct metal_uart *uart); int (*get_interrupt_id)(struct metal_uart *uart); + int (*tx_interrupt_enable)(struct metal_uart *uart); + int (*tx_interrupt_disable)(struct metal_uart *uart); + int (*rx_interrupt_enable)(struct metal_uart *uart); + int (*rx_interrupt_disable)(struct metal_uart *uart); + int (*set_tx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_tx_watermark)(struct metal_uart *uart); + int (*set_rx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_rx_watermark)(struct metal_uart *uart); }; /*! @@ -30,16 +40,25 @@ struct metal_uart { const struct metal_uart_vtable *vtable; }; +/*! @brief Get a handle for a UART device + * @param device_num The index of the desired UART device + * @return A handle to the UART device, or NULL if the device does not exist*/ +struct metal_uart *metal_uart_get_device(unsigned int device_num); + /*! * @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. + + * 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); } +__inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) { + uart->vtable->init(uart, baud_rate); +} /*! * @brief Output a character over the UART @@ -47,22 +66,40 @@ inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uar * @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); } +__inline__ int metal_uart_putc(struct metal_uart *uart, int c) { + return uart->vtable->putc(uart, c); +} + +/*! + * @brief Test, determine if tx output is blocked(full/busy) + * @param uart The UART device handle + * @return 0 not blocked + */ +__inline__ int metal_uart_txready(struct metal_uart *uart) { + return uart->vtable->txready(uart); +} /*! * @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 + * + * If "c == -1" no char was ready. + * If "c != -1" then C == byte value (0x00 to 0xff) */ -inline int metal_uart_getc(struct metal_uart *uart, unsigned char *c) { return uart->vtable->getc(uart, c); } +__inline__ int metal_uart_getc(struct metal_uart *uart, int *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); } +__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 @@ -70,7 +107,10 @@ inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtab * @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); } +__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 @@ -82,13 +122,94 @@ inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { re * @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); } +__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); } +__inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) { + return uart->vtable->get_interrupt_id(uart); +} + +/*! + * @brief Enable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_disable(uart); +} + +/*! + * @brief Enable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_disable(uart); +} + +/*! + * @brief Set the transmit watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_tx_watermark(uart, level); +} + +/*! + * @brief Get the transmit watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_transmit_watermark(struct metal_uart *uart) { + return uart->vtable->get_tx_watermark(uart); +} + +/*! + * @brief Set the receive watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_rx_watermark(uart, level); +} + +/*! + * @brief Get the receive watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_receive_watermark(struct metal_uart *uart) { + return uart->vtable->get_rx_watermark(uart); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h new file mode 100644 index 000000000..2f84d3b49 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h @@ -0,0 +1,168 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__WATCHDOG_H +#define METAL__WATCHDOG_H + +/*! + * @file watchdog.h + * + * @brief API for configuring watchdog timers + */ + +#include + +struct metal_watchdog; + +/*! + * @brief List of watchdog timer count behaviors + */ +enum metal_watchdog_run_option { + METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */ + METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during + sleep */ + METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake + */ +}; + +/*! + * @brief List of behaviors when a watchdog triggers + */ +enum metal_watchdog_result { + METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */ + METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt + */ + METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full + system reset */ +}; + +struct metal_watchdog_vtable { + int (*feed)(const struct metal_watchdog *const wdog); + long int (*get_rate)(const struct metal_watchdog *const wdog); + long int (*set_rate)(const struct metal_watchdog *const wdog, + const long int rate); + long int (*get_timeout)(const struct metal_watchdog *const wdog); + long int (*set_timeout)(const struct metal_watchdog *const wdog, + const long int timeout); + int (*set_result)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result); + int (*run)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option); + struct metal_interrupt *(*get_interrupt)( + const struct metal_watchdog *const wdog); + int (*get_interrupt_id)(const struct metal_watchdog *const wdog); + int (*clear_interrupt)(const struct metal_watchdog *const wdog); +}; + +/*! + * @brief Handle for a Watchdog Timer + */ +struct metal_watchdog { + const struct metal_watchdog_vtable *vtable; +}; + +/*! + * @brief Feed the watchdog timer + */ +inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) { + return wdog->vtable->feed(wdog); +} + +/*! + * @brief Get the rate of the watchdog timer in Hz + * + * @return the rate of the watchdog timer + */ +inline long int +metal_watchdog_get_rate(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_rate(wdog); +} + +/*! + * @brief Set the rate of the watchdog timer in Hz + * + * There is no guarantee that the new rate will match the requested rate. + * + * @return the new rate of the watchdog timer + */ +inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, + const long int rate) { + return wdog->vtable->set_rate(wdog, rate); +} + +/*! + * @brief Get the timeout of the watchdog timer + * + * @return the watchdog timeout value + */ +inline long int +metal_watchdog_get_timeout(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_timeout(wdog); +} + +/*! + * @brief Set the timeout of the watchdog timer + * + * The set rate will be the minimimum of the requested and maximum supported + * rates. + * + * @return the new watchdog timeout value + */ +inline long int +metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, + const long int timeout) { + return wdog->vtable->set_timeout(wdog, timeout); +} + +/*! + * @brief Sets the result behavior of a watchdog timer timeout + * + * @return 0 if the requested result behavior is supported + */ +inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result) { + return wdog->vtable->set_result(wdog, result); +} + +/*! + * @brief Set the run behavior of the watchdog + * + * Used to enable/disable the watchdog timer + * + * @return 0 if the watchdog was successfully started/stopped + */ +inline int metal_watchdog_run(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option) { + return wdog->vtable->run(wdog, option); +} + +/*! + * @brief Get the interrupt controller for the watchdog interrupt + */ +inline struct metal_interrupt * +metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt(wdog); +} + +/*! + * @Brief Get the interrupt id for the watchdog interrupt + */ +inline int +metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt_id(wdog); +} + +/*! + * @brief Clear the watchdog interrupt + */ +inline int +metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->clear_interrupt(wdog); +} + +/*! + * @brief Get a watchdog handle + */ +struct metal_watchdog *metal_watchdog_get_device(const int index); + +#endif /* METAL__WATCHDOG_H */ 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 index 8c0cd048b..fd05ab065 100644 --- 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 @@ -5,128 +5,181 @@ #ifndef ASSEMBLY -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#ifndef METAL_INLINE_H +#define METAL_INLINE_H #include /* --------------------- fixed_clock ------------ */ -extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *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); +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); +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); +extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(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); +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); +extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid); + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- 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); +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); +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_i2c0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); + + +/* --------------------- sifive_pwm0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx); +extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm); + + +/* --------------------- sifive_rtc0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc); +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc); +extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc); +extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc); + + /* --------------------- 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); +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_trace ------------ */ + /* --------------------- 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); +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_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog); +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog); +extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog); /* --------------------- 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); +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); +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_lfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(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( ); +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 ------------ */ +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( ); /* From clock@0 */ @@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = { .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, }; +/* From clock@6 */ +struct __metal_driver_fixed_clock __metal_dt_clock_6 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + struct metal_memory __metal_dt_mem_dtim_80000000 = { ._base_address = 2147483648UL, ._size = 16384UL, @@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_itim_8000000 = { + ._base_address = 134217728UL, + ._size = 8192UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + struct metal_memory __metal_dt_mem_spi_10014000 = { ._base_address = 536870912UL, ._size = 500000UL, @@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_spi_10024000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10034000 = { + ._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, @@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { /* From cpu@0 */ struct __metal_driver_cpu __metal_dt_cpu_0 = { .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, + .hpm_count = 0, }; /* From interrupt_controller */ @@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { .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, -}; +struct metal_pmp __metal_dt_pmp; /* 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 = { +/* From led@0 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { +/* From led@1 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { +/* From led@2 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; + +/* From pwm@10015000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10025000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10035000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = { + .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc, +}; + /* From spi@10014000 */ struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, }; +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .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 serial@10023000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = { + .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog, +}; + /* From clock@3 */ struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, @@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock, }; +/* From clock@7 */ +struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.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, @@ -242,8 +376,9 @@ 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 = { + .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci, }; -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ +#endif /* 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 index 4ecd3e336..d517b5859 100644 --- 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 @@ -3,8 +3,8 @@ /* ----------------------------------- */ /* ----------------------------------- */ -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#ifndef METAL_PLATFORM_H +#define METAL_PLATFORM_H /* From clock@0 */ #define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL @@ -13,7 +13,10 @@ #define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL /* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL + +/* From clock@6 */ +#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL #define METAL_FIXED_CLOCK @@ -35,15 +38,18 @@ #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_C000000_RISCV_NDEV 53UL +#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL #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 +#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL +#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL +#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL +#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL +#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL /* From aon@10000000 */ #define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL @@ -111,6 +117,10 @@ #define METAL_SIFIVE_FE310_G000_HFXOSC +/* From clock@7 */ + +#define METAL_SIFIVE_FE310_G000_LFROSC + /* From prci@10008000 */ #define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL #define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL @@ -153,11 +163,11 @@ #define METAL_SIFIVE_GPIO0_IOF_SEL 60UL #define METAL_SIFIVE_GPIO0_OUT_XOR 64UL -/* From led@0red */ +/* From led@0 */ -/* From led@0green */ +/* From led@1 */ -/* From led@0blue */ +/* From led@2 */ #define METAL_SIFIVE_GPIO_LEDS @@ -176,16 +186,24 @@ #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 +/* From pwm@10025000 */ +#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_1_SIZE 4096UL + +/* From pwm@10035000 */ +#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_2_SIZE 4096UL + #define METAL_SIFIVE_PWM0 #define METAL_SIFIVE_PWM0_PWMCFG 0UL #define METAL_SIFIVE_PWM0_PWMCOUNT 8UL @@ -195,12 +213,37 @@ #define METAL_SIFIVE_PWM0_PWMCMP2 40UL #define METAL_SIFIVE_PWM0_PWMCMP3 44UL +/* 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_RTC0 +#define METAL_SIFIVE_RTC0_RTCCFG 64UL +#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL +#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL +#define METAL_SIFIVE_RTC0_RTCS 80UL +#define METAL_SIFIVE_RTC0_RTCCMP0 96UL + /* 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 +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + #define METAL_SIFIVE_SPI0 #define METAL_SIFIVE_SPI0_SCKDIV 0UL #define METAL_SIFIVE_SPI0_SCKMODE 4UL @@ -225,6 +268,12 @@ #define METAL_SIFIVE_UART0_10013000_SIZE 4096UL #define METAL_SIFIVE_UART0_0_SIZE 4096UL +/* From serial@10023000 */ +#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL +#define METAL_SIFIVE_UART0_1_SIZE 4096UL + #define METAL_SIFIVE_UART0 #define METAL_SIFIVE_UART0_TXDATA 0UL #define METAL_SIFIVE_UART0_RXDATA 4UL @@ -234,4 +283,20 @@ #define METAL_SIFIVE_UART0_IP 20UL #define METAL_SIFIVE_UART0_DIV 24UL -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ +/* 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_WDOG0 +#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL +#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL +#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL +#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL +#define METAL_SIFIVE_WDOG0_WDOGS 16UL +#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL +#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL +#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL + +#endif /* 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 index 7070af7e8..be7f84c71 100644 --- 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 @@ -1,236 +1,302 @@ -/* Copyright 2019 SiFive, Inc */ +/* Copyright (c) 2020 SiFive Inc. */ /* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - OUTPUT_ARCH("riscv") +/* Default Linker Script + * + * This is the default linker script for all Freedom Metal applications. + */ + ENTRY(_enter) MEMORY { - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 - flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120 + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 } PHDRS { - flash PT_LOAD; - ram_init PT_LOAD; - itim_init PT_LOAD; - ram PT_NULL; - itim PT_NULL; + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; } 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); + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; - .init : - { - KEEP (*(.text.metal.init.enter)) - KEEP (*(SORT_NONE(.init))) - KEEP (*(.text.libgloss.start)) - } >flash AT>flash :flash + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.itim .itim.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >flash AT>flash :flash + .init_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + .fini_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom - . = ALIGN(4); + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >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)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom :rom - .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 + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init - .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 + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ - .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 + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); - .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 + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom :text - .litimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_source_start = . ); - } >flash AT>flash :flash + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom :ram_init - .ditimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_target_start = . ); - } >ram AT>flash :ram_init + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); - .itim : - { - *(.itim .itim.*) - } >flash AT>flash :flash + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); - . = ALIGN(8); - PROVIDE( metal_segment_itim_target_end = . ); + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - PROVIDE( metal_segment_data_source_start = . ); - } >flash AT>flash :flash + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + - .dalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_data_target_start = . ); - } >ram AT>flash :ram_init + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + __freertos_irq_stack_top = .; + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram - .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 - - -} - + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds new file mode 100644 index 000000000..4798504ed --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds @@ -0,0 +1,327 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* Privileged mode Linker Script + * + * This linker script is based on metal.default.lds. It introduce specific + * section to isolate (acessible only from machine mode) and others that can be + * used in every execution mode. This linker script it tailored for FreeRTOS + * applications. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom + + .init_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + + .fini_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom + + .privileged_functions : ALIGN (32) { + __privileged_functions_start__ = .; + KEEP(*(privileged_functions)) + . = ALIGN(32); + __privileged_functions_end__ = .; + } >rom + + + .ctors : { + . = ALIGN(32); + __unprivileged_section_start__ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + *(freertos_system_calls) + . = ALIGN(32); + __unprivileged_section_end__ = .; + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + . = ALIGN(32); + __unprivileged_data_section_start__ = .; + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32); + __unprivileged_data_section_end__ = .; + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + .privileged_data (NOLOAD) : ALIGN(32) { + __privileged_data_start__ = .; + *(privileged_data) + /* Non kernel data is kept out of the first _Privileged_Data_Region_Size + bytes of SRAM. */ + . = ALIGN(32); + __privileged_data_end__ = .; + } >ram + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} \ No newline at end of file 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 index f76dbd632..74c361b4b 100644 --- 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 @@ -9,15 +9,15 @@ #ifdef __METAL_MACHINE_MACROS -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_IF_METAL_H +#define MACROS_IF_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_SUBINTERRUPTS 53 #define __METAL_PLIC_NUM_PARENTS 1 @@ -31,12 +31,12 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #endif -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_IF_METAL_H*/ #else /* ! __METAL_MACHINE_MACROS */ -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_ELSE_METAL_H +#define MACROS_ELSE_METAL_H #define __METAL_CLINT_2000000_INTERRUPTS 2 @@ -46,7 +46,7 @@ #define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define METAL_MAX_PLIC_INTERRUPTS 1 @@ -55,20 +55,36 @@ #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_LOCAL_EXT_INTERRUPTS 0 #define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0 -#define __METAL_GPIO_10012000_INTERRUPTS 16 +#define __METAL_GPIO_10012000_INTERRUPTS 32 -#define METAL_MAX_GPIO_INTERRUPTS 16 +#define METAL_MAX_GPIO_INTERRUPTS 32 + +#define __METAL_I2C_10016000_INTERRUPTS 1 + +#define METAL_MAX_I2C0_INTERRUPTS 1 + +#define __METAL_PWM_10015000_INTERRUPTS 4 + +#define __METAL_PWM_10025000_INTERRUPTS 4 + +#define __METAL_PWM_10035000_INTERRUPTS 4 + +#define METAL_MAX_PWM0_INTERRUPTS 4 + +#define METAL_MAX_PWM0_NCMP 4 #define __METAL_SERIAL_10013000_INTERRUPTS 1 +#define __METAL_SERIAL_10023000_INTERRUPTS 1 + #define METAL_MAX_UART_INTERRUPTS 1 +#define METAL_MAX_SIMUART_INTERRUPTS 0 + #include #include @@ -76,79 +92,119 @@ #include #include #include -#include #include #include +#include +#include +#include #include #include +#include #include #include +#include #include #include /* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0; +extern struct __metal_driver_fixed_clock __metal_dt_clock_0; /* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; +extern struct __metal_driver_fixed_clock __metal_dt_clock_2; /* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; +extern struct __metal_driver_fixed_clock __metal_dt_clock_5; -struct metal_memory __metal_dt_mem_dtim_80000000; +/* From clock@6 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_6; -struct metal_memory __metal_dt_mem_spi_10014000; +extern struct metal_memory __metal_dt_mem_dtim_80000000; + +extern struct metal_memory __metal_dt_mem_itim_8000000; + +extern struct metal_memory __metal_dt_mem_spi_10014000; + +extern struct metal_memory __metal_dt_mem_spi_10024000; + +extern struct metal_memory __metal_dt_mem_spi_10034000; /* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; +extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; /* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; +extern struct __metal_driver_cpu __metal_dt_cpu_0; -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; +extern 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; +extern 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; +extern struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; +extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; +/* From led@0 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; +/* From led@1 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; +/* From led@2 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2; + +/* From i2c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; + +/* From pwm@10015000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; + +/* From pwm@10025000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000; + +/* From pwm@10035000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000; /* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10034000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; /* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From serial@10023000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000; /* From clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; +extern 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; +extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; + +/* From clock@7 */ +extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7; /* From clock@4 */ -struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; +extern 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; +extern 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) +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; @@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) { + return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY; + } else { return 0; } @@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c /* --------------------- sifive_clint0 ------------ */ -static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) +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; @@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met } } -static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) +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; @@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met } } -static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) +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; @@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter } } -static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) +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; @@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa } } -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 3; @@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte /* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 0; @@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) } } -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; + return 16000000; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) +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; @@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s } } -static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) +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; @@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) } } +static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return NULL; + } + else { + return NULL; + } +} + /* --------------------- sifive_plic0 ------------ */ -static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) +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; @@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta } } -static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) +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; @@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta } } -static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) +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; @@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr } } -static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) +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; @@ -312,120 +381,52 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup } } -static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) +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) +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; } } +static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid) +{ + if (hartid == 0) { + return 0; + } + else { + return -1; + } +} + + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- 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) +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; @@ -435,7 +436,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio * } } -static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) +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; @@ -445,7 +446,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio * } } -static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) +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; @@ -455,7 +456,7 @@ static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio * } } -static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +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; @@ -465,56 +466,104 @@ static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_par } } -static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) +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))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { return 9; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { return 10; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { return 11; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { return 12; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { return 13; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { return 14; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { return 15; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { return 16; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { return 17; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { return 18; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { return 19; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { return 20; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { return 21; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { return 22; } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + return 23; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) { + return 24; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) { + return 25; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) { + return 26; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) { + return 29; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) { + return 30; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) { + return 31; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) { + return 32; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) { + return 33; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) { + return 34; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) { + return 35; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) { + return 36; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) { + return 29; + } else { return 0; } @@ -526,15 +575,15 @@ static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio /* --------------------- sifive_gpio_led ------------ */ -static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *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) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return (struct metal_gpio *)&__metal_dt_gpio_10012000; } else { @@ -542,15 +591,15 @@ static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct met } } -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return 22; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return 19; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return 21; } else { @@ -558,15 +607,15 @@ static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) } } -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { return "LD0red"; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { return "LD0green"; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { return "LD0blue"; } else { @@ -579,45 +628,430 @@ static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) /* --------------------- sifive_gpio_switch ------------ */ -/* --------------------- sifive_spi0 ------------ */ -static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) +/* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_pwm0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return __METAL_PWM_10015000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return __METAL_PWM_10025000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return __METAL_PWM_10035000_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx) +{ + if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) { + return 40; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) { + return 41; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) { + return 42; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) { + return 43; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) { + return 44; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) { + return 45; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) { + return 46; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) { + return 47; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) { + return 48; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) { + return 49; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) { + return 50; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) { + return 51; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 8; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 16; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 16; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 4; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_rtc0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return 2; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} + + +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 if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) +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 if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_SIZE; + } else { return 0; } } -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) { - return 60; + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { return 60; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 4227858432; + } + else { + return 0; + } } @@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_SIZE; + } else { return 0; } } -static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_MAX_UART_INTERRUPTS; + } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) +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 if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) { - return 5; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 3; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 4; + } + else { + return 0; + } } -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) { - return 196608; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 0; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return 196608; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 8650752; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return 1; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } } /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) +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) +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) +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) +static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; } @@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) +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) +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) +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_lfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_5.clock; + } + else { + return NULL; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_6.clock; + } + else { + return NULL; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 112; + } + else { + return 0; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 124; + } + else { + return 0; + } +} + + + /* --------------------- sifive_fe310_g000_pll ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) +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) +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) +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) +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( ) +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( ) +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( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ) { return 16000000; } @@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) /* --------------------- sifive_fe310_g000_prci ------------ */ -static inline long __metal_driver_sifive_fe310_g000_prci_base( ) +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( ) +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( ) +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 3 - -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); +__asm__ (".weak __metal_memory_table"); struct metal_memory *__metal_memory_table[] = { &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_itim_8000000, &__metal_dt_mem_spi_10014000}; /* From serial@10013000 */ @@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = { #define __METAL_DT_MAX_HARTS 1 -asm (".weak __metal_cpu_table"); +#define __METAL_CPU_0_ICACHE_HANDLE 1 + +__asm__ (".weak __metal_cpu_table"); struct __metal_driver_cpu *__metal_cpu_table[] = { &__metal_dt_cpu_0}; @@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = { #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"); +__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"); +__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"); +__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}; + &__metal_dt_led_0, + &__metal_dt_led_1, + &__metal_dt_led_2}; #define __METAL_DT_MAX_SWITCHES 0 -asm (".weak __metal_switch_table"); +__asm__ (".weak __metal_switch_table"); struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { NULL }; -#define __METAL_DT_MAX_SPIS 1 +#define __METAL_DT_MAX_I2CS 1 -asm (".weak __metal_spi_table"); +__asm__ (".weak __metal_i2c_table"); +struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = { + &__metal_dt_i2c_10016000}; + +#define __METAL_DT_MAX_PWMS 3 + +__asm__ (".weak __metal_pwm_table"); +struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = { + &__metal_dt_pwm_10015000, + &__metal_dt_pwm_10025000, + &__metal_dt_pwm_10035000}; + +#define __METAL_DT_MAX_RTCS 1 + +__asm__ (".weak __metal_rtc_table"); +struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = { + &__metal_dt_rtc_10000000}; + +#define __METAL_DT_MAX_SPIS 3 + +__asm__ (".weak __metal_spi_table"); struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; + +#define __METAL_DT_MAX_UARTS 2 + +__asm__ (".weak __metal_uart_table"); +struct __metal_driver_sifive_uart0 *__metal_uart_table[] = { + &__metal_dt_serial_10013000, + &__metal_dt_serial_10023000}; + +#define __METAL_DT_MAX_SIMUARTS 0 + +__asm__ (".weak __metal_simuart_table"); +struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = { + NULL }; +#define __METAL_DT_MAX_WDOGS 1 + +__asm__ (".weak __metal_wdog_table"); +struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = { + &__metal_dt_aon_10000000}; /* 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 /* MACROS_ELSE_METAL_H*/ #endif /* ! __METAL_MACHINE_MACROS */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds new file mode 100644 index 000000000..6803873ce --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds @@ -0,0 +1,306 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* RAM Read-Only Data Linker Script + * + * This linker script places application code and read-only data into writable + * memories in an attempt to improve performance, since writable memories + * are generally lower-latency. This linker script may cause your application + * to overflow RAM, since it dramatically increases the quantity of data vying + * for space there. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom + + .init_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + + .fini_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom + + + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + /* Read-only data is placed in RAM to improve performance, since + * read-only memory generally has higher latency than RAM */ + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(8); + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >ram AT>rom :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds new file mode 100644 index 000000000..356726912 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds @@ -0,0 +1,294 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* Scratchpad Linker Script + * + * This linker script is for executing in "scratchpad" mode, where all + * application code and data is placed in writable memory. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + PROVIDE(__metal_eccscrub_bit = 0); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >ram :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >ram :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram :rom + + .init_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >ram :rom + + .fini_array : ALIGN(8) { + 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 = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >ram :rom + + + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >ram :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >ram : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>ram :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>ram :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >ram :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>ram :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>ram :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk new file mode 100644 index 000000000..a8ddd99f2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2020 SiFive Inc +# SPDX-License-Identifier: Apache-2.0 + +RISCV_ARCH = rv32imac +RISCV_ABI = ilp32 +RISCV_CMODEL = medlow +RISCV_SERIES = sifive-3-series + +TARGET_TAGS = board jlink +TARGET_DHRY_ITERS = 20000000 +TARGET_CORE_ITERS = 5000 +TARGET_FREERTOS_WAIT_MS = 1000 +TARGET_INTR_WAIT_CYCLE = 0 \ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format new file mode 100644 index 000000000..f9d627fe6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +Language: Cpp + +IndentWidth: 4 + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml new file mode 100644 index 000000000..04ce26935 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml @@ -0,0 +1,35 @@ +sudo: required + +# Travis doesn't provide a wide variety of host environments to run on, so we +# rely on Docker to provide these instead. +services: + - docker + +# It is not really needed, other than for showing correct language tag in +# Travis CI build log. +language: c + +# The matrix of targets that we're interested in. +env: + - HOST="ubuntu:16.04" + +# Before running the install phase we need to set up docker container that runs +# the target machine. +before_install: + - docker run -d --name host -v $(pwd):/travis $HOST tail -f /dev/null + - docker ps + +# Update the container and install dependencies +install: + - docker exec -t host bash -c "yes | apt-get update" + - docker exec -t host bash -c "yes | apt-get upgrade" + - docker exec -t host bash -c "yes | apt-get install git clang-format-6.0" + - sudo curl -L -o /tmp/wake.deb https://github.com/sifive/wake/releases/download/v0.19.0/ubuntu-16-04-wake_0.19.0-1_amd64.deb + - sudo apt install /tmp/wake.deb + +# Here's where we actually run the test. +script: +# Check source code formatting + - docker exec -t host bash -c "cd /travis && ./scripts/check-format" +# Run dummy Wake program in order to run Wake type checker. + - wake --init . && wake -x Unit diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile new file mode 100644 index 000000000..22c8f7845 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile @@ -0,0 +1,2537 @@ +# Doxyfile 1.8.15 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Freedom Metal" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Bare Metal Compatibility Library for the Freedom Platform" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = "doc" + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = metal + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = metal/compiler.h metal/io.h metal/machine.h + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = _* __* *vtable + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /