From 9157a420428030f36dcd5a78180a496f3322c5b5 Mon Sep 17 00:00:00 2001 From: Stanislaw Kaushanski Date: Wed, 16 Sep 2020 10:28:54 +0200 Subject: [PATCH] raven FW with data and interrupt transfer (based on bldc project) --- raven/Makefile | 30 +- raven/bsp/Debug/drivers/fe300prci/subdir.mk | 24 - raven/bsp/Debug/drivers/plic/subdir.mk | 24 - .../bsp/Debug/env/freedom-e300-arty/subdir.mk | 24 - .../Debug/env/freedom-e300-hifive1/subdir.mk | 27 - raven/bsp/Debug/env/iss/subdir.mk | 27 - raven/bsp/Debug/env/subdir.mk | 27 - raven/bsp/Debug/libwrap/stdlib/subdir.mk | 27 - raven/bsp/Debug/libwrap/sys/subdir.mk | 98 - raven/bsp/Debug/makefile | 66 - raven/bsp/Debug/objects.mk | 8 - raven/bsp/Debug/sources.mk | 35 - raven/bsp/drivers/clic/clic_driver.c | 163 ++ raven/bsp/drivers/clic/clic_driver.h | 44 + .../bsp/drivers/fe300prci/fe300prci_driver.c | 2 +- raven/bsp/drivers/plic/plic_driver.c | 25 +- raven/bsp/drivers/plic/plic_driver.h | 5 +- raven/bsp/env/common.mk | 38 +- raven/bsp/env/coreip-e2-arty/flash.lds | 161 ++ raven/bsp/env/coreip-e2-arty/init.c | 98 + raven/bsp/env/coreip-e2-arty/openocd.cfg | 31 + raven/bsp/env/coreip-e2-arty/platform.h | 98 + raven/bsp/env/coreip-e2-arty/settings.mk | 3 + raven/bsp/env/coreip-e2-arty/tim-split.lds | 157 ++ raven/bsp/env/coreip-e2-arty/tim.lds | 161 ++ raven/bsp/env/coreplexip-arty.h | 102 + .../bsp/env/coreplexip-e31-arty/dhrystone.lds | 157 ++ raven/bsp/env/coreplexip-e31-arty/flash.lds | 161 ++ raven/bsp/env/coreplexip-e31-arty/init.c | 122 + raven/bsp/env/coreplexip-e31-arty/openocd.cfg | 31 + raven/bsp/env/coreplexip-e31-arty/platform.h | 100 + .../env/coreplexip-e31-arty/scratchpad.lds | 161 ++ raven/bsp/env/coreplexip-e31-arty/settings.mk | 3 + .../bsp/env/coreplexip-e51-arty/dhrystone.lds | 157 ++ raven/bsp/env/coreplexip-e51-arty/flash.lds | 161 ++ raven/bsp/env/coreplexip-e51-arty/init.c | 122 + raven/bsp/env/coreplexip-e51-arty/openocd.cfg | 31 + raven/bsp/env/coreplexip-e51-arty/platform.h | 100 + .../env/coreplexip-e51-arty/scratchpad.lds | 161 ++ raven/bsp/env/coreplexip-e51-arty/settings.mk | 3 + raven/bsp/env/entry.S | 1 + .../freedom-e300-arty/{link.lds => flash.lds} | 16 +- raven/bsp/env/freedom-e300-arty/platform.h | 55 +- raven/bsp/env/freedom-e300-arty/settings.mk | 3 + .../dhrystone.lds} | 29 +- .../{link.lds => flash.lds} | 16 +- raven/bsp/env/freedom-e300-hifive1/init.c | 4 +- raven/bsp/env/freedom-e300-hifive1/platform.h | 66 +- .../bsp/env/freedom-e300-hifive1/settings.mk | 3 + raven/bsp/env/hifive1.h | 2 + raven/bsp/env/iss/init.c | 238 -- raven/bsp/env/iss/openocd.cfg | 34 - raven/bsp/env/iss/platform.h | 133 - raven/bsp/env/start.S | 59 +- raven/bsp/env/ventry.S | 288 +++ raven/bsp/include/sifive/bits.h | 3 +- raven/bsp/include/sifive/const.h | 1 + raven/bsp/include/sifive/devices/clic.h | 30 + raven/bsp/include/sifive/devices/spi.h | 4 +- raven/bsp/include/sifive/sections.h | 1 + raven/bsp/include/sifive/smp.h | 65 + raven/bsp/libwrap/libwrap.mk | 7 +- raven/bsp/libwrap/misc/write_hex.c | 19 + raven/bsp/libwrap/sys/_exit.c | 7 +- raven/bsp/libwrap/sys/close.c | 2 + raven/bsp/libwrap/sys/execve.c | 2 + raven/bsp/libwrap/sys/fstat.c | 2 + raven/bsp/libwrap/sys/getpid.c | 2 + raven/bsp/libwrap/sys/isatty.c | 2 + raven/bsp/libwrap/sys/kill.c | 2 + raven/bsp/libwrap/sys/link.c | 2 + raven/bsp/libwrap/sys/lseek.c | 2 + raven/bsp/libwrap/sys/open.c | 2 + raven/bsp/libwrap/sys/openat.c | 2 + raven/bsp/libwrap/sys/puts.c | 28 + raven/bsp/libwrap/sys/read.c | 6 +- raven/bsp/libwrap/sys/sbrk.c | 2 + raven/bsp/libwrap/sys/stat.c | 2 + raven/bsp/libwrap/sys/times.c | 2 + raven/bsp/libwrap/sys/unlink.c | 2 + raven/bsp/libwrap/sys/weak_under_alias.h | 7 + raven/bsp/libwrap/sys/write.c | 2 + raven/hello_raven | Bin 71708 -> 150920 bytes raven/hello_raven.c | 55 - raven/hello_raven.dis | 2156 ----------------- raven/src/bsp.h | 22 + raven/src/delay.c | 123 + raven/src/delay.h | 25 + raven/src/hello_raven.cpp | 148 ++ raven/src/hello_raven.h | 7 + raven/src/hifive1_io.cpp | 16 + raven/src/hifive1_io.h | 26 + raven/src/io/gpio.h | 89 + raven/src/io/pwm.h | 122 + raven/src/io/spi.h | 200 ++ raven/src/io/uart.h | 83 + raven/src/util/bit_field.h | 179 ++ raven/{ => src}/wrap_printf.c | 2 +- raven/toolchain-rv32.cmake | 33 + 99 files changed, 4254 insertions(+), 3162 deletions(-) delete mode 100644 raven/bsp/Debug/drivers/fe300prci/subdir.mk delete mode 100644 raven/bsp/Debug/drivers/plic/subdir.mk delete mode 100644 raven/bsp/Debug/env/freedom-e300-arty/subdir.mk delete mode 100644 raven/bsp/Debug/env/freedom-e300-hifive1/subdir.mk delete mode 100644 raven/bsp/Debug/env/iss/subdir.mk delete mode 100644 raven/bsp/Debug/env/subdir.mk delete mode 100644 raven/bsp/Debug/libwrap/stdlib/subdir.mk delete mode 100644 raven/bsp/Debug/libwrap/sys/subdir.mk delete mode 100644 raven/bsp/Debug/makefile delete mode 100644 raven/bsp/Debug/objects.mk delete mode 100644 raven/bsp/Debug/sources.mk create mode 100644 raven/bsp/drivers/clic/clic_driver.c create mode 100644 raven/bsp/drivers/clic/clic_driver.h create mode 100644 raven/bsp/env/coreip-e2-arty/flash.lds create mode 100644 raven/bsp/env/coreip-e2-arty/init.c create mode 100644 raven/bsp/env/coreip-e2-arty/openocd.cfg create mode 100644 raven/bsp/env/coreip-e2-arty/platform.h create mode 100644 raven/bsp/env/coreip-e2-arty/settings.mk create mode 100644 raven/bsp/env/coreip-e2-arty/tim-split.lds create mode 100644 raven/bsp/env/coreip-e2-arty/tim.lds create mode 100644 raven/bsp/env/coreplexip-arty.h create mode 100644 raven/bsp/env/coreplexip-e31-arty/dhrystone.lds create mode 100644 raven/bsp/env/coreplexip-e31-arty/flash.lds create mode 100644 raven/bsp/env/coreplexip-e31-arty/init.c create mode 100644 raven/bsp/env/coreplexip-e31-arty/openocd.cfg create mode 100644 raven/bsp/env/coreplexip-e31-arty/platform.h create mode 100644 raven/bsp/env/coreplexip-e31-arty/scratchpad.lds create mode 100644 raven/bsp/env/coreplexip-e31-arty/settings.mk create mode 100644 raven/bsp/env/coreplexip-e51-arty/dhrystone.lds create mode 100644 raven/bsp/env/coreplexip-e51-arty/flash.lds create mode 100644 raven/bsp/env/coreplexip-e51-arty/init.c create mode 100644 raven/bsp/env/coreplexip-e51-arty/openocd.cfg create mode 100644 raven/bsp/env/coreplexip-e51-arty/platform.h create mode 100644 raven/bsp/env/coreplexip-e51-arty/scratchpad.lds create mode 100644 raven/bsp/env/coreplexip-e51-arty/settings.mk rename raven/bsp/env/freedom-e300-arty/{link.lds => flash.lds} (96%) create mode 100644 raven/bsp/env/freedom-e300-arty/settings.mk rename raven/bsp/env/{iss/link.lds => freedom-e300-hifive1/dhrystone.lds} (92%) rename raven/bsp/env/freedom-e300-hifive1/{link.lds => flash.lds} (96%) create mode 100644 raven/bsp/env/freedom-e300-hifive1/settings.mk delete mode 100644 raven/bsp/env/iss/init.c delete mode 100644 raven/bsp/env/iss/openocd.cfg delete mode 100644 raven/bsp/env/iss/platform.h create mode 100644 raven/bsp/env/ventry.S create mode 100644 raven/bsp/include/sifive/devices/clic.h create mode 100644 raven/bsp/include/sifive/smp.h create mode 100644 raven/bsp/libwrap/misc/write_hex.c create mode 100644 raven/bsp/libwrap/sys/puts.c create mode 100644 raven/bsp/libwrap/sys/weak_under_alias.h delete mode 100644 raven/hello_raven.c delete mode 100644 raven/hello_raven.dis create mode 100644 raven/src/bsp.h create mode 100644 raven/src/delay.c create mode 100644 raven/src/delay.h create mode 100644 raven/src/hello_raven.cpp create mode 100644 raven/src/hello_raven.h create mode 100644 raven/src/hifive1_io.cpp create mode 100644 raven/src/hifive1_io.h create mode 100644 raven/src/io/gpio.h create mode 100644 raven/src/io/pwm.h create mode 100644 raven/src/io/spi.h create mode 100644 raven/src/io/uart.h create mode 100644 raven/src/util/bit_field.h rename raven/{ => src}/wrap_printf.c (99%) create mode 100644 raven/toolchain-rv32.cmake diff --git a/raven/Makefile b/raven/Makefile index 25c627a..6729b90 100644 --- a/raven/Makefile +++ b/raven/Makefile @@ -1,13 +1,29 @@ -TARGET = hello_raven -C_SRCS += $(wildcard *.c) -CFLAGS += -g -#-fno-builtin-printf -LDFLAGS := -Wl,--wrap=scanf -Wl,--wrap=printf +TARGET = hello_raven +C_SRCS = $(wildcard src/*.c) $(BSP_BASE)/drivers/fe300prci/fe300prci_driver.c $(BSP_BASE)/drivers/plic/plic_driver.c +CXX_SRCS = $(wildcard src/*.cpp) +HEADERS = $(wildcard src/*.h) +CFLAGS = -g -fno-builtin-printf -DUSE_PLIC -DUSE_M_TIME -DNO_INIT -I./src +CXXFLAGS = -fno-use-cxa-atexit +LDFLAGS = -Wl,--wrap=printf +LDFLAGS += -g -lstdc++ -fno-use-cxa-atexit -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=medany + -#BOARD = iss BOARD=freedom-e300-hifive1 -TOOL_DIR=/opt/shared/riscv/FreedomStudio/20180122/SiFive/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6/bin +LINK_TARGET=flash +RISCV_ARCH=rv32imac +RISCV_ABI=ilp32 + +TOOL_DIR=/home/stas/Downloads/riscv64-unknown-elf-gcc-8.3.0-2020.04.0-x86_64-linux-ubuntu14/bin +#TOOL_DIR?=/opt/riscv/FreedomStudio/20180122/SiFive/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6/bin BSP_BASE = ./bsp include $(BSP_BASE)/env/common.mk + +.PHONY: all +all: $(TARGET).dump + +$(TARGET).dump: $(TARGET) + $(TOOL_DIR)/$(TRIPLET)-objdump -d -S -C $< > $@ + + diff --git a/raven/bsp/Debug/drivers/fe300prci/subdir.mk b/raven/bsp/Debug/drivers/fe300prci/subdir.mk deleted file mode 100644 index 9a05361..0000000 --- a/raven/bsp/Debug/drivers/fe300prci/subdir.mk +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../drivers/fe300prci/fe300prci_driver.c - -OBJS += \ -./drivers/fe300prci/fe300prci_driver.o - -C_DEPS += \ -./drivers/fe300prci/fe300prci_driver.d - - -# Each subdirectory must supply rules for building sources it contributes -drivers/fe300prci/%.o: ../drivers/fe300prci/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/drivers/plic/subdir.mk b/raven/bsp/Debug/drivers/plic/subdir.mk deleted file mode 100644 index be3a955..0000000 --- a/raven/bsp/Debug/drivers/plic/subdir.mk +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../drivers/plic/plic_driver.c - -OBJS += \ -./drivers/plic/plic_driver.o - -C_DEPS += \ -./drivers/plic/plic_driver.d - - -# Each subdirectory must supply rules for building sources it contributes -drivers/plic/%.o: ../drivers/plic/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/env/freedom-e300-arty/subdir.mk b/raven/bsp/Debug/env/freedom-e300-arty/subdir.mk deleted file mode 100644 index c0bee22..0000000 --- a/raven/bsp/Debug/env/freedom-e300-arty/subdir.mk +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../env/freedom-e300-arty/init.c - -OBJS += \ -./env/freedom-e300-arty/init.o - -C_DEPS += \ -./env/freedom-e300-arty/init.d - - -# Each subdirectory must supply rules for building sources it contributes -env/freedom-e300-arty/%.o: ../env/freedom-e300-arty/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/env/freedom-e300-hifive1/subdir.mk b/raven/bsp/Debug/env/freedom-e300-hifive1/subdir.mk deleted file mode 100644 index 16eea64..0000000 --- a/raven/bsp/Debug/env/freedom-e300-hifive1/subdir.mk +++ /dev/null @@ -1,27 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../env/freedom-e300-hifive1/init.c - -O_SRCS += \ -../env/freedom-e300-hifive1/init.o - -OBJS += \ -./env/freedom-e300-hifive1/init.o - -C_DEPS += \ -./env/freedom-e300-hifive1/init.d - - -# Each subdirectory must supply rules for building sources it contributes -env/freedom-e300-hifive1/%.o: ../env/freedom-e300-hifive1/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/env/iss/subdir.mk b/raven/bsp/Debug/env/iss/subdir.mk deleted file mode 100644 index 88f2d87..0000000 --- a/raven/bsp/Debug/env/iss/subdir.mk +++ /dev/null @@ -1,27 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../env/iss/init.c - -O_SRCS += \ -../env/iss/init.o - -OBJS += \ -./env/iss/init.o - -C_DEPS += \ -./env/iss/init.d - - -# Each subdirectory must supply rules for building sources it contributes -env/iss/%.o: ../env/iss/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/env/subdir.mk b/raven/bsp/Debug/env/subdir.mk deleted file mode 100644 index b8eaa7a..0000000 --- a/raven/bsp/Debug/env/subdir.mk +++ /dev/null @@ -1,27 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -O_SRCS += \ -../env/entry.o \ -../env/start.o - -S_UPPER_SRCS += \ -../env/entry.S \ -../env/start.S - -OBJS += \ -./env/entry.o \ -./env/start.o - - -# Each subdirectory must supply rules for building sources it contributes -env/%.o: ../env/%.S - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Assembler' - riscv32-unknown-elf-as -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/libwrap/stdlib/subdir.mk b/raven/bsp/Debug/libwrap/stdlib/subdir.mk deleted file mode 100644 index 2327c6d..0000000 --- a/raven/bsp/Debug/libwrap/stdlib/subdir.mk +++ /dev/null @@ -1,27 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../libwrap/stdlib/malloc.c - -O_SRCS += \ -../libwrap/stdlib/malloc.o - -OBJS += \ -./libwrap/stdlib/malloc.o - -C_DEPS += \ -./libwrap/stdlib/malloc.d - - -# Each subdirectory must supply rules for building sources it contributes -libwrap/stdlib/%.o: ../libwrap/stdlib/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/libwrap/sys/subdir.mk b/raven/bsp/Debug/libwrap/sys/subdir.mk deleted file mode 100644 index a93df2a..0000000 --- a/raven/bsp/Debug/libwrap/sys/subdir.mk +++ /dev/null @@ -1,98 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -# Add inputs and outputs from these tool invocations to the build variables -C_SRCS += \ -../libwrap/sys/_exit.c \ -../libwrap/sys/close.c \ -../libwrap/sys/execve.c \ -../libwrap/sys/fork.c \ -../libwrap/sys/fstat.c \ -../libwrap/sys/getpid.c \ -../libwrap/sys/isatty.c \ -../libwrap/sys/kill.c \ -../libwrap/sys/link.c \ -../libwrap/sys/lseek.c \ -../libwrap/sys/open.c \ -../libwrap/sys/openat.c \ -../libwrap/sys/read.c \ -../libwrap/sys/sbrk.c \ -../libwrap/sys/stat.c \ -../libwrap/sys/times.c \ -../libwrap/sys/unlink.c \ -../libwrap/sys/wait.c \ -../libwrap/sys/write.c - -O_SRCS += \ -../libwrap/sys/_exit.o \ -../libwrap/sys/close.o \ -../libwrap/sys/execve.o \ -../libwrap/sys/fork.o \ -../libwrap/sys/fstat.o \ -../libwrap/sys/getpid.o \ -../libwrap/sys/isatty.o \ -../libwrap/sys/kill.o \ -../libwrap/sys/link.o \ -../libwrap/sys/lseek.o \ -../libwrap/sys/open.o \ -../libwrap/sys/read.o \ -../libwrap/sys/sbrk.o \ -../libwrap/sys/stat.o \ -../libwrap/sys/times.o \ -../libwrap/sys/unlink.o \ -../libwrap/sys/wait.o \ -../libwrap/sys/write.o - -OBJS += \ -./libwrap/sys/_exit.o \ -./libwrap/sys/close.o \ -./libwrap/sys/execve.o \ -./libwrap/sys/fork.o \ -./libwrap/sys/fstat.o \ -./libwrap/sys/getpid.o \ -./libwrap/sys/isatty.o \ -./libwrap/sys/kill.o \ -./libwrap/sys/link.o \ -./libwrap/sys/lseek.o \ -./libwrap/sys/open.o \ -./libwrap/sys/openat.o \ -./libwrap/sys/read.o \ -./libwrap/sys/sbrk.o \ -./libwrap/sys/stat.o \ -./libwrap/sys/times.o \ -./libwrap/sys/unlink.o \ -./libwrap/sys/wait.o \ -./libwrap/sys/write.o - -C_DEPS += \ -./libwrap/sys/_exit.d \ -./libwrap/sys/close.d \ -./libwrap/sys/execve.d \ -./libwrap/sys/fork.d \ -./libwrap/sys/fstat.d \ -./libwrap/sys/getpid.d \ -./libwrap/sys/isatty.d \ -./libwrap/sys/kill.d \ -./libwrap/sys/link.d \ -./libwrap/sys/lseek.d \ -./libwrap/sys/open.d \ -./libwrap/sys/openat.d \ -./libwrap/sys/read.d \ -./libwrap/sys/sbrk.d \ -./libwrap/sys/stat.d \ -./libwrap/sys/times.d \ -./libwrap/sys/unlink.d \ -./libwrap/sys/wait.d \ -./libwrap/sys/write.d - - -# Each subdirectory must supply rules for building sources it contributes -libwrap/sys/%.o: ../libwrap/sys/%.c - @echo 'Building file: $<' - @echo 'Invoking: Cross GCC Compiler' - riscv32-unknown-elf-gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" - @echo 'Finished building: $<' - @echo ' ' - - diff --git a/raven/bsp/Debug/makefile b/raven/bsp/Debug/makefile deleted file mode 100644 index 34f9759..0000000 --- a/raven/bsp/Debug/makefile +++ /dev/null @@ -1,66 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - --include ../makefile.init - -RM := rm -rf - -# All of the sources participating in the build are defined here --include sources.mk --include libwrap/sys/subdir.mk --include libwrap/stdlib/subdir.mk --include libwrap/misc/subdir.mk --include env/iss/subdir.mk --include env/freedom-e300-hifive1/subdir.mk --include env/freedom-e300-arty/subdir.mk --include env/subdir.mk --include drivers/plic/subdir.mk --include drivers/fe300prci/subdir.mk --include subdir.mk --include objects.mk - -ifneq ($(MAKECMDGOALS),clean) -ifneq ($(strip $(CC_DEPS)),) --include $(CC_DEPS) -endif -ifneq ($(strip $(C++_DEPS)),) --include $(C++_DEPS) -endif -ifneq ($(strip $(C_UPPER_DEPS)),) --include $(C_UPPER_DEPS) -endif -ifneq ($(strip $(CXX_DEPS)),) --include $(CXX_DEPS) -endif -ifneq ($(strip $(C_DEPS)),) --include $(C_DEPS) -endif -ifneq ($(strip $(CPP_DEPS)),) --include $(CPP_DEPS) -endif -endif - --include ../makefile.defs - -# Add inputs and outputs from these tool invocations to the build variables - -# All Target -all: bsp - -# Tool invocations -bsp: $(OBJS) $(USER_OBJS) - @echo 'Building target: $@' - @echo 'Invoking: Cross G++ Linker' - riscv32-unknown-elf-g++ -o "bsp" $(OBJS) $(USER_OBJS) $(LIBS) - @echo 'Finished building target: $@' - @echo ' ' - -# Other Targets -clean: - -$(RM) $(CC_DEPS)$(C++_DEPS)$(EXECUTABLES)$(OBJS)$(C_UPPER_DEPS)$(CXX_DEPS)$(C_DEPS)$(CPP_DEPS) bsp - -@echo ' ' - -.PHONY: all clean dependents - --include ../makefile.targets diff --git a/raven/bsp/Debug/objects.mk b/raven/bsp/Debug/objects.mk deleted file mode 100644 index 742c2da..0000000 --- a/raven/bsp/Debug/objects.mk +++ /dev/null @@ -1,8 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -USER_OBJS := - -LIBS := - diff --git a/raven/bsp/Debug/sources.mk b/raven/bsp/Debug/sources.mk deleted file mode 100644 index bfb7eff..0000000 --- a/raven/bsp/Debug/sources.mk +++ /dev/null @@ -1,35 +0,0 @@ -################################################################################ -# Automatically-generated file. Do not edit! -################################################################################ - -C_UPPER_SRCS := -CXX_SRCS := -C++_SRCS := -OBJ_SRCS := -CC_SRCS := -ASM_SRCS := -C_SRCS := -CPP_SRCS := -O_SRCS := -S_UPPER_SRCS := -CC_DEPS := -C++_DEPS := -EXECUTABLES := -OBJS := -C_UPPER_DEPS := -CXX_DEPS := -C_DEPS := -CPP_DEPS := - -# Every subdirectory with source files must be described here -SUBDIRS := \ -drivers/fe300prci \ -drivers/plic \ -env \ -env/freedom-e300-arty \ -env/freedom-e300-hifive1 \ -env/iss \ -libwrap/misc \ -libwrap/stdlib \ -libwrap/sys \ - diff --git a/raven/bsp/drivers/clic/clic_driver.c b/raven/bsp/drivers/clic/clic_driver.c new file mode 100644 index 0000000..0612e58 --- /dev/null +++ b/raven/bsp/drivers/clic/clic_driver.c @@ -0,0 +1,163 @@ +// See LICENSE for license details. + +#include "sifive/devices/clic.h" +#include "clic/clic_driver.h" +#include "platform.h" +#include "encoding.h" +#include + + +void volatile_memzero(uint8_t * base, unsigned int size) { + volatile uint8_t * ptr; + for (ptr = base; ptr < (base + size); ptr++){ + *ptr = 0; + } +} + +// Note that there are no assertions or bounds checking on these +// parameter values. +void clic_init ( + clic_instance_t * this_clic, + uintptr_t hart_addr, + interrupt_function_ptr_t* vect_table, + interrupt_function_ptr_t default_handler, + uint32_t num_irq, + uint32_t num_config_bits + ) +{ + this_clic->hart_addr= hart_addr; + this_clic->vect_table= vect_table; + this_clic->num_config_bits= num_config_bits; + + //initialize vector table + for(int i=0;i++;ivect_table[i] = default_handler; + } + + //set base vectors + write_csr(mtvt, vect_table); + + + //clear all interrupt enables and pending + volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIE), num_irq); + volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIP), num_irq); + + //clear nlbits and nvbits; all interrupts trap to level 15 + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG)=0; + +} + +void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler) { + this_clic->vect_table[source] = handler; +} + +void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source) { + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 1; +} + +void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 0; +} + +void clic_set_pending(clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 1; +} + +void clic_clear_pending(clic_instance_t * this_clic, uint32_t source){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 0; +} + +void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source) = intcfg; +} + +uint8_t clic_get_intcfg (clic_instance_t * this_clic, uint32_t source){ + return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source); +} + +void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg){ + *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG) = cfg; +} + +uint8_t clic_get_cliccfg (clic_instance_t * this_clic){ + return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG); +} + +//sets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level) { + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift level right to mask off unused bits + level = level>>((this_clic->num_config_bits)-nlbits); //plus this_clic->nmbits which is always 0 for now. + //shift level into correct bit position + level = level << (8-this_clic->num_config_bits) + (this_clic->num_config_bits - nlbits); + + //write to clicintcfg + uint8_t current_intcfg = clic_get_intcfg(this_clic, source); + clic_set_intcfg(this_clic, source, (current_intcfg | level)); + + return level; +} + +//gets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source) { + uint8_t level; + level = clic_get_intcfg(this_clic, source); + + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift level + level = level >> (8-(this_clic->num_config_bits)); + + //shift level right to mask off priority bits + level = level>>(this_clic->num_config_bits-nlbits); //this_clic->nmbits which is always 0 for now. + + return level; +} + +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority) { + //priority bits = num_config_bits - nlbits + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + uint8_t priority_bits = this_clic->num_config_bits-nlbits; + if(priority_bits = 0) { + //no bits to set + return 0; + } + //mask off unused bits + priority = priority >> (8-priority_bits); + //shift into the correct bit position + priority = priority << (8-(this_clic->num_config_bits)); + + //write to clicintcfg + uint8_t current_intcfg = clic_get_intcfg(this_clic, source); + clic_set_intcfg(this_clic, source, (current_intcfg | priority)); + return current_intcfg; +} + +//gets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source) { + uint8_t priority; + priority = clic_get_intcfg(this_clic, source); + + //extract nlbits + uint8_t nlbits = clic_get_cliccfg(this_clic); + nlbits = (nlbits >>1) & 0x7; + + //shift left to mask off level bits + priority = priority << nlbits; + + //shift priority + priority = priority >> (8-((this_clic->num_config_bits)+nlbits)); + + return priority; +} + + diff --git a/raven/bsp/drivers/clic/clic_driver.h b/raven/bsp/drivers/clic/clic_driver.h new file mode 100644 index 0000000..27c34c2 --- /dev/null +++ b/raven/bsp/drivers/clic/clic_driver.h @@ -0,0 +1,44 @@ +// See LICENSE file for licence details + +#ifndef PLIC_DRIVER_H +#define PLIC_DRIVER_H + + +__BEGIN_DECLS + +#include "platform.h" + +typedef void (*interrupt_function_ptr_t) (void); + +typedef struct __clic_instance_t +{ + uintptr_t hart_addr; + interrupt_function_ptr_t* vect_table; + uint32_t num_config_bits; + uint32_t num_sources; +} clic_instance_t; + +// Note that there are no assertions or bounds checking on these +// parameter values. +void clic_init (clic_instance_t * this_clic, uintptr_t hart_addr, interrupt_function_ptr_t* vect_table, interrupt_function_ptr_t default_handler, uint32_t num_irq,uint32_t num_config_bits); +void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler); +void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source); +void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source); +void clic_set_pending(clic_instance_t * this_clic, uint32_t source); +void clic_clear_pending(clic_instance_t * this_clic, uint32_t source); +void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg); +uint8_t clic_get_intcfg (clic_instance_t * this_clic, uint32_t source); +void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg); +uint8_t clic_get_cliccfg (clic_instance_t * this_clic); +//sets an interrupt level based encoding of nmbits, nlbits +uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level); +//get an interrupt level based encoding of nmbits, nlbits +uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source); +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority); +//sets an interrupt priority based encoding of nmbits, nlbits +uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source); + +__END_DECLS + +#endif diff --git a/raven/bsp/drivers/fe300prci/fe300prci_driver.c b/raven/bsp/drivers/fe300prci/fe300prci_driver.c index 2d9c52f..8eeaafc 100644 --- a/raven/bsp/drivers/fe300prci/fe300prci_driver.c +++ b/raven/bsp/drivers/fe300prci/fe300prci_driver.c @@ -2,7 +2,7 @@ #include "platform.h" -#ifdef PRCI_BASE_ADDR +#ifdef PRCI_CTRL_ADDR #include "fe300prci/fe300prci_driver.h" #include diff --git a/raven/bsp/drivers/plic/plic_driver.c b/raven/bsp/drivers/plic/plic_driver.c index b27d7a5..4f41bda 100644 --- a/raven/bsp/drivers/plic/plic_driver.c +++ b/raven/bsp/drivers/plic/plic_driver.c @@ -22,19 +22,20 @@ void PLIC_init ( plic_instance_t * this_plic, uintptr_t base_addr, uint32_t num_sources, - uint32_t num_priorities + uint32_t num_priorities, + uint32_t target_hartid ) { this_plic->base_addr = base_addr; this_plic->num_sources = num_sources; this_plic->num_priorities = num_priorities; + this_plic->target_hartid = target_hartid; // Disable all interrupts (don't assume that these registers are reset). - unsigned long hart_id = read_csr(mhartid); volatile_memzero((uint8_t*) (this_plic->base_addr + PLIC_ENABLE_OFFSET + - (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)), + (this_plic->target_hartid << PLIC_ENABLE_SHIFT_PER_TARGET)), (num_sources + 8) / 8); // Set all priorities to 0 (equal priority -- don't assume that these are reset). @@ -46,7 +47,7 @@ void PLIC_init ( volatile plic_threshold* threshold = (plic_threshold*) (this_plic->base_addr + PLIC_THRESHOLD_OFFSET + - (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); + (this_plic->target_hartid << PLIC_THRESHOLD_SHIFT_PER_TARGET)); *threshold = 0; @@ -55,10 +56,9 @@ void PLIC_init ( void PLIC_set_threshold (plic_instance_t * this_plic, plic_threshold threshold){ - unsigned long hart_id = read_csr(mhartid); volatile plic_threshold* threshold_ptr = (plic_threshold*) (this_plic->base_addr + PLIC_THRESHOLD_OFFSET + - (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); + (this_plic->target_hartid << PLIC_THRESHOLD_SHIFT_PER_TARGET)); *threshold_ptr = threshold; @@ -67,10 +67,9 @@ void PLIC_set_threshold (plic_instance_t * this_plic, void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){ - unsigned long hart_id = read_csr(mhartid); volatile uint8_t * current_ptr = (volatile uint8_t *)(this_plic->base_addr + PLIC_ENABLE_OFFSET + - (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + + (this_plic->target_hartid << PLIC_ENABLE_SHIFT_PER_TARGET) + (source >> 3)); uint8_t current = *current_ptr; current = current | ( 1 << (source & 0x7)); @@ -80,10 +79,9 @@ void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){ void PLIC_disable_interrupt (plic_instance_t * this_plic, plic_source source){ - unsigned long hart_id = read_csr(mhartid); volatile uint8_t * current_ptr = (volatile uint8_t *) (this_plic->base_addr + PLIC_ENABLE_OFFSET + - (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + + (this_plic->target_hartid << PLIC_ENABLE_SHIFT_PER_TARGET) + (source >> 3)); uint8_t current = *current_ptr; current = current & ~(( 1 << (source & 0x7))); @@ -104,12 +102,10 @@ void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_pr plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){ - unsigned long hart_id = read_csr(mhartid); - volatile plic_source * claim_addr = (volatile plic_source * ) (this_plic->base_addr + PLIC_CLAIM_OFFSET + - (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); + (this_plic->target_hartid << PLIC_CLAIM_SHIFT_PER_TARGET)); return *claim_addr; @@ -117,10 +113,9 @@ plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){ void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){ - unsigned long hart_id = read_csr(mhartid); volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr + PLIC_CLAIM_OFFSET + - (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); + (this_plic->target_hartid << PLIC_CLAIM_SHIFT_PER_TARGET)); *claim_addr = source; } diff --git a/raven/bsp/drivers/plic/plic_driver.h b/raven/bsp/drivers/plic/plic_driver.h index e7d609b..f7201ee 100644 --- a/raven/bsp/drivers/plic/plic_driver.h +++ b/raven/bsp/drivers/plic/plic_driver.h @@ -14,7 +14,7 @@ typedef struct __plic_instance_t uint32_t num_sources; uint32_t num_priorities; - + uint32_t target_hartid; } plic_instance_t; typedef uint32_t plic_source; @@ -25,7 +25,8 @@ void PLIC_init ( plic_instance_t * this_plic, uintptr_t base_addr, uint32_t num_sources, - uint32_t num_priorities + uint32_t num_priorities, + uint32_t target_hartid ); void PLIC_set_threshold (plic_instance_t * this_plic, diff --git a/raven/bsp/env/common.mk b/raven/bsp/env/common.mk index 0995009..0ca2c70 100644 --- a/raven/bsp/env/common.mk +++ b/raven/bsp/env/common.mk @@ -8,18 +8,14 @@ all: $(TARGET) include $(BSP_BASE)/libwrap/libwrap.mk -BOARD ?= freedom-e300-hifive1 ENV_DIR = $(BSP_BASE)/env PLATFORM_DIR = $(ENV_DIR)/$(BOARD) -#TARGET_FLAVOR := -march=rv32imac -mabi=ilp32 -mcmodel=medany -msmall-data-limit=8 -x assembler-with-cpp -TARGET_FLAVOR := -march=rv32i -mabi=ilp32 - ASM_SRCS += $(ENV_DIR)/start.S ASM_SRCS += $(ENV_DIR)/entry.S C_SRCS += $(PLATFORM_DIR)/init.c -LINKER_SCRIPT := $(PLATFORM_DIR)/link.lds +LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds INCLUDES += -I$(BSP_BASE)/include INCLUDES += -I$(BSP_BASE)/drivers/ @@ -28,35 +24,43 @@ INCLUDES += -I$(PLATFORM_DIR) TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin -CC := $(TOOL_DIR)/riscv64-unknown-elf-gcc ${TARGET_FLAVOR} -AR := $(TOOL_DIR)/riscv64-unknown-elf-ar -OBJDUMP := $(TOOL_DIR)/riscv64-unknown-elf-objdump - LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles -LDFLAGS += -L$(ENV_DIR) +LDFLAGS += -L$(ENV_DIR) --specs=nano.specs ASM_OBJS := $(ASM_SRCS:.S=.o) -C_OBJS := $(C_SRCS:.c=.o) +C_OBJS := $(C_SRCS:.c=.o) +CXX_OBJS := $(CXX_SRCS:.cpp=.o) -LINK_OBJS += $(ASM_OBJS) $(C_OBJS) +LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS) LINK_DEPS += $(LINKER_SCRIPT) CLEAN_OBJS += $(TARGET) $(LINK_OBJS) -CFLAGS += -g +CFLAGS += -march=$(RISCV_ARCH) +CFLAGS += -mabi=$(RISCV_ABI) +CFLAGS += -mcmodel=medany + +TRIPLET?=riscv64-unknown-elf +CXX=$(TOOL_DIR)/$(TRIPLET)-c++ +CC=$(TOOL_DIR)/$(TRIPLET)-gcc +LD=$(TOOL_DIR)/$(TRIPLET)-gcc +AR=$(TOOL_DIR)/$(TRIPLET)-ar + $(TARGET): $(LINK_OBJS) $(LINK_DEPS) - $(CC) $(CFLAGS) $(INCLUDES) $(LINK_OBJS) -o $@ $(LDFLAGS) - $(OBJDUMP) -d $(TARGET) > $(TARGET).dis - + $(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@ + $(ASM_OBJS): %.o: %.S $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< $(C_OBJS): %.o: %.c $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< +$(CXX_OBJS): %.o: %.cpp $(HEADERS) + $(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + .PHONY: clean clean: - rm -f $(CLEAN_OBJS) + rm -f $(CLEAN_OBJS) $(LIBWRAP) endif # _SIFIVE_MK_COMMON diff --git a/raven/bsp/env/coreip-e2-arty/flash.lds b/raven/bsp/env/coreip-e2-arty/flash.lds new file mode 100644 index 0000000..2d5eb01 --- /dev/null +++ b/raven/bsp/env/coreip-e2-arty/flash.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x40400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 64K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreip-e2-arty/init.c b/raven/bsp/env/coreip-e2-arty/init.c new file mode 100644 index 0000000..3a4c77c --- /dev/null +++ b/raven/bsp/env/coreip-e2-arty/init.c @@ -0,0 +1,98 @@ +//See LICENSE for license details. +#include +#include +#include + +#include "platform.h" +#include "encoding.h" + +#define CPU_FREQ 32000000 +#define XSTR(x) #x +#define STR(x) XSTR(x) + +extern int main(int argc, char** argv); + +unsigned long get_cpu_freq() +{ + return CPU_FREQ; +} + +unsigned long get_timer_freq() +{ + return get_cpu_freq(); +} + +uint64_t get_timer_value() +{ +#if __riscv_xlen == 32 + while (1) { + uint32_t hi = read_csr(mcycleh); + uint32_t lo = read_csr(mcycle); + if (hi == read_csr(mcycleh)) + return ((uint64_t)hi << 32) | lo; + } +#else + return read_csr(mcycle); +#endif +} + +static void uart_init(size_t baud_rate) +{ + UART0_REG(UART_REG_DIV) = (get_cpu_freq() ) / baud_rate - 1; + UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; +} + + +typedef void (*interrupt_function_ptr_t) (void); +interrupt_function_ptr_t localISR[CLIC_NUM_INTERRUPTS] __attribute__((aligned(64))); + + +void trap_entry(void) __attribute__((interrupt, aligned(64))); +void trap_entry(void) +{ + unsigned long mcause = read_csr(mcause); + unsigned long mepc = read_csr(mepc); + if (mcause & MCAUSE_INT) { + localISR[mcause & MCAUSE_CAUSE] (); + } else { + while(1); + } +} + +#ifdef CLIC_DIRECT +#else +void default_handler(void)__attribute__((interrupt));; +#endif +void default_handler(void) +{ + puts("default handler\n"); + while(1); +} + +void _init() +{ +#ifndef NO_INIT + uart_init(115200); + + puts("core freq at " STR(CPU_FREQ) " Hz\n"); + +//initialize vector table + int i=0; + while(iflash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreip-e2-arty/tim.lds b/raven/bsp/env/coreip-e2-arty/tim.lds new file mode 100644 index 0000000..7dfb36b --- /dev/null +++ b/raven/bsp/env/coreip-e2-arty/tim.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 64K +} + +PHDRS +{ + ram PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >ram AT>ram :ram + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >ram AT>ram :ram + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >ram AT>ram :ram + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >ram AT>ram :ram + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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)) + } >ram AT>ram :ram + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >ram AT>ram :ram + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >ram AT>ram :ram + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>ram :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>ram :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack : + { + . = ALIGN(8); + . += __stack_size; + PROVIDE( _sp = . ); + PROVIDE( _heap_end = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-arty.h b/raven/bsp/env/coreplexip-arty.h new file mode 100644 index 0000000..eedcaa5 --- /dev/null +++ b/raven/bsp/env/coreplexip-arty.h @@ -0,0 +1,102 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_COREPLEXIP_ARTY_H +#define _SIFIVE_COREPLEXIP_ARTY_H + +#include + +/**************************************************************************** + * GPIO Connections + *****************************************************************************/ + +// These are the GPIO bit offsets for the directly driven +// RGB LEDs on the Freedom Exx Coreplex IP Evaluation Arty FPGA Dev Kit. +// Additional RGB LEDs are driven by the 3 PWM outputs. + +#define RED_LED_OFFSET 0 +#define GREEN_LED_OFFSET 1 +#define BLUE_LED_OFFSET 2 + +// Switch 3 is used as a GPIO input. (Switch 0 is used to set +// the reset vector, the other switches are unused). + +#define SW_3_OFFSET 3 + +// These are the buttons which are mapped as inputs. + +#define HAS_BOARD_BUTTONS + +#define BUTTON_0_OFFSET 4 +#define BUTTON_1_OFFSET 5 +#define BUTTON_2_OFFSET 6 +#define BUTTON_3_OFFSET 7 + +// These are the bit offsets for the different GPIO pins +// mapped onto the PMOD A header. + +#define JA_0_OFFSET 8 +#define JA_1_OFFSET 9 +#define JA_2_OFFSET 10 +#define JA_3_OFFSET 11 +#define JA_4_OFFSET 12 +#define JA_5_OFFSET 13 +#define JA_6_OFFSET 14 +#define JA_7_OFFSET 15 + +// The below gives a mapping between global interrupt +// sources and their number. Note that on the coreplex +// deliverable, the io_global_interrupts go directly into +// the PLIC. The evaluation image on the FPGA mimics a +// system with peripheral devices which are driving the +// global interrupt lines. +// So, on this image, in order to get an interrupt from +// e.g. pressing BUTTON_0: +// 1) Steps which are external to the delivery coreplex: +// a) The corresponding GPIO pin must be configured as in input +// b) The "interrupt on fall" bit must be set for the GPIO pin +// 2) Steps which would also need to be performed for the delivery coreplex: +// a) The corresponding global interrupt, priority, and threshold must be configured in the PLIC. +// b) The external interrupt bit must be enabled in MSTATUS +// c) Interrupts must be enabled globally in the core. + +// Any of the above GPIO pins can be used as global interrupt +// sources by adding their offset to the INT_GPIO_BASE. +// For example, the buttons are shown here: + +#define INT_DEVICE_BUTTON_0 (GPIO_INT_BASE + BUTTON_0_OFFSET) +#define INT_DEVICE_BUTTON_1 (GPIO_INT_BASE + BUTTON_1_OFFSET) +#define INT_DEVICE_BUTTON_2 (GPIO_INT_BASE + BUTTON_2_OFFSET) +#define INT_DEVICE_BUTTON_3 (GPIO_INT_BASE + BUTTON_3_OFFSET) + +// In addition, the Switches are mapped directly to +// the PLIC (without going through the GPIO Peripheral). + +#define INT_EXT_DEVICE_SW_0 (EXTERNAL_INT_BASE + 0) +#define INT_EXT_DEVICE_SW_1 (EXTERNAL_INT_BASE + 1) +#define INT_EXT_DEVICE_SW_2 (EXTERNAL_INT_BASE + 2) +#define INT_EXT_DEVICE_SW_3 (EXTERNAL_INT_BASE + 3) + +// This gives the mapping from inputs to LOCAL interrupts. + +#define LOCAL_INT_SW_0 0 +#define LOCAL_INT_SW_1 1 +#define LOCAL_INT_SW_2 2 +#define LOCAL_INT_SW_3 3 +#define LOCAL_INT_BTN_0 4 +#define LOCAL_INT_BTN_1 5 +#define LOCAL_INT_BTN_2 6 +#define LOCAL_INT_BTN_3 7 +#define LOCAL_INT_JA_0 8 +#define LOCAL_INT_JA_1 9 +#define LOCAL_INT_JA_2 10 +#define LOCAL_INT_JA_3 11 +#define LOCAL_INT_JA_4 12 +#define LOCAL_INT_JA_5 13 +#define LOCAL_INT_JA_6 14 +#define LOCAL_INT_JA_7 15 + +#define RTC_FREQ 32768 + +void write_hex(int fd, unsigned long int hex); + +#endif /* _SIFIVE_COREPLEXIP_ARTY_H */ diff --git a/raven/bsp/env/coreplexip-e31-arty/dhrystone.lds b/raven/bsp/env/coreplexip-e31-arty/dhrystone.lds new file mode 100644 index 0000000..8f6527b --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/dhrystone.lds @@ -0,0 +1,157 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x40400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e31-arty/flash.lds b/raven/bsp/env/coreplexip-e31-arty/flash.lds new file mode 100644 index 0000000..590c5b6 --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/flash.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x40400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e31-arty/init.c b/raven/bsp/env/coreplexip-e31-arty/init.c new file mode 100644 index 0000000..1f8b679 --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/init.c @@ -0,0 +1,122 @@ +//See LICENSE for license details. +#include +#include +#include + +#include "platform.h" +#include "encoding.h" + +#define CPU_FREQ 65000000 +#define XSTR(x) #x +#define STR(x) XSTR(x) + +#ifndef VECT_IRQ + #define TRAP_ENTRY trap_entry +#else + #define TRAP_ENTRY vtrap_entry +#endif + +extern int main(int argc, char** argv); +extern void TRAP_ENTRY(); + +unsigned long get_cpu_freq() +{ + return CPU_FREQ; +} + +unsigned long get_timer_freq() +{ + return get_cpu_freq(); +} + +uint64_t get_timer_value() +{ +#if __riscv_xlen == 32 + while (1) { + uint32_t hi = read_csr(mcycleh); + uint32_t lo = read_csr(mcycle); + if (hi == read_csr(mcycleh)) + return ((uint64_t)hi << 32) | lo; + } +#else + return read_csr(mcycle); +#endif +} + +static void uart_init(size_t baud_rate) +{ + UART0_REG(UART_REG_DIV) = (get_cpu_freq() / 2) / baud_rate - 1; + UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; +} + + +#ifdef USE_PLIC +extern void handle_m_ext_interrupt(); +#endif + +#ifdef USE_M_TIME +extern void handle_m_time_interrupt(); +#endif + +#ifdef USE_LOCAL_ISR +typedef void (*my_interrupt_function_ptr_t) (void); +extern my_interrupt_function_ptr_t localISR[]; +#endif + +#ifndef VECT_IRQ +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) __attribute__((noinline)); +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) +{ + if (0){ +#ifdef USE_PLIC + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) { + handle_m_ext_interrupt(); +#endif +#ifdef USE_M_TIME + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){ + handle_m_time_interrupt(); +#endif +#ifdef USE_LOCAL_ISR + } else if (mcause & MCAUSE_INT) { + localISR[mcause & MCAUSE_CAUSE] (); +#endif + } + else { + write(1, "Unhandled Trap:\n", 16); + _exit(1 + mcause); + } + return epc; +} +#endif + +#ifdef USE_CLIC +void trap_entry(void) __attribute__((interrupt("SiFive-CLIC-preemptible"), aligned(64))); +void trap_entry(void) +{ + unsigned long mcause = read_csr(mcause); + unsigned long mepc = read_csr(mepc); + handle_trap(mcause, mepc); +} +#endif + +void _init() +{ + #ifndef NO_INIT + uart_init(115200); + + puts("core freq at " STR(CPU_FREQ) " Hz\n"); + +#ifdef USE_CLIC + write_csr(mtvec, ((unsigned long)&trap_entry | MTVEC_CLIC)); +#else + write_csr(mtvec, ((unsigned long)&TRAP_ENTRY | MTVEC_VECTORED)); +#endif + + #endif +} + +void _fini() +{ +} diff --git a/raven/bsp/env/coreplexip-e31-arty/openocd.cfg b/raven/bsp/env/coreplexip-e31-arty/openocd.cfg new file mode 100644 index 0000000..0481a72 --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/openocd.cfg @@ -0,0 +1,31 @@ +# JTAG adapter setup +adapter_khz 10000 + +interface ftdi +ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" +ftdi_vid_pid 0x15ba 0x002a + +ftdi_layout_init 0x0808 0x0a1b +ftdi_layout_signal nSRST -oe 0x0200 +#ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 +ftdi_layout_signal LED -data 0x0800 + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 + +# Un-comment these two flash lines if you have a SPI flash and want to write +# it. +flash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000 +init +if {[ info exists pulse_srst]} { + ftdi_set_signal nSRST 0 + ftdi_set_signal nSRST z +} +halt +#flash protect 0 64 last off +echo "Ready for Remote Connections" diff --git a/raven/bsp/env/coreplexip-e31-arty/platform.h b/raven/bsp/env/coreplexip-e31-arty/platform.h new file mode 100644 index 0000000..6fa79ea --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/platform.h @@ -0,0 +1,100 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_PLATFORM_H +#define _SIFIVE_PLATFORM_H + +// Some things missing from the official encoding.h + +#if __riscv_xlen == 32 +#define MCAUSE_INT 0x80000000UL +#define MCAUSE_CAUSE 0x000003FFUL +#else +#define MCAUSE_INT 0x8000000000000000UL +#define MCAUSE_CAUSE 0x00000000000003FFUL +#endif + +#ifdef VECT_IRQ + #define MTVEC_VECTORED 0x01 +#else + #define MTVEC_VECTORED 0x00 +#endif +#define MTVEC_CLIC 0x02 +#define IRQ_M_LOCAL 16 +#define MIP_MLIP(x) (1 << (IRQ_M_LOCAL + x)) + +#include "sifive/const.h" +#include "sifive/devices/clint.h" +#include "sifive/devices/gpio.h" +#include "sifive/devices/plic.h" +#include "sifive/devices/pwm.h" +#include "sifive/devices/spi.h" +#include "sifive/devices/uart.h" + +/**************************************************************************** + * Platform definitions + *****************************************************************************/ + +// Memory map +#define CLINT_CTRL_ADDR _AC(0x02000000,UL) +#define GPIO_CTRL_ADDR _AC(0x20002000,UL) +#define PLIC_CTRL_ADDR _AC(0x0C000000,UL) +#define PWM0_CTRL_ADDR _AC(0x20005000,UL) +#define RAM_MEM_ADDR _AC(0x80000000,UL) +#define RAM_MEM_SIZE _AC(0x10000,UL) +#define SPI0_CTRL_ADDR _AC(0x20004000,UL) +#define SPI0_MEM_ADDR _AC(0x40000000,UL) +#define SPI0_MEM_SIZE _AC(0x20000000,UL) +#define TESTBENCH_MEM_ADDR _AC(0x20000000,UL) +#define TESTBENCH_MEM_SIZE _AC(0x10000000,UL) +#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL) +#define UART0_CTRL_ADDR _AC(0x20000000,UL) + +// IOF masks + +// Interrupt numbers +#define RESERVED_INT_BASE 0 +#define UART0_INT_BASE 1 +#define EXTERNAL_INT_BASE 2 +#define SPI0_INT_BASE 6 +#define GPIO_INT_BASE 7 +#define PWM0_INT_BASE 23 + +// Helper functions +#define _REG64(p, i) (*(volatile uint64_t *)((p) + (i))) +#define _REG32(p, i) (*(volatile uint32_t *)((p) + (i))) +#define _REG16(p, i) (*(volatile uint16_t *)((p) + (i))) +// Bulk set bits in `reg` to either 0 or 1. +// E.g. SET_BITS(MY_REG, 0x00000007, 0) would generate MY_REG &= ~0x7 +// E.g. SET_BITS(MY_REG, 0x00000007, 1) would generate MY_REG |= 0x7 +#define SET_BITS(reg, mask, value) if ((value) == 0) { (reg) &= ~(mask); } else { (reg) |= (mask); } +#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) +#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) +#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset) +#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset) +#define TRAPVEC_TABLE_REG(offset) _REG32(TRAPVEC_TABLE_CTRL_ADDR, offset) +#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset) +#define CLINT_REG64(offset) _REG64(CLINT_CTRL_ADDR, offset) +#define GPIO_REG64(offset) _REG64(GPIO_CTRL_ADDR, offset) +#define PLIC_REG64(offset) _REG64(PLIC_CTRL_ADDR, offset) +#define PWM0_REG64(offset) _REG64(PWM0_CTRL_ADDR, offset) +#define SPI0_REG64(offset) _REG64(SPI0_CTRL_ADDR, offset) +#define TRAPVEC_TABLE_REG64(offset) _REG64(TRAPVEC_TABLE_CTRL_ADDR, offset) +#define UART0_REG64(offset) _REG64(UART0_CTRL_ADDR, offset) + +// Misc + +#define NUM_GPIO 16 + +#define PLIC_NUM_INTERRUPTS 28 +#define PLIC_NUM_PRIORITIES 7 + +#define HAS_BOARD_BUTTONS + +#include "coreplexip-arty.h" + +unsigned long get_cpu_freq(void); +unsigned long get_timer_freq(void); +uint64_t get_timer_value(void); + +#endif /* _SIFIVE_PLATFORM_H */ diff --git a/raven/bsp/env/coreplexip-e31-arty/scratchpad.lds b/raven/bsp/env/coreplexip-e31-arty/scratchpad.lds new file mode 100644 index 0000000..7887c13 --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/scratchpad.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + ram PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >ram AT>ram :ram + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >ram AT>ram :ram + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >ram AT>ram :ram + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >ram AT>ram :ram + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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)) + } >ram AT>ram :ram + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >ram AT>ram :ram + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >ram AT>ram :ram + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>ram :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>ram :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack : + { + . = ALIGN(8); + . += __stack_size; + PROVIDE( _sp = . ); + PROVIDE( _heap_end = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e31-arty/settings.mk b/raven/bsp/env/coreplexip-e31-arty/settings.mk new file mode 100644 index 0000000..230fccc --- /dev/null +++ b/raven/bsp/env/coreplexip-e31-arty/settings.mk @@ -0,0 +1,3 @@ +# Describes the CPU on this board to the rest of the SDK. +RISCV_ARCH := rv32imac +RISCV_ABI := ilp32 diff --git a/raven/bsp/env/coreplexip-e51-arty/dhrystone.lds b/raven/bsp/env/coreplexip-e51-arty/dhrystone.lds new file mode 100644 index 0000000..8f6527b --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/dhrystone.lds @@ -0,0 +1,157 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x40400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e51-arty/flash.lds b/raven/bsp/env/coreplexip-e51-arty/flash.lds new file mode 100644 index 0000000..590c5b6 --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/flash.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x40400000, LENGTH = 512M + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e51-arty/init.c b/raven/bsp/env/coreplexip-e51-arty/init.c new file mode 100644 index 0000000..1f8b679 --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/init.c @@ -0,0 +1,122 @@ +//See LICENSE for license details. +#include +#include +#include + +#include "platform.h" +#include "encoding.h" + +#define CPU_FREQ 65000000 +#define XSTR(x) #x +#define STR(x) XSTR(x) + +#ifndef VECT_IRQ + #define TRAP_ENTRY trap_entry +#else + #define TRAP_ENTRY vtrap_entry +#endif + +extern int main(int argc, char** argv); +extern void TRAP_ENTRY(); + +unsigned long get_cpu_freq() +{ + return CPU_FREQ; +} + +unsigned long get_timer_freq() +{ + return get_cpu_freq(); +} + +uint64_t get_timer_value() +{ +#if __riscv_xlen == 32 + while (1) { + uint32_t hi = read_csr(mcycleh); + uint32_t lo = read_csr(mcycle); + if (hi == read_csr(mcycleh)) + return ((uint64_t)hi << 32) | lo; + } +#else + return read_csr(mcycle); +#endif +} + +static void uart_init(size_t baud_rate) +{ + UART0_REG(UART_REG_DIV) = (get_cpu_freq() / 2) / baud_rate - 1; + UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; +} + + +#ifdef USE_PLIC +extern void handle_m_ext_interrupt(); +#endif + +#ifdef USE_M_TIME +extern void handle_m_time_interrupt(); +#endif + +#ifdef USE_LOCAL_ISR +typedef void (*my_interrupt_function_ptr_t) (void); +extern my_interrupt_function_ptr_t localISR[]; +#endif + +#ifndef VECT_IRQ +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) __attribute__((noinline)); +uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) +{ + if (0){ +#ifdef USE_PLIC + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) { + handle_m_ext_interrupt(); +#endif +#ifdef USE_M_TIME + // External Machine-Level interrupt from PLIC + } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){ + handle_m_time_interrupt(); +#endif +#ifdef USE_LOCAL_ISR + } else if (mcause & MCAUSE_INT) { + localISR[mcause & MCAUSE_CAUSE] (); +#endif + } + else { + write(1, "Unhandled Trap:\n", 16); + _exit(1 + mcause); + } + return epc; +} +#endif + +#ifdef USE_CLIC +void trap_entry(void) __attribute__((interrupt("SiFive-CLIC-preemptible"), aligned(64))); +void trap_entry(void) +{ + unsigned long mcause = read_csr(mcause); + unsigned long mepc = read_csr(mepc); + handle_trap(mcause, mepc); +} +#endif + +void _init() +{ + #ifndef NO_INIT + uart_init(115200); + + puts("core freq at " STR(CPU_FREQ) " Hz\n"); + +#ifdef USE_CLIC + write_csr(mtvec, ((unsigned long)&trap_entry | MTVEC_CLIC)); +#else + write_csr(mtvec, ((unsigned long)&TRAP_ENTRY | MTVEC_VECTORED)); +#endif + + #endif +} + +void _fini() +{ +} diff --git a/raven/bsp/env/coreplexip-e51-arty/openocd.cfg b/raven/bsp/env/coreplexip-e51-arty/openocd.cfg new file mode 100644 index 0000000..0481a72 --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/openocd.cfg @@ -0,0 +1,31 @@ +# JTAG adapter setup +adapter_khz 10000 + +interface ftdi +ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" +ftdi_vid_pid 0x15ba 0x002a + +ftdi_layout_init 0x0808 0x0a1b +ftdi_layout_signal nSRST -oe 0x0200 +#ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 +ftdi_layout_signal LED -data 0x0800 + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 + +# Un-comment these two flash lines if you have a SPI flash and want to write +# it. +flash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000 +init +if {[ info exists pulse_srst]} { + ftdi_set_signal nSRST 0 + ftdi_set_signal nSRST z +} +halt +#flash protect 0 64 last off +echo "Ready for Remote Connections" diff --git a/raven/bsp/env/coreplexip-e51-arty/platform.h b/raven/bsp/env/coreplexip-e51-arty/platform.h new file mode 100644 index 0000000..6fa79ea --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/platform.h @@ -0,0 +1,100 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_PLATFORM_H +#define _SIFIVE_PLATFORM_H + +// Some things missing from the official encoding.h + +#if __riscv_xlen == 32 +#define MCAUSE_INT 0x80000000UL +#define MCAUSE_CAUSE 0x000003FFUL +#else +#define MCAUSE_INT 0x8000000000000000UL +#define MCAUSE_CAUSE 0x00000000000003FFUL +#endif + +#ifdef VECT_IRQ + #define MTVEC_VECTORED 0x01 +#else + #define MTVEC_VECTORED 0x00 +#endif +#define MTVEC_CLIC 0x02 +#define IRQ_M_LOCAL 16 +#define MIP_MLIP(x) (1 << (IRQ_M_LOCAL + x)) + +#include "sifive/const.h" +#include "sifive/devices/clint.h" +#include "sifive/devices/gpio.h" +#include "sifive/devices/plic.h" +#include "sifive/devices/pwm.h" +#include "sifive/devices/spi.h" +#include "sifive/devices/uart.h" + +/**************************************************************************** + * Platform definitions + *****************************************************************************/ + +// Memory map +#define CLINT_CTRL_ADDR _AC(0x02000000,UL) +#define GPIO_CTRL_ADDR _AC(0x20002000,UL) +#define PLIC_CTRL_ADDR _AC(0x0C000000,UL) +#define PWM0_CTRL_ADDR _AC(0x20005000,UL) +#define RAM_MEM_ADDR _AC(0x80000000,UL) +#define RAM_MEM_SIZE _AC(0x10000,UL) +#define SPI0_CTRL_ADDR _AC(0x20004000,UL) +#define SPI0_MEM_ADDR _AC(0x40000000,UL) +#define SPI0_MEM_SIZE _AC(0x20000000,UL) +#define TESTBENCH_MEM_ADDR _AC(0x20000000,UL) +#define TESTBENCH_MEM_SIZE _AC(0x10000000,UL) +#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL) +#define UART0_CTRL_ADDR _AC(0x20000000,UL) + +// IOF masks + +// Interrupt numbers +#define RESERVED_INT_BASE 0 +#define UART0_INT_BASE 1 +#define EXTERNAL_INT_BASE 2 +#define SPI0_INT_BASE 6 +#define GPIO_INT_BASE 7 +#define PWM0_INT_BASE 23 + +// Helper functions +#define _REG64(p, i) (*(volatile uint64_t *)((p) + (i))) +#define _REG32(p, i) (*(volatile uint32_t *)((p) + (i))) +#define _REG16(p, i) (*(volatile uint16_t *)((p) + (i))) +// Bulk set bits in `reg` to either 0 or 1. +// E.g. SET_BITS(MY_REG, 0x00000007, 0) would generate MY_REG &= ~0x7 +// E.g. SET_BITS(MY_REG, 0x00000007, 1) would generate MY_REG |= 0x7 +#define SET_BITS(reg, mask, value) if ((value) == 0) { (reg) &= ~(mask); } else { (reg) |= (mask); } +#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) +#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) +#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset) +#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset) +#define TRAPVEC_TABLE_REG(offset) _REG32(TRAPVEC_TABLE_CTRL_ADDR, offset) +#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset) +#define CLINT_REG64(offset) _REG64(CLINT_CTRL_ADDR, offset) +#define GPIO_REG64(offset) _REG64(GPIO_CTRL_ADDR, offset) +#define PLIC_REG64(offset) _REG64(PLIC_CTRL_ADDR, offset) +#define PWM0_REG64(offset) _REG64(PWM0_CTRL_ADDR, offset) +#define SPI0_REG64(offset) _REG64(SPI0_CTRL_ADDR, offset) +#define TRAPVEC_TABLE_REG64(offset) _REG64(TRAPVEC_TABLE_CTRL_ADDR, offset) +#define UART0_REG64(offset) _REG64(UART0_CTRL_ADDR, offset) + +// Misc + +#define NUM_GPIO 16 + +#define PLIC_NUM_INTERRUPTS 28 +#define PLIC_NUM_PRIORITIES 7 + +#define HAS_BOARD_BUTTONS + +#include "coreplexip-arty.h" + +unsigned long get_cpu_freq(void); +unsigned long get_timer_freq(void); +uint64_t get_timer_value(void); + +#endif /* _SIFIVE_PLATFORM_H */ diff --git a/raven/bsp/env/coreplexip-e51-arty/scratchpad.lds b/raven/bsp/env/coreplexip-e51-arty/scratchpad.lds new file mode 100644 index 0000000..7887c13 --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/scratchpad.lds @@ -0,0 +1,161 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K +} + +PHDRS +{ + ram PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >ram AT>ram :ram + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >ram AT>ram :ram + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >ram AT>ram :ram + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >ram AT>ram :ram + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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 = .); + } >ram AT>ram :ram + + .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)) + } >ram AT>ram :ram + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >ram AT>ram :ram + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >ram AT>ram :ram + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>ram :ram_init + + .data : + { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>ram :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + + .stack : + { + . = ALIGN(8); + . += __stack_size; + PROVIDE( _sp = . ); + PROVIDE( _heap_end = . ); + } >ram AT>ram :ram +} diff --git a/raven/bsp/env/coreplexip-e51-arty/settings.mk b/raven/bsp/env/coreplexip-e51-arty/settings.mk new file mode 100644 index 0000000..96aea84 --- /dev/null +++ b/raven/bsp/env/coreplexip-e51-arty/settings.mk @@ -0,0 +1,3 @@ +# Describes the CPU on this board to the rest of the SDK. +RISCV_ARCH := rv64imac +RISCV_ABI := lp64 diff --git a/raven/bsp/env/entry.S b/raven/bsp/env/entry.S index 1f5de24..261b2a4 100644 --- a/raven/bsp/env/entry.S +++ b/raven/bsp/env/entry.S @@ -8,6 +8,7 @@ .section .text.entry .align 2 + .weak trap_entry .global trap_entry trap_entry: addi sp, sp, -32*REGBYTES diff --git a/raven/bsp/env/freedom-e300-arty/link.lds b/raven/bsp/env/freedom-e300-arty/flash.lds similarity index 96% rename from raven/bsp/env/freedom-e300-arty/link.lds rename to raven/bsp/env/freedom-e300-arty/flash.lds index 90e5c8f..6b37141 100644 --- a/raven/bsp/env/freedom-e300-arty/link.lds +++ b/raven/bsp/env/freedom-e300-arty/flash.lds @@ -120,11 +120,11 @@ SECTIONS { *(.data .data.*) *(.gnu.linkonce.d.*) - } >ram AT>flash :ram_init - - .srodata : - { - PROVIDE( _gp = . + 0x800 ); + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) @@ -132,12 +132,6 @@ SECTIONS *(.srodata .srodata.*) } >ram AT>flash :ram_init - .sdata : - { - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - } >ram AT>flash :ram_init - . = ALIGN(4); PROVIDE( _edata = . ); PROVIDE( edata = . ); diff --git a/raven/bsp/env/freedom-e300-arty/platform.h b/raven/bsp/env/freedom-e300-arty/platform.h index d5d6dda..8ff7ae6 100644 --- a/raven/bsp/env/freedom-e300-arty/platform.h +++ b/raven/bsp/env/freedom-e300-arty/platform.h @@ -20,21 +20,21 @@ * Platform definitions *****************************************************************************/ -#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL) -#define CLINT_BASE_ADDR _AC(0x02000000,UL) -#define PLIC_BASE_ADDR _AC(0x0C000000,UL) -#define AON_BASE_ADDR _AC(0x10000000,UL) -#define GPIO_BASE_ADDR _AC(0x10012000,UL) -#define UART0_BASE_ADDR _AC(0x10013000,UL) -#define SPI0_BASE_ADDR _AC(0x10014000,UL) -#define PWM0_BASE_ADDR _AC(0x10015000,UL) -#define UART1_BASE_ADDR _AC(0x10023000,UL) -#define SPI1_BASE_ADDR _AC(0x10024000,UL) -#define PWM1_BASE_ADDR _AC(0x10025000,UL) -#define SPI2_BASE_ADDR _AC(0x10034000,UL) -#define PWM2_BASE_ADDR _AC(0x10035000,UL) +#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL) +#define CLINT_CTRL_ADDR _AC(0x02000000,UL) +#define PLIC_CTRL_ADDR _AC(0x0C000000,UL) +#define AON_CTRL_ADDR _AC(0x10000000,UL) +#define GPIO_CTRL_ADDR _AC(0x10012000,UL) +#define UART0_CTRL_ADDR _AC(0x10013000,UL) +#define SPI0_CTRL_ADDR _AC(0x10014000,UL) +#define PWM0_CTRL_ADDR _AC(0x10015000,UL) +#define UART1_CTRL_ADDR _AC(0x10023000,UL) +#define SPI1_CTRL_ADDR _AC(0x10024000,UL) +#define PWM1_CTRL_ADDR _AC(0x10025000,UL) +#define SPI2_CTRL_ADDR _AC(0x10034000,UL) +#define PWM2_CTRL_ADDR _AC(0x10035000,UL) #define SPI0_MMAP_ADDR _AC(0x20000000,UL) -#define MEM_BASE_ADDR _AC(0x80000000,UL) +#define MEM_CTRL_ADDR _AC(0x80000000,UL) // IOF Mappings #define IOF0_SPI1_MASK _AC(0x000007FC,UL) @@ -91,20 +91,19 @@ // Helper functions #define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) #define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) -#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset) -#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset) -#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset) -#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset) -#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset) -#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset) -#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset) -#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset) -#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset) -#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset) -#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset) -#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset) -#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset) -#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset) +#define AON_REG(offset) _REG32(AON_CTRL_ADDR, offset) +#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) +#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define OTP_REG(offset) _REG32(OTP_CTRL_ADDR, offset) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) +#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset) +#define PWM1_REG(offset) _REG32(PWM1_CTRL_ADDR, offset) +#define PWM2_REG(offset) _REG32(PWM2_CTRL_ADDR, offset) +#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset) +#define SPI1_REG(offset) _REG32(SPI1_CTRL_ADDR, offset) +#define SPI2_REG(offset) _REG32(SPI2_CTRL_ADDR, offset) +#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset) +#define UART1_REG(offset) _REG32(UART1_CTRL_ADDR, offset) // Misc diff --git a/raven/bsp/env/freedom-e300-arty/settings.mk b/raven/bsp/env/freedom-e300-arty/settings.mk new file mode 100644 index 0000000..230fccc --- /dev/null +++ b/raven/bsp/env/freedom-e300-arty/settings.mk @@ -0,0 +1,3 @@ +# Describes the CPU on this board to the rest of the SDK. +RISCV_ARCH := rv32imac +RISCV_ABI := ilp32 diff --git a/raven/bsp/env/iss/link.lds b/raven/bsp/env/freedom-e300-hifive1/dhrystone.lds similarity index 92% rename from raven/bsp/env/iss/link.lds rename to raven/bsp/env/freedom-e300-hifive1/dhrystone.lds index bc60026..cc9cd9b 100644 --- a/raven/bsp/env/iss/link.lds +++ b/raven/bsp/env/freedom-e300-hifive1/dhrystone.lds @@ -4,9 +4,8 @@ ENTRY( _start ) MEMORY { - /*flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M*/ flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K } PHDRS @@ -42,13 +41,6 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >flash AT>flash :flash - . = ALIGN(4); .preinit_array : @@ -119,13 +111,16 @@ SECTIONS .data : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) - } >ram AT>flash :ram_init - - .srodata : - { - PROVIDE( _gp = . + 0x800 ); + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) @@ -133,12 +128,6 @@ SECTIONS *(.srodata .srodata.*) } >ram AT>flash :ram_init - .sdata : - { - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - } >ram AT>flash :ram_init - . = ALIGN(4); PROVIDE( _edata = . ); PROVIDE( edata = . ); diff --git a/raven/bsp/env/freedom-e300-hifive1/link.lds b/raven/bsp/env/freedom-e300-hifive1/flash.lds similarity index 96% rename from raven/bsp/env/freedom-e300-hifive1/link.lds rename to raven/bsp/env/freedom-e300-hifive1/flash.lds index 90e5c8f..6b37141 100644 --- a/raven/bsp/env/freedom-e300-hifive1/link.lds +++ b/raven/bsp/env/freedom-e300-hifive1/flash.lds @@ -120,11 +120,11 @@ SECTIONS { *(.data .data.*) *(.gnu.linkonce.d.*) - } >ram AT>flash :ram_init - - .srodata : - { - PROVIDE( _gp = . + 0x800 ); + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) @@ -132,12 +132,6 @@ SECTIONS *(.srodata .srodata.*) } >ram AT>flash :ram_init - .sdata : - { - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - } >ram AT>flash :ram_init - . = ALIGN(4); PROVIDE( _edata = . ); PROVIDE( edata = . ); diff --git a/raven/bsp/env/freedom-e300-hifive1/init.c b/raven/bsp/env/freedom-e300-hifive1/init.c index de046cc..621a6e2 100644 --- a/raven/bsp/env/freedom-e300-hifive1/init.c +++ b/raven/bsp/env/freedom-e300-hifive1/init.c @@ -10,14 +10,14 @@ extern void trap_entry(); static unsigned long mtime_lo(void) { - return *(volatile unsigned long *)(CLINT_BASE_ADDR + CLINT_MTIME); + return *(volatile unsigned long *)(CLINT_CTRL_ADDR + CLINT_MTIME); } #ifdef __riscv32 static uint32_t mtime_hi(void) { - return *(volatile uint32_t *)(CLINT_BASE_ADDR + CLINT_MTIME + 4); + return *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4); } uint64_t get_timer_value() diff --git a/raven/bsp/env/freedom-e300-hifive1/platform.h b/raven/bsp/env/freedom-e300-hifive1/platform.h index 63efc9e..806fcfc 100644 --- a/raven/bsp/env/freedom-e300-hifive1/platform.h +++ b/raven/bsp/env/freedom-e300-hifive1/platform.h @@ -23,25 +23,25 @@ *****************************************************************************/ // Memory map -#define MASKROM_BASE_ADDR _AC(0x00001000,UL) -#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL) -#define OTP_MMAP_ADDR _AC(0x00020000,UL) -#define CLINT_BASE_ADDR _AC(0x02000000,UL) -#define PLIC_BASE_ADDR _AC(0x0C000000,UL) -#define AON_BASE_ADDR _AC(0x10000000,UL) -#define PRCI_BASE_ADDR _AC(0x10008000,UL) -#define OTP_BASE_ADDR _AC(0x10010000,UL) -#define GPIO_BASE_ADDR _AC(0x10012000,UL) -#define UART0_BASE_ADDR _AC(0x10013000,UL) -#define SPI0_BASE_ADDR _AC(0x10014000,UL) -#define PWM0_BASE_ADDR _AC(0x10015000,UL) -#define UART1_BASE_ADDR _AC(0x10023000,UL) -#define SPI1_BASE_ADDR _AC(0x10024000,UL) -#define PWM1_BASE_ADDR _AC(0x10025000,UL) -#define SPI2_BASE_ADDR _AC(0x10034000,UL) -#define PWM2_BASE_ADDR _AC(0x10035000,UL) -#define SPI0_MMAP_ADDR _AC(0x20000000,UL) -#define MEM_BASE_ADDR _AC(0x80000000,UL) +#define MASKROM_MEM_ADDR _AC(0x00001000,UL) +#define TRAPVEC_TABLE_CTRL_ADDR _AC(0x00001010,UL) +#define OTP_MEM_ADDR _AC(0x00020000,UL) +#define CLINT_CTRL_ADDR _AC(0x02000000,UL) +#define PLIC_CTRL_ADDR _AC(0x0C000000,UL) +#define AON_CTRL_ADDR _AC(0x10000000,UL) +#define PRCI_CTRL_ADDR _AC(0x10008000,UL) +#define OTP_CTRL_ADDR _AC(0x10010000,UL) +#define GPIO_CTRL_ADDR _AC(0x10012000,UL) +#define UART0_CTRL_ADDR _AC(0x10013000,UL) +#define SPI0_CTRL_ADDR _AC(0x10014000,UL) +#define PWM0_CTRL_ADDR _AC(0x10015000,UL) +#define UART1_CTRL_ADDR _AC(0x10023000,UL) +#define SPI1_CTRL_ADDR _AC(0x10024000,UL) +#define PWM1_CTRL_ADDR _AC(0x10025000,UL) +#define SPI2_CTRL_ADDR _AC(0x10034000,UL) +#define PWM2_CTRL_ADDR _AC(0x10035000,UL) +#define SPI0_MEM_ADDR _AC(0x20000000,UL) +#define MEM_CTRL_ADDR _AC(0x80000000,UL) // IOF masks #define IOF0_SPI1_MASK _AC(0x000007FC,UL) @@ -100,20 +100,20 @@ // Helper functions #define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) #define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) -#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset) -#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset) -#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset) -#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset) -#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset) -#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset) -#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset) -#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset) -#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset) -#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset) -#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset) -#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset) -#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset) -#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset) +#define AON_REG(offset) _REG32(AON_CTRL_ADDR, offset) +#define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) +#define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define OTP_REG(offset) _REG32(OTP_CTRL_ADDR, offset) +#define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) +#define PRCI_REG(offset) _REG32(PRCI_CTRL_ADDR, offset) +#define PWM0_REG(offset) _REG32(PWM0_CTRL_ADDR, offset) +#define PWM1_REG(offset) _REG32(PWM1_CTRL_ADDR, offset) +#define PWM2_REG(offset) _REG32(PWM2_CTRL_ADDR, offset) +#define SPI0_REG(offset) _REG32(SPI0_CTRL_ADDR, offset) +#define SPI1_REG(offset) _REG32(SPI1_CTRL_ADDR, offset) +#define SPI2_REG(offset) _REG32(SPI2_CTRL_ADDR, offset) +#define UART0_REG(offset) _REG32(UART0_CTRL_ADDR, offset) +#define UART1_REG(offset) _REG32(UART1_CTRL_ADDR, offset) // Misc diff --git a/raven/bsp/env/freedom-e300-hifive1/settings.mk b/raven/bsp/env/freedom-e300-hifive1/settings.mk new file mode 100644 index 0000000..230fccc --- /dev/null +++ b/raven/bsp/env/freedom-e300-hifive1/settings.mk @@ -0,0 +1,3 @@ +# Describes the CPU on this board to the rest of the SDK. +RISCV_ARCH := rv32imac +RISCV_ABI := ilp32 diff --git a/raven/bsp/env/hifive1.h b/raven/bsp/env/hifive1.h index cfd7099..0db2f0f 100644 --- a/raven/bsp/env/hifive1.h +++ b/raven/bsp/env/hifive1.h @@ -76,4 +76,6 @@ #define RTC_FREQ 32768 +void write_hex(int fd, unsigned long int hex); + #endif /* _SIFIVE_HIFIVE1_H */ diff --git a/raven/bsp/env/iss/init.c b/raven/bsp/env/iss/init.c deleted file mode 100644 index de046cc..0000000 --- a/raven/bsp/env/iss/init.c +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include -#include - -#include "platform.h" -#include "encoding.h" - -extern int main(int argc, char** argv); -extern void trap_entry(); - -static unsigned long mtime_lo(void) -{ - return *(volatile unsigned long *)(CLINT_BASE_ADDR + CLINT_MTIME); -} - -#ifdef __riscv32 - -static uint32_t mtime_hi(void) -{ - return *(volatile uint32_t *)(CLINT_BASE_ADDR + CLINT_MTIME + 4); -} - -uint64_t get_timer_value() -{ - while (1) { - uint32_t hi = mtime_hi(); - uint32_t lo = mtime_lo(); - if (hi == mtime_hi()) - return ((uint64_t)hi << 32) | lo; - } -} - -#else /* __riscv32 */ - -uint64_t get_timer_value() -{ - return mtime_lo(); -} - -#endif - -unsigned long get_timer_freq() -{ - return 32768; -} - -static void use_hfrosc(int div, int trim) -{ - // Make sure the HFROSC is running at its default setting - PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(div) | ROSC_TRIM(trim) | ROSC_EN(1)); - while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0) ; - PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1); -} - -static void use_pll(int refsel, int bypass, int r, int f, int q) -{ - // Ensure that we aren't running off the PLL before we mess with it. - if (PRCI_REG(PRCI_PLLCFG) & PLL_SEL(1)) { - // Make sure the HFROSC is running at its default setting - use_hfrosc(4, 16); - } - - // Set PLL Source to be HFXOSC if available. - uint32_t config_value = 0; - - config_value |= PLL_REFSEL(refsel); - - if (bypass) { - // Bypass - config_value |= PLL_BYPASS(1); - - PRCI_REG(PRCI_PLLCFG) = config_value; - - // If we don't have an HFXTAL, this doesn't really matter. - // Set our Final output divide to divide-by-1: - PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); - } else { - // In case we are executing from QSPI, - // (which is quite likely) we need to - // set the QSPI clock divider appropriately - // before boosting the clock frequency. - - // Div = f_sck/2 - SPI0_REG(SPI_REG_SCKDIV) = 8; - - // Set DIV Settings for PLL - // Both HFROSC and HFXOSC are modeled as ideal - // 16MHz sources (assuming dividers are set properly for - // HFROSC). - // (Legal values of f_REF are 6-48MHz) - - // Set DIVR to divide-by-2 to get 8MHz frequency - // (legal values of f_R are 6-12 MHz) - - config_value |= PLL_BYPASS(1); - config_value |= PLL_R(r); - - // Set DIVF to get 512Mhz frequncy - // There is an implied multiply-by-2, 16Mhz. - // So need to write 32-1 - // (legal values of f_F are 384-768 MHz) - config_value |= PLL_F(f); - - // Set DIVQ to divide-by-2 to get 256 MHz frequency - // (legal values of f_Q are 50-400Mhz) - config_value |= PLL_Q(q); - - // Set our Final output divide to divide-by-1: - PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); - - PRCI_REG(PRCI_PLLCFG) = config_value; - - // Un-Bypass the PLL. - PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1); - - // Wait for PLL Lock - // Note that the Lock signal can be glitchy. - // Need to wait 100 us - // RTC is running at 32kHz. - // So wait 4 ticks of RTC. - uint32_t now = mtime_lo(); - while (mtime_lo() - now < 4) ; - - // Now it is safe to check for PLL Lock - while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0) ; - } - - // Switch over to PLL Clock source - PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1); -} - -static void use_default_clocks() -{ - // Turn off the LFROSC - AON_REG(AON_LFROSC) &= ~ROSC_EN(1); - - // Use HFROSC - use_hfrosc(4, 16); -} - -static unsigned long __attribute__((noinline)) measure_cpu_freq(size_t n) -{ - unsigned long start_mtime, delta_mtime; - unsigned long mtime_freq = get_timer_freq(); - - // Don't start measuruing until we see an mtime tick - unsigned long tmp = mtime_lo(); - do { - start_mtime = mtime_lo(); - } while (start_mtime == tmp); - - unsigned long start_mcycle = read_csr(mcycle); - - do { - delta_mtime = mtime_lo() - start_mtime; - } while (delta_mtime < n); - - unsigned long delta_mcycle = read_csr(mcycle) - start_mcycle; - - return (delta_mcycle / delta_mtime) * mtime_freq - + ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime; -} - -unsigned long get_cpu_freq() -{ - static uint32_t cpu_freq; - - if (!cpu_freq) { - // warm up I$ - measure_cpu_freq(1); - // measure for real - cpu_freq = measure_cpu_freq(10); - } - - return cpu_freq; -} - -static void uart_init(size_t baud_rate) -{ - GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; - GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK; - UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1; - UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; -} - - - -#ifdef USE_PLIC -extern void handle_m_ext_interrupt(); -#endif - -#ifdef USE_M_TIME -extern void handle_m_time_interrupt(); -#endif - -uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) -{ - if (0){ -#ifdef USE_PLIC - // External Machine-Level interrupt from PLIC - } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) { - handle_m_ext_interrupt(); -#endif -#ifdef USE_M_TIME - // External Machine-Level interrupt from PLIC - } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){ - handle_m_time_interrupt(); -#endif - } - else { - write(1, "trap\n", 5); - _exit(1 + mcause); - } - return epc; -} - -void _init() -{ - - #ifndef NO_INIT - use_default_clocks(); - use_pll(0, 0, 1, 31, 1); - uart_init(115200); - - printf("core freq at %d Hz\n", get_cpu_freq()); - - write_csr(mtvec, &trap_entry); - if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present - write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping - write_csr(fcsr, 0); // initialize rounding mode, undefined at reset - } - #endif - -} - -void _fini() -{ -} diff --git a/raven/bsp/env/iss/openocd.cfg b/raven/bsp/env/iss/openocd.cfg deleted file mode 100644 index b531e9c..0000000 --- a/raven/bsp/env/iss/openocd.cfg +++ /dev/null @@ -1,34 +0,0 @@ -adapter_khz 10000 - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x001b -ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 - -#Reset Stretcher logic on FE310 is ~1 second long -#This doesn't apply if you use -# ftdi_set_signal, but still good to document -#adapter_nsrst_delay 1500 - -set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME riscv -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 - -flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME -init -#reset -- This type of reset is not implemented yet -if {[ info exists pulse_srst]} { - ftdi_set_signal nSRST 0 - ftdi_set_signal nSRST z - #Wait for the reset stretcher - #It will work without this, but - #will incur lots of delays for later commands. - sleep 1500 -} -halt -#flash protect 0 64 last off diff --git a/raven/bsp/env/iss/platform.h b/raven/bsp/env/iss/platform.h deleted file mode 100644 index 63efc9e..0000000 --- a/raven/bsp/env/iss/platform.h +++ /dev/null @@ -1,133 +0,0 @@ -// See LICENSE for license details. - -#ifndef _SIFIVE_PLATFORM_H -#define _SIFIVE_PLATFORM_H - -// Some things missing from the official encoding.h -#define MCAUSE_INT 0x80000000 -#define MCAUSE_CAUSE 0x7FFFFFFF - -#include "sifive/const.h" -#include "sifive/devices/aon.h" -#include "sifive/devices/clint.h" -#include "sifive/devices/gpio.h" -#include "sifive/devices/otp.h" -#include "sifive/devices/plic.h" -#include "sifive/devices/prci.h" -#include "sifive/devices/pwm.h" -#include "sifive/devices/spi.h" -#include "sifive/devices/uart.h" - -/**************************************************************************** - * Platform definitions - *****************************************************************************/ - -// Memory map -#define MASKROM_BASE_ADDR _AC(0x00001000,UL) -#define TRAPVEC_TABLE_BASE_ADDR _AC(0x00001010,UL) -#define OTP_MMAP_ADDR _AC(0x00020000,UL) -#define CLINT_BASE_ADDR _AC(0x02000000,UL) -#define PLIC_BASE_ADDR _AC(0x0C000000,UL) -#define AON_BASE_ADDR _AC(0x10000000,UL) -#define PRCI_BASE_ADDR _AC(0x10008000,UL) -#define OTP_BASE_ADDR _AC(0x10010000,UL) -#define GPIO_BASE_ADDR _AC(0x10012000,UL) -#define UART0_BASE_ADDR _AC(0x10013000,UL) -#define SPI0_BASE_ADDR _AC(0x10014000,UL) -#define PWM0_BASE_ADDR _AC(0x10015000,UL) -#define UART1_BASE_ADDR _AC(0x10023000,UL) -#define SPI1_BASE_ADDR _AC(0x10024000,UL) -#define PWM1_BASE_ADDR _AC(0x10025000,UL) -#define SPI2_BASE_ADDR _AC(0x10034000,UL) -#define PWM2_BASE_ADDR _AC(0x10035000,UL) -#define SPI0_MMAP_ADDR _AC(0x20000000,UL) -#define MEM_BASE_ADDR _AC(0x80000000,UL) - -// IOF masks -#define IOF0_SPI1_MASK _AC(0x000007FC,UL) -#define SPI11_NUM_SS (4) -#define IOF_SPI1_SS0 (2u) -#define IOF_SPI1_SS1 (8u) -#define IOF_SPI1_SS2 (9u) -#define IOF_SPI1_SS3 (10u) -#define IOF_SPI1_MOSI (3u) -#define IOF_SPI1_MISO (4u) -#define IOF_SPI1_SCK (5u) -#define IOF_SPI1_DQ0 (3u) -#define IOF_SPI1_DQ1 (4u) -#define IOF_SPI1_DQ2 (6u) -#define IOF_SPI1_DQ3 (7u) - -#define IOF0_SPI2_MASK _AC(0xFC000000,UL) -#define SPI2_NUM_SS (1) -#define IOF_SPI2_SS0 (26u) -#define IOF_SPI2_MOSI (27u) -#define IOF_SPI2_MISO (28u) -#define IOF_SPI2_SCK (29u) -#define IOF_SPI2_DQ0 (27u) -#define IOF_SPI2_DQ1 (28u) -#define IOF_SPI2_DQ2 (30u) -#define IOF_SPI2_DQ3 (31u) - -//#define IOF0_I2C_MASK _AC(0x00003000,UL) - -#define IOF0_UART0_MASK _AC(0x00030000, UL) -#define IOF_UART0_RX (16u) -#define IOF_UART0_TX (17u) - -#define IOF0_UART1_MASK _AC(0x03000000, UL) -#define IOF_UART1_RX (24u) -#define IOF_UART1_TX (25u) - -#define IOF1_PWM0_MASK _AC(0x0000000F, UL) -#define IOF1_PWM1_MASK _AC(0x00780000, UL) -#define IOF1_PWM2_MASK _AC(0x00003C00, UL) - -// Interrupt numbers -#define INT_RESERVED 0 -#define INT_WDOGCMP 1 -#define INT_RTCCMP 2 -#define INT_UART0_BASE 3 -#define INT_UART1_BASE 4 -#define INT_SPI0_BASE 5 -#define INT_SPI1_BASE 6 -#define INT_SPI2_BASE 7 -#define INT_GPIO_BASE 8 -#define INT_PWM0_BASE 40 -#define INT_PWM1_BASE 44 -#define INT_PWM2_BASE 48 - -// Helper functions -#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) -#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) -#define AON_REG(offset) _REG32(AON_BASE_ADDR, offset) -#define CLINT_REG(offset) _REG32(CLINT_BASE_ADDR, offset) -#define GPIO_REG(offset) _REG32(GPIO_BASE_ADDR, offset) -#define OTP_REG(offset) _REG32(OTP_BASE_ADDR, offset) -#define PLIC_REG(offset) _REG32(PLIC_BASE_ADDR, offset) -#define PRCI_REG(offset) _REG32(PRCI_BASE_ADDR, offset) -#define PWM0_REG(offset) _REG32(PWM0_BASE_ADDR, offset) -#define PWM1_REG(offset) _REG32(PWM1_BASE_ADDR, offset) -#define PWM2_REG(offset) _REG32(PWM2_BASE_ADDR, offset) -#define SPI0_REG(offset) _REG32(SPI0_BASE_ADDR, offset) -#define SPI1_REG(offset) _REG32(SPI1_BASE_ADDR, offset) -#define SPI2_REG(offset) _REG32(SPI2_BASE_ADDR, offset) -#define UART0_REG(offset) _REG32(UART0_BASE_ADDR, offset) -#define UART1_REG(offset) _REG32(UART1_BASE_ADDR, offset) - -// Misc - -#include - -#define NUM_GPIO 32 - -#define PLIC_NUM_INTERRUPTS 52 -#define PLIC_NUM_PRIORITIES 7 - -#include "hifive1.h" - -unsigned long get_cpu_freq(void); -unsigned long get_timer_freq(void); -uint64_t get_timer_value(void); - -#endif /* _SIFIVE_PLATFORM_H */ diff --git a/raven/bsp/env/start.S b/raven/bsp/env/start.S index b526411..4e9f665 100644 --- a/raven/bsp/env/start.S +++ b/raven/bsp/env/start.S @@ -1,13 +1,27 @@ // See LICENSE for license details. +#include + +/* This is defined in sifive/platform.h, but that can't be included from + * assembly. */ +#define CLINT_CTRL_ADDR 0x02000000 .section .init .globl _start .type _start,@function _start: - la gp, _gp + .cfi_startproc + .cfi_undefined ra +.option push +.option norelax + la gp, __global_pointer$ +.option pop la sp, _sp +#if defined(ENABLE_SMP) + smp_pause(t0, t1) +#endif + /* Load data section */ la a0, _data_lma la a1, _data @@ -47,8 +61,51 @@ _start: 1: #endif +#if defined(ENABLE_SMP) + smp_resume(t0, t1) + + csrr a0, mhartid + bnez a0, 2f +#endif + + auipc ra, 0 + addi sp, sp, -16 +#if __riscv_xlen == 32 + sw ra, 8(sp) +#else + sd ra, 8(sp) +#endif + /* argc = argv = 0 */ li a0, 0 li a1, 0 call main tail exit +1: + j 1b + +#if defined(ENABLE_SMP) +2: + la t0, trap_entry + csrw mtvec, t0 + + csrr a0, mhartid + la t1, _sp + slli t0, a0, 10 + sub sp, t1, t0 + + auipc ra, 0 + addi sp, sp, -16 +#if __riscv_xlen == 32 + sw ra, 8(sp) +#else + sd ra, 8(sp) +#endif + + call secondary_main + tail exit + +1: + j 1b +#endif + .cfi_endproc diff --git a/raven/bsp/env/ventry.S b/raven/bsp/env/ventry.S new file mode 100644 index 0000000..5c82c48 --- /dev/null +++ b/raven/bsp/env/ventry.S @@ -0,0 +1,288 @@ +// See LICENSE for license details + +#ifndef VENTRY_S +#define VENTRY_S + +#include "encoding.h" +#include "sifive/bits.h" + +#only save caller registers +.macro TRAP_ENTRY + addi sp, sp, -16*REGBYTES + + STORE x1, 0*REGBYTES(sp) + STORE x5, 1*REGBYTES(sp) + STORE x6, 2*REGBYTES(sp) + STORE x7, 3*REGBYTES(sp) + STORE x10, 4*REGBYTES(sp) + STORE x11, 5*REGBYTES(sp) + STORE x12, 6*REGBYTES(sp) + STORE x13, 7*REGBYTES(sp) + STORE x14, 8*REGBYTES(sp) + STORE x15, 9*REGBYTES(sp) + STORE x16, 10*REGBYTES(sp) + STORE x17, 11*REGBYTES(sp) + STORE x28, 12*REGBYTES(sp) + STORE x29, 13*REGBYTES(sp) + STORE x30, 14*REGBYTES(sp) + STORE x31, 15*REGBYTES(sp) +.endm + +#restore caller registers +.macro TRAP_EXIT +# Remain in M-mode after mret + li t0, MSTATUS_MPP + csrs mstatus, t0 + + LOAD x1, 0*REGBYTES(sp) + LOAD x5, 1*REGBYTES(sp) + LOAD x6, 2*REGBYTES(sp) + LOAD x7, 3*REGBYTES(sp) + LOAD x10, 4*REGBYTES(sp) + LOAD x11, 5*REGBYTES(sp) + LOAD x12, 6*REGBYTES(sp) + LOAD x13, 7*REGBYTES(sp) + LOAD x14, 8*REGBYTES(sp) + LOAD x15, 9*REGBYTES(sp) + LOAD x16, 10*REGBYTES(sp) + LOAD x17, 11*REGBYTES(sp) + LOAD x28, 12*REGBYTES(sp) + LOAD x29, 13*REGBYTES(sp) + LOAD x30, 14*REGBYTES(sp) + LOAD x31, 15*REGBYTES(sp) + + addi sp, sp, 16*REGBYTES + mret +.endm + + + +#Vector table for E31/E51 + + .section .text.entry + .align 8 + .global vtrap_entry +vtrap_entry: + j sync_trap + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmsi_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmti_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vmei_Handler + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j reserved + .align 2 + j vlip_Handler0 + .align 2 + j vlip_Handler1 + .align 2 + j vlip_Handler2 + .align 2 + j vlip_Handler3 + .align 2 + j vlip_Handler4 + .align 2 + j vlip_Handler5 + .align 2 + j vlip_Handler6 + .align 2 + j vlip_Handler7 + .align 2 + j vlip_Handler8 + .align 2 + j vlip_Handler9 + .align 2 + j vlip_Handler10 + .align 2 + j vlip_Handler11 + .align 2 + j vlip_Handler12 + .align 2 + j vlip_Handler13 + .align 2 + j vlip_Handler14 + .align 2 + j vlip_Handler15 + +#synchronous trap +sync_trap: + TRAP_ENTRY + jal handle_sync_trap + TRAP_EXIT + +#Machine Software Interrupt +vmsi_Handler: + TRAP_ENTRY + jal reserved + TRAP_EXIT + +#Machine Timer Interrupt +vmti_Handler: + TRAP_ENTRY + jal handle_m_time_interrupt + TRAP_EXIT + +#Machine External Interrupt +vmei_Handler: + TRAP_ENTRY + jal handle_m_external_interrupt + TRAP_EXIT + +#LIP0 +vlip_Handler0: + TRAP_ENTRY + jal handle_local_interrupt0 + TRAP_EXIT + +#LIP1 +vlip_Handler1: + TRAP_ENTRY + jal handle_local_interrupt1 + TRAP_EXIT + +#LIP2 +vlip_Handler2: + TRAP_ENTRY + jal handle_local_interrupt2 + TRAP_EXIT + +#LIP3 +vlip_Handler3: + TRAP_ENTRY + jal handle_local_interrupt3 + TRAP_EXIT + +#LIP4 +vlip_Handler4: + TRAP_ENTRY + jal handle_local_interrupt4 + TRAP_EXIT + +#LIP5 +vlip_Handler5: + TRAP_ENTRY + jal handle_local_interrupt5 + TRAP_EXIT + +#LIP6 +vlip_Handler6: + TRAP_ENTRY + jal handle_local_interrupt6 + TRAP_EXIT + +#LIP7 +vlip_Handler7: + TRAP_ENTRY + jal handle_local_interrupt7 + TRAP_EXIT + +#LIP8 +vlip_Handler8: + TRAP_ENTRY + jal handle_local_interrupt8 + TRAP_EXIT + +#LIP9 +vlip_Handler9: + TRAP_ENTRY + jal handle_local_interrupt9 + TRAP_EXIT + +#LIP10 +vlip_Handler10: + TRAP_ENTRY + jal handle_local_interrupt10 + TRAP_EXIT + +#LIP11 +vlip_Handler11: + TRAP_ENTRY + jal handle_local_interrupt11 + TRAP_EXIT + +#LIP12 +vlip_Handler12: + TRAP_ENTRY + jal handle_local_interrupt12 + TRAP_EXIT + +#LIP13 +vlip_Handler13: + TRAP_ENTRY + jal handle_local_interrupt13 + TRAP_EXIT + +#LIP14 +vlip_Handler14: + TRAP_ENTRY + jal handle_local_interrupt14 + TRAP_EXIT + +#LIP15 +vlip_Handler15: + TRAP_ENTRY + jal handle_local_interrupt15 + TRAP_EXIT + +#unimplemented ISRs trap here +.weak reserved +reserved: +.weak handle_local_interrupt0 +handle_local_interrupt0: +.weak handle_local_interrupt1 +handle_local_interrupt1: +.weak handle_local_interrupt2 +handle_local_interrupt2: +.weak handle_local_interrupt3 +handle_local_interrupt3: +.weak handle_local_interrupt4 +handle_local_interrupt4: +.weak handle_local_interrupt5 +handle_local_interrupt5: +.weak handle_local_interrupt6 +handle_local_interrupt6: +.weak handle_local_interrupt7 +handle_local_interrupt7: +.weak handle_local_interrupt8 +handle_local_interrupt8: +.weak handle_local_interrupt9 +handle_local_interrupt9: +.weak handle_local_interrupt10 +handle_local_interrupt10: +.weak handle_local_interrupt11 +handle_local_interrupt11: +.weak handle_local_interrupt12 +handle_local_interrupt12: +.weak handle_local_interrupt13 +handle_local_interrupt13: +.weak handle_local_interrupt14 +handle_local_interrupt14: +.weak handle_local_interrupt15 +handle_local_interrupt15: +1: + j 1b + +#endif diff --git a/raven/bsp/include/sifive/bits.h b/raven/bsp/include/sifive/bits.h index e550f80..bfe656f 100644 --- a/raven/bsp/include/sifive/bits.h +++ b/raven/bsp/include/sifive/bits.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. #ifndef _RISCV_BITS_H #define _RISCV_BITS_H @@ -17,7 +18,7 @@ #define STR(x) XSTR(x) #define XSTR(x) #x -#ifdef __riscv64 +#if __riscv_xlen == 64 # define SLL32 sllw # define STORE sd # define LOAD ld diff --git a/raven/bsp/include/sifive/const.h b/raven/bsp/include/sifive/const.h index 3e0a681..8dcffbb 100644 --- a/raven/bsp/include/sifive/const.h +++ b/raven/bsp/include/sifive/const.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. /* Derived from */ #ifndef _SIFIVE_CONST_H diff --git a/raven/bsp/include/sifive/devices/clic.h b/raven/bsp/include/sifive/devices/clic.h new file mode 100644 index 0000000..e8dc2df --- /dev/null +++ b/raven/bsp/include/sifive/devices/clic.h @@ -0,0 +1,30 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_CLIC_H +#define _SIFIVE_CLIC_H + +#define CLIC_HART0 0x00800000 +#define CLIC_MSIP 0x0000 +#define CLIC_MSIP_size 0x4 +#define CLIC_MTIMECMP 0x4000 +#define CLIC_MTIMECMP_size 0x8 +#define CLIC_MTIME 0xBFF8 +#define CLIC_MTIME_size 0x8 + +#define CLIC_INTIP 0x000 +#define CLIC_INTIE 0x400 +#define CLIC_INTCFG 0x800 +#define CLIC_CFG 0xc00 + +// These interrupt IDs are consistent across old and new mtvec modes +#define SSIPID 1 +#define MSIPID 3 +#define STIPID 5 +#define MTIPID 7 +#define SEIPID 9 +#define MEIPID 11 +#define CSIPID 12 +#define LOCALINTIDBASE 16 + + +#endif /* _SIFIVE_CLIC_H */ diff --git a/raven/bsp/include/sifive/devices/spi.h b/raven/bsp/include/sifive/devices/spi.h index 916d86b..80ef345 100644 --- a/raven/bsp/include/sifive/devices/spi.h +++ b/raven/bsp/include/sifive/devices/spi.h @@ -30,8 +30,8 @@ /* Fields */ -#define SPI_SCK_POL 0x1 -#define SPI_SCK_PHA 0x2 +#define SPI_SCK_PHA 0x1 +#define SPI_SCK_POL 0x2 #define SPI_FMT_PROTO(x) ((x) & 0x3) #define SPI_FMT_ENDIAN(x) (((x) & 0x1) << 2) diff --git a/raven/bsp/include/sifive/sections.h b/raven/bsp/include/sifive/sections.h index 848c237..6e1f051 100644 --- a/raven/bsp/include/sifive/sections.h +++ b/raven/bsp/include/sifive/sections.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. #ifndef _SECTIONS_H #define _SECTIONS_H diff --git a/raven/bsp/include/sifive/smp.h b/raven/bsp/include/sifive/smp.h new file mode 100644 index 0000000..8e34388 --- /dev/null +++ b/raven/bsp/include/sifive/smp.h @@ -0,0 +1,65 @@ +#ifndef SIFIVE_SMP +#define SIFIVE_SMP + +// The maximum number of HARTs this code supports +#ifndef MAX_HARTS +#define MAX_HARTS 32 +#endif +#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4) + +// The hart that non-SMP tests should run on +#ifndef NONSMP_HART +#define NONSMP_HART 0 +#endif + +/* If your test cannot handle multiple-threads, use this: + * smp_disable(reg1) + */ +#define smp_disable(reg1, reg2) \ + csrr reg1, mhartid ;\ + li reg2, NONSMP_HART ;\ + beq reg1, reg2, hart0_entry ;\ +42: ;\ + wfi ;\ + j 42b ;\ +hart0_entry: + +/* If your test needs to temporarily block multiple-threads, do this: + * smp_pause(reg1, reg2) + * ... single-threaded work ... + * smp_resume(reg1, reg2) + * ... multi-threaded work ... + */ + +#define smp_pause(reg1, reg2) \ + li reg2, 0x8 ;\ + csrw mie, reg2 ;\ + csrr reg2, mhartid ;\ + bnez reg2, 42f + +#define smp_resume(reg1, reg2) \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ +42: ;\ + wfi ;\ + csrr reg2, mip ;\ + andi reg2, reg2, 0x8 ;\ + beqz reg2, 42b ;\ + li reg1, CLINT_CTRL_ADDR ;\ + csrr reg2, mhartid ;\ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b + +#endif diff --git a/raven/bsp/libwrap/libwrap.mk b/raven/bsp/libwrap/libwrap.mk index add3285..71bba3d 100644 --- a/raven/bsp/libwrap/libwrap.mk +++ b/raven/bsp/libwrap/libwrap.mk @@ -25,7 +25,9 @@ LIBWRAP_SRCS := \ sys/isatty.c \ sys/times.c \ sys/sbrk.c \ - sys/_exit.c + sys/_exit.c \ + sys/puts.c \ + misc/write_hex.c LIBWRAP_SRCS := $(foreach f,$(LIBWRAP_SRCS),$(LIBWRAP_DIR)/$(f)) LIBWRAP_OBJS := $(LIBWRAP_SRCS:.c=.o) @@ -33,13 +35,14 @@ LIBWRAP_OBJS := $(LIBWRAP_SRCS:.c=.o) LIBWRAP_SYMS := malloc free \ open lseek read write fstat stat close link unlink \ execve fork getpid kill wait \ - isatty times sbrk _exit + isatty times sbrk _exit puts LIBWRAP := libwrap.a LINK_DEPS += $(LIBWRAP) LDFLAGS += $(foreach s,$(LIBWRAP_SYMS),-Wl,--wrap=$(s)) +LDFLAGS += $(foreach s,$(LIBWRAP_SYMS),-Wl,--wrap=_$(s)) LDFLAGS += -L. -Wl,--start-group -lwrap -lc -Wl,--end-group CLEAN_OBJS += $(LIBWRAP_OBJS) diff --git a/raven/bsp/libwrap/misc/write_hex.c b/raven/bsp/libwrap/misc/write_hex.c new file mode 100644 index 0000000..a35ad7a --- /dev/null +++ b/raven/bsp/libwrap/misc/write_hex.c @@ -0,0 +1,19 @@ +/* See LICENSE of license details. */ + +#include +#include +#include "platform.h" + +void write_hex(int fd, unsigned long int hex) +{ + uint8_t ii; + uint8_t jj; + char towrite; + write(fd , "0x", 2); + for (ii = sizeof(unsigned long int) * 2 ; ii > 0; ii--) { + jj = ii - 1; + uint8_t digit = ((hex & (0xF << (jj*4))) >> (jj*4)); + towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA)); + write(fd, &towrite, 1); + } +} diff --git a/raven/bsp/libwrap/sys/_exit.c b/raven/bsp/libwrap/sys/_exit.c index ceb0b82..011464f 100644 --- a/raven/bsp/libwrap/sys/_exit.c +++ b/raven/bsp/libwrap/sys/_exit.c @@ -2,15 +2,16 @@ #include #include "platform.h" +#include "weak_under_alias.h" -void __wrap__exit(int code) +void __wrap_exit(int code) { -//volatile uint32_t* leds = (uint32_t*) (GPIO_BASE_ADDR + GPIO_OUT_OFFSET); const char message[] = "\nProgam has exited with code:"; -//*leds = (~(code)); write(STDERR_FILENO, message, sizeof(message) - 1); + write_hex(STDERR_FILENO, code); write(STDERR_FILENO, "\n", 1); for (;;); } +weak_under_alias(exit); diff --git a/raven/bsp/libwrap/sys/close.c b/raven/bsp/libwrap/sys/close.c index e4f8e14..199fe51 100644 --- a/raven/bsp/libwrap/sys/close.c +++ b/raven/bsp/libwrap/sys/close.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_close(int fd) { return _stub(EBADF); } +weak_under_alias(close); diff --git a/raven/bsp/libwrap/sys/execve.c b/raven/bsp/libwrap/sys/execve.c index 6178a01..f7be25a 100644 --- a/raven/bsp/libwrap/sys/execve.c +++ b/raven/bsp/libwrap/sys/execve.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_execve(const char* name, char* const argv[], char* const env[]) { return _stub(ENOMEM); } +weak_under_alias(execve); diff --git a/raven/bsp/libwrap/sys/fstat.c b/raven/bsp/libwrap/sys/fstat.c index 6ea3e6a..ff82bf9 100644 --- a/raven/bsp/libwrap/sys/fstat.c +++ b/raven/bsp/libwrap/sys/fstat.c @@ -4,6 +4,7 @@ #include #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_fstat(int fd, struct stat* st) { @@ -14,3 +15,4 @@ int __wrap_fstat(int fd, struct stat* st) return _stub(EBADF); } +weak_under_alias(fstat); diff --git a/raven/bsp/libwrap/sys/getpid.c b/raven/bsp/libwrap/sys/getpid.c index 5aa510b..195fbec 100644 --- a/raven/bsp/libwrap/sys/getpid.c +++ b/raven/bsp/libwrap/sys/getpid.c @@ -1,6 +1,8 @@ /* See LICENSE of license details. */ +#include "weak_under_alias.h" int __wrap_getpid(void) { return 1; } +weak_under_alias(getpid); diff --git a/raven/bsp/libwrap/sys/isatty.c b/raven/bsp/libwrap/sys/isatty.c index 55eab0a..7bb82ab 100644 --- a/raven/bsp/libwrap/sys/isatty.c +++ b/raven/bsp/libwrap/sys/isatty.c @@ -1,6 +1,7 @@ /* See LICENSE of license details. */ #include +#include "weak_under_alias.h" int __wrap_isatty(int fd) { @@ -9,3 +10,4 @@ int __wrap_isatty(int fd) return 0; } +weak_under_alias(isatty); diff --git a/raven/bsp/libwrap/sys/kill.c b/raven/bsp/libwrap/sys/kill.c index 9c56632..18b9bd4 100644 --- a/raven/bsp/libwrap/sys/kill.c +++ b/raven/bsp/libwrap/sys/kill.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_kill(int pid, int sig) { return _stub(EINVAL); } +weak_under_alias(kill); diff --git a/raven/bsp/libwrap/sys/link.c b/raven/bsp/libwrap/sys/link.c index 9340cad..0cad551 100644 --- a/raven/bsp/libwrap/sys/link.c +++ b/raven/bsp/libwrap/sys/link.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_link(const char *old_name, const char *new_name) { return _stub(EMLINK); } +weak_under_alias(link); diff --git a/raven/bsp/libwrap/sys/lseek.c b/raven/bsp/libwrap/sys/lseek.c index 46f58fa..4131449 100644 --- a/raven/bsp/libwrap/sys/lseek.c +++ b/raven/bsp/libwrap/sys/lseek.c @@ -4,6 +4,7 @@ #include #include #include "stub.h" +#include "weak_under_alias.h" off_t __wrap_lseek(int fd, off_t ptr, int dir) { @@ -12,3 +13,4 @@ off_t __wrap_lseek(int fd, off_t ptr, int dir) return _stub(EBADF); } +weak_under_alias(lseek); diff --git a/raven/bsp/libwrap/sys/open.c b/raven/bsp/libwrap/sys/open.c index d1871f9..c61415a 100644 --- a/raven/bsp/libwrap/sys/open.c +++ b/raven/bsp/libwrap/sys/open.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_open(const char* name, int flags, int mode) { return _stub(ENOENT); } +weak_under_alias(open); diff --git a/raven/bsp/libwrap/sys/openat.c b/raven/bsp/libwrap/sys/openat.c index 7f1c945..227c956 100644 --- a/raven/bsp/libwrap/sys/openat.c +++ b/raven/bsp/libwrap/sys/openat.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_openat(int dirfd, const char* name, int flags, int mode) { return _stub(ENOENT); } +weak_under_alias(openat); diff --git a/raven/bsp/libwrap/sys/puts.c b/raven/bsp/libwrap/sys/puts.c new file mode 100644 index 0000000..50d6437 --- /dev/null +++ b/raven/bsp/libwrap/sys/puts.c @@ -0,0 +1,28 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "platform.h" +#include "stub.h" +#include "weak_under_alias.h" + +int __wrap_puts(const char *s) +{ + while (*s != '\0') { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = *s; + + if (*s == '\n') { + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = '\r'; + } + + ++s; + } + + return 0; +} +weak_under_alias(puts); diff --git a/raven/bsp/libwrap/sys/read.c b/raven/bsp/libwrap/sys/read.c index 4e57f08..3226cdb 100644 --- a/raven/bsp/libwrap/sys/read.c +++ b/raven/bsp/libwrap/sys/read.c @@ -7,12 +7,13 @@ #include "platform.h" #include "stub.h" +#include "weak_under_alias.h" ssize_t __wrap_read(int fd, void* ptr, size_t len) { uint8_t * current = (uint8_t *)ptr; - volatile uint32_t * uart_rx = (uint32_t *)(UART0_BASE_ADDR + UART_REG_RXFIFO); - volatile uint8_t * uart_rx_cnt = (uint8_t *)(UART0_BASE_ADDR + UART_REG_RXCTRL + 2); + volatile uint32_t * uart_rx = (uint32_t *)(UART0_CTRL_ADDR + UART_REG_RXFIFO); + volatile uint8_t * uart_rx_cnt = (uint8_t *)(UART0_CTRL_ADDR + UART_REG_RXCTRL + 2); ssize_t result = 0; @@ -28,3 +29,4 @@ ssize_t __wrap_read(int fd, void* ptr, size_t len) return _stub(EBADF); } +weak_under_alias(read); diff --git a/raven/bsp/libwrap/sys/sbrk.c b/raven/bsp/libwrap/sys/sbrk.c index 6e6b36a..12170b4 100644 --- a/raven/bsp/libwrap/sys/sbrk.c +++ b/raven/bsp/libwrap/sys/sbrk.c @@ -1,6 +1,7 @@ /* See LICENSE of license details. */ #include +#include "weak_under_alias.h" void *__wrap_sbrk(ptrdiff_t incr) { @@ -14,3 +15,4 @@ void *__wrap_sbrk(ptrdiff_t incr) curbrk += incr; return curbrk - incr; } +weak_under_alias(sbrk); diff --git a/raven/bsp/libwrap/sys/stat.c b/raven/bsp/libwrap/sys/stat.c index 1ccc2f4..1576ca1 100644 --- a/raven/bsp/libwrap/sys/stat.c +++ b/raven/bsp/libwrap/sys/stat.c @@ -3,8 +3,10 @@ #include #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_stat(const char* file, struct stat* st) { return _stub(EACCES); } +weak_under_alias(stat); diff --git a/raven/bsp/libwrap/sys/times.c b/raven/bsp/libwrap/sys/times.c index 26a9566..55969a7 100644 --- a/raven/bsp/libwrap/sys/times.c +++ b/raven/bsp/libwrap/sys/times.c @@ -3,8 +3,10 @@ #include #include #include "stub.h" +#include "weak_under_alias.h" clock_t __wrap_times(struct tms* buf) { return _stub(EACCES); } +weak_under_alias(times); diff --git a/raven/bsp/libwrap/sys/unlink.c b/raven/bsp/libwrap/sys/unlink.c index b62b1ba..09f4da7 100644 --- a/raven/bsp/libwrap/sys/unlink.c +++ b/raven/bsp/libwrap/sys/unlink.c @@ -2,8 +2,10 @@ #include #include "stub.h" +#include "weak_under_alias.h" int __wrap_unlink(const char* name) { return _stub(ENOENT); } +weak_under_alias(unlink); diff --git a/raven/bsp/libwrap/sys/weak_under_alias.h b/raven/bsp/libwrap/sys/weak_under_alias.h new file mode 100644 index 0000000..7629353 --- /dev/null +++ b/raven/bsp/libwrap/sys/weak_under_alias.h @@ -0,0 +1,7 @@ +#ifndef _BSP_LIBWRAP_WEAK_UNDER_ALIAS_H +#define _BSP_LIBWRAP_WEAK_UNDER_ALIAS_H + +#define weak_under_alias(name) \ + extern __typeof (__wrap_##name) __wrap__##name __attribute__ ((weak, alias ("__wrap_"#name))) + +#endif diff --git a/raven/bsp/libwrap/sys/write.c b/raven/bsp/libwrap/sys/write.c index d00eb17..b1e9a7e 100644 --- a/raven/bsp/libwrap/sys/write.c +++ b/raven/bsp/libwrap/sys/write.c @@ -7,6 +7,7 @@ #include "platform.h" #include "stub.h" +#include "weak_under_alias.h" ssize_t __wrap_write(int fd, const void* ptr, size_t len) { @@ -27,3 +28,4 @@ ssize_t __wrap_write(int fd, const void* ptr, size_t len) return _stub(EBADF); } +weak_under_alias(write); diff --git a/raven/hello_raven b/raven/hello_raven index d68e0ddb063b8e9ddc99041996cb801c5aa1fc8b..7f2c204c90795d6664b6c9783f8354ca5b6081cf 100755 GIT binary patch literal 150920 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 literal 71708 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 -#include -#include - -#include "platform.h" -#include "encoding.h" - -#define IOF_ENABLE_TERMINAL (0x30000) -int factorial(int i){ - - volatile int result = 1; - for (int ii = 1; ii <= i; ii++) { - result = result * ii; - } - return result; - -} - - - -int main() -{ - GPIO_REG(GPIO_IOF_EN) |= IOF_ENABLE_TERMINAL; // enable GPIO connection to the terminal - - int hartid = read_csr(0xf14); // CSR_MHARTID - int target_mem_base = 0x90000000; - int local_mem_base = 0x80000000; - - if (hartid == 0) { - int val_a = 5; - int val_b = 0xA; - *(int *)target_mem_base = val_a; - *(int *)(target_mem_base+4) = val_b; - printf("HW thread ID %d: write value A=0x%x and value B=0x%x to thread 1\n", hartid, val_a, val_b); - } - - - int result = factorial (10); - printf("HW thread ID %d: spend some time calculating factorial of 10=0x%x\n", hartid, result); - - if (hartid == 1) { - int val_a = *(int *)local_mem_base; - int val_b = *(int *)(local_mem_base+4); - int sum = val_a + val_b; - if (sum == 0xF) - printf("HW thread ID %d: sum of A+B=0x%x\n", hartid, sum); - else { - printf("HW thread ID %d: sum of A+B is not 0x%x. Test FAILED!!!\n", hartid, sum); - return 1; - } - } - - printf("End of execution"); - return 0; -} diff --git a/raven/hello_raven.dis b/raven/hello_raven.dis deleted file mode 100644 index c5d1bca..0000000 --- a/raven/hello_raven.dis +++ /dev/null @@ -1,2156 +0,0 @@ - -hello_raven: file format elf32-littleriscv - - -Disassembly of section .init: - -20400000 <_start>: -20400000: 5fc01197 auipc gp,0x5fc01 -20400004: c2818193 addi gp,gp,-984 # 80000c28 <_gp> -20400008: 5fc04117 auipc sp,0x5fc04 -2040000c: ff810113 addi sp,sp,-8 # 80004000 <_sp> -20400010: 00002517 auipc a0,0x2 -20400014: 40450513 addi a0,a0,1028 # 20402414 <__fini_array_end> -20400018: 5fc00597 auipc a1,0x5fc00 -2040001c: fe858593 addi a1,a1,-24 # 80000000 <_data> -20400020: 5fc00617 auipc a2,0x5fc00 -20400024: 41060613 addi a2,a2,1040 # 80000430 <__bss_start> -20400028: 00c5fc63 bgeu a1,a2,20400040 <_start+0x40> -2040002c: 00052283 lw t0,0(a0) -20400030: 0055a023 sw t0,0(a1) -20400034: 00450513 addi a0,a0,4 -20400038: 00458593 addi a1,a1,4 -2040003c: fec5e8e3 bltu a1,a2,2040002c <_start+0x2c> -20400040: 5fc00517 auipc a0,0x5fc00 -20400044: 3f050513 addi a0,a0,1008 # 80000430 <__bss_start> -20400048: 5fc00597 auipc a1,0x5fc00 -2040004c: 3f058593 addi a1,a1,1008 # 80000438 <_end> -20400050: 00b57863 bgeu a0,a1,20400060 <_start+0x60> -20400054: 00052023 sw zero,0(a0) -20400058: 00450513 addi a0,a0,4 -2040005c: feb56ce3 bltu a0,a1,20400054 <_start+0x54> -20400060: 00001517 auipc a0,0x1 -20400064: 4c450513 addi a0,a0,1220 # 20401524 <__libc_fini_array> -20400068: 470010ef jal ra,204014d8 -2040006c: 518010ef jal ra,20401584 <__libc_init_array> -20400070: 00000513 li a0,0 -20400074: 00000593 li a1,0 -20400078: 321000ef jal ra,20400b98
-2040007c: 4700106f j 204014ec - -Disassembly of section .text: - -20400080 : -20400080: dfc00797 auipc a5,0xdfc00 -20400084: f8078793 addi a5,a5,-128 # 0 <__stack_size-0x800> -20400088: 00078863 beqz a5,20400098 -2040008c: 00001517 auipc a0,0x1 -20400090: 49850513 addi a0,a0,1176 # 20401524 <__libc_fini_array> -20400094: 4440106f j 204014d8 -20400098: 00008067 ret - -2040009c : -2040009c: f8010113 addi sp,sp,-128 -204000a0: 00112223 sw ra,4(sp) -204000a4: 00212423 sw sp,8(sp) -204000a8: 00312623 sw gp,12(sp) -204000ac: 00412823 sw tp,16(sp) -204000b0: 00512a23 sw t0,20(sp) -204000b4: 00612c23 sw t1,24(sp) -204000b8: 00712e23 sw t2,28(sp) -204000bc: 02812023 sw s0,32(sp) -204000c0: 02912223 sw s1,36(sp) -204000c4: 02a12423 sw a0,40(sp) -204000c8: 02b12623 sw a1,44(sp) -204000cc: 02c12823 sw a2,48(sp) -204000d0: 02d12a23 sw a3,52(sp) -204000d4: 02e12c23 sw a4,56(sp) -204000d8: 02f12e23 sw a5,60(sp) -204000dc: 05012023 sw a6,64(sp) -204000e0: 05112223 sw a7,68(sp) -204000e4: 05212423 sw s2,72(sp) -204000e8: 05312623 sw s3,76(sp) -204000ec: 05412823 sw s4,80(sp) -204000f0: 05512a23 sw s5,84(sp) -204000f4: 05612c23 sw s6,88(sp) -204000f8: 05712e23 sw s7,92(sp) -204000fc: 07812023 sw s8,96(sp) -20400100: 07912223 sw s9,100(sp) -20400104: 07a12423 sw s10,104(sp) -20400108: 07b12623 sw s11,108(sp) -2040010c: 07c12823 sw t3,112(sp) -20400110: 07d12a23 sw t4,116(sp) -20400114: 07e12c23 sw t5,120(sp) -20400118: 07f12e23 sw t6,124(sp) -2040011c: 34202573 csrr a0,mcause -20400120: 341025f3 csrr a1,mepc -20400124: 00010613 mv a2,sp -20400128: 100010ef jal ra,20401228 -2040012c: 34151073 csrw mepc,a0 -20400130: 000022b7 lui t0,0x2 -20400134: 80028293 addi t0,t0,-2048 # 1800 <__stack_size+0x1000> -20400138: 3002a073 csrs mstatus,t0 -2040013c: 00412083 lw ra,4(sp) -20400140: 00812103 lw sp,8(sp) -20400144: 00c12183 lw gp,12(sp) -20400148: 01012203 lw tp,16(sp) -2040014c: 01412283 lw t0,20(sp) -20400150: 01812303 lw t1,24(sp) -20400154: 01c12383 lw t2,28(sp) -20400158: 02012403 lw s0,32(sp) -2040015c: 02412483 lw s1,36(sp) -20400160: 02812503 lw a0,40(sp) -20400164: 02c12583 lw a1,44(sp) -20400168: 03012603 lw a2,48(sp) -2040016c: 03412683 lw a3,52(sp) -20400170: 03812703 lw a4,56(sp) -20400174: 03c12783 lw a5,60(sp) -20400178: 04012803 lw a6,64(sp) -2040017c: 04412883 lw a7,68(sp) -20400180: 04812903 lw s2,72(sp) -20400184: 04c12983 lw s3,76(sp) -20400188: 05012a03 lw s4,80(sp) -2040018c: 05412a83 lw s5,84(sp) -20400190: 05812b03 lw s6,88(sp) -20400194: 05c12b83 lw s7,92(sp) -20400198: 06012c03 lw s8,96(sp) -2040019c: 06412c83 lw s9,100(sp) -204001a0: 06812d03 lw s10,104(sp) -204001a4: 06c12d83 lw s11,108(sp) -204001a8: 07012e03 lw t3,112(sp) -204001ac: 07412e83 lw t4,116(sp) -204001b0: 07812f03 lw t5,120(sp) -204001b4: 07c12f83 lw t6,124(sp) -204001b8: 08010113 addi sp,sp,128 -204001bc: 30200073 mret -204001c0: 0000006f j 204001c0 - -204001c4 : -204001c4: fe010113 addi sp,sp,-32 -204001c8: 00112e23 sw ra,28(sp) -204001cc: 00812c23 sw s0,24(sp) -204001d0: 02010413 addi s0,sp,32 -204001d4: fea42623 sw a0,-20(s0) -204001d8: fec40793 addi a5,s0,-20 -204001dc: 00100613 li a2,1 -204001e0: 00078593 mv a1,a5 -204001e4: 00100513 li a0,1 -204001e8: 14c010ef jal ra,20401334 <__wrap_write> -204001ec: 00050713 mv a4,a0 -204001f0: 00100793 li a5,1 -204001f4: 00f71663 bne a4,a5,20400200 -204001f8: fec42783 lw a5,-20(s0) -204001fc: 0080006f j 20400204 -20400200: fff00793 li a5,-1 -20400204: 00078513 mv a0,a5 -20400208: 01c12083 lw ra,28(sp) -2040020c: 01812403 lw s0,24(sp) -20400210: 02010113 addi sp,sp,32 -20400214: 00008067 ret - -20400218 : -20400218: fd010113 addi sp,sp,-48 -2040021c: 02812623 sw s0,44(sp) -20400220: 03010413 addi s0,sp,48 -20400224: fca42e23 sw a0,-36(s0) -20400228: fcb42c23 sw a1,-40(s0) -2040022c: fd842783 lw a5,-40(s0) -20400230: fef42623 sw a5,-20(s0) -20400234: fec42783 lw a5,-20(s0) -20400238: 0007a783 lw a5,0(a5) -2040023c: fdc42703 lw a4,-36(s0) -20400240: 0ff77713 andi a4,a4,255 -20400244: 00e78023 sb a4,0(a5) -20400248: fec42783 lw a5,-20(s0) -2040024c: 0007a783 lw a5,0(a5) -20400250: 00178713 addi a4,a5,1 -20400254: fec42783 lw a5,-20(s0) -20400258: 00e7a023 sw a4,0(a5) -2040025c: 00000013 nop -20400260: 02c12403 lw s0,44(sp) -20400264: 03010113 addi sp,sp,48 -20400268: 00008067 ret - -2040026c : -2040026c: fe010113 addi sp,sp,-32 -20400270: 00812e23 sw s0,28(sp) -20400274: 02010413 addi s0,sp,32 -20400278: fea42623 sw a0,-20(s0) -2040027c: feb42423 sw a1,-24(s0) -20400280: fe842783 lw a5,-24(s0) -20400284: 02078063 beqz a5,204002a4 -20400288: fec42783 lw a5,-20(s0) -2040028c: 0007a783 lw a5,0(a5) -20400290: 00478693 addi a3,a5,4 -20400294: fec42703 lw a4,-20(s0) -20400298: 00d72023 sw a3,0(a4) -2040029c: 0007a783 lw a5,0(a5) -204002a0: 01c0006f j 204002bc -204002a4: fec42783 lw a5,-20(s0) -204002a8: 0007a783 lw a5,0(a5) -204002ac: 00478693 addi a3,a5,4 -204002b0: fec42703 lw a4,-20(s0) -204002b4: 00d72023 sw a3,0(a4) -204002b8: 0007a783 lw a5,0(a5) -204002bc: 00078513 mv a0,a5 -204002c0: 01c12403 lw s0,28(sp) -204002c4: 02010113 addi sp,sp,32 -204002c8: 00008067 ret - -204002cc : -204002cc: fe010113 addi sp,sp,-32 -204002d0: 00812e23 sw s0,28(sp) -204002d4: 02010413 addi s0,sp,32 -204002d8: fea42623 sw a0,-20(s0) -204002dc: feb42423 sw a1,-24(s0) -204002e0: fe842783 lw a5,-24(s0) -204002e4: 02078063 beqz a5,20400304 -204002e8: fec42783 lw a5,-20(s0) -204002ec: 0007a783 lw a5,0(a5) -204002f0: 00478693 addi a3,a5,4 -204002f4: fec42703 lw a4,-20(s0) -204002f8: 00d72023 sw a3,0(a4) -204002fc: 0007a783 lw a5,0(a5) -20400300: 01c0006f j 2040031c -20400304: fec42783 lw a5,-20(s0) -20400308: 0007a783 lw a5,0(a5) -2040030c: 00478693 addi a3,a5,4 -20400310: fec42703 lw a4,-20(s0) -20400314: 00d72023 sw a3,0(a4) -20400318: 0007a783 lw a5,0(a5) -2040031c: 00078513 mv a0,a5 -20400320: 01c12403 lw s0,28(sp) -20400324: 02010113 addi sp,sp,32 -20400328: 00008067 ret - -2040032c : -2040032c: f4010113 addi sp,sp,-192 -20400330: 0a112e23 sw ra,188(sp) -20400334: 0a812c23 sw s0,184(sp) -20400338: 0a912a23 sw s1,180(sp) -2040033c: 0c010413 addi s0,sp,192 -20400340: f4a42e23 sw a0,-164(s0) -20400344: f4b42c23 sw a1,-168(s0) -20400348: f4c42a23 sw a2,-172(s0) -2040034c: f4d42823 sw a3,-176(s0) -20400350: f4e42623 sw a4,-180(s0) -20400354: f4f42423 sw a5,-184(s0) -20400358: fe042623 sw zero,-20(s0) -2040035c: fec42483 lw s1,-20(s0) -20400360: 00148793 addi a5,s1,1 -20400364: fef42623 sw a5,-20(s0) -20400368: f5442783 lw a5,-172(s0) -2040036c: f5042583 lw a1,-176(s0) -20400370: 00078513 mv a0,a5 -20400374: 409010ef jal ra,20401f7c <__umodsi3> -20400378: 00050793 mv a5,a0 -2040037c: 00078713 mv a4,a5 -20400380: 00249793 slli a5,s1,0x2 -20400384: ff040693 addi a3,s0,-16 -20400388: 00f687b3 add a5,a3,a5 -2040038c: f6e7ae23 sw a4,-132(a5) -20400390: f5442703 lw a4,-172(s0) -20400394: f5042783 lw a5,-176(s0) -20400398: 00f76e63 bltu a4,a5,204003b4 -2040039c: f5042583 lw a1,-176(s0) -204003a0: f5442503 lw a0,-172(s0) -204003a4: 391010ef jal ra,20401f34 <__udivsi3> -204003a8: 00050793 mv a5,a0 -204003ac: f4f42a23 sw a5,-172(s0) -204003b0: fadff06f j 2040035c -204003b4: 00000013 nop -204003b8: 0140006f j 204003cc -204003bc: f5c42783 lw a5,-164(s0) -204003c0: f5842583 lw a1,-168(s0) -204003c4: f4842503 lw a0,-184(s0) -204003c8: 000780e7 jalr a5 -204003cc: f4c42783 lw a5,-180(s0) -204003d0: fff78713 addi a4,a5,-1 -204003d4: f4e42623 sw a4,-180(s0) -204003d8: fec42703 lw a4,-20(s0) -204003dc: fef740e3 blt a4,a5,204003bc -204003e0: 0540006f j 20400434 -204003e4: fec42783 lw a5,-20(s0) -204003e8: 00279793 slli a5,a5,0x2 -204003ec: ff040713 addi a4,s0,-16 -204003f0: 00f707b3 add a5,a4,a5 -204003f4: f7c7a703 lw a4,-132(a5) -204003f8: fec42783 lw a5,-20(s0) -204003fc: 00279793 slli a5,a5,0x2 -20400400: ff040693 addi a3,s0,-16 -20400404: 00f687b3 add a5,a3,a5 -20400408: f7c7a683 lw a3,-132(a5) -2040040c: 00900793 li a5,9 -20400410: 00d7f663 bgeu a5,a3,2040041c -20400414: 05700793 li a5,87 -20400418: 0080006f j 20400420 -2040041c: 03000793 li a5,48 -20400420: 00e787b3 add a5,a5,a4 -20400424: f5c42703 lw a4,-164(s0) -20400428: f5842583 lw a1,-168(s0) -2040042c: 00078513 mv a0,a5 -20400430: 000700e7 jalr a4 -20400434: fec42783 lw a5,-20(s0) -20400438: fff78713 addi a4,a5,-1 -2040043c: fee42623 sw a4,-20(s0) -20400440: faf042e3 bgtz a5,204003e4 -20400444: 00000013 nop -20400448: 0bc12083 lw ra,188(sp) -2040044c: 0b812403 lw s0,184(sp) -20400450: 0b412483 lw s1,180(sp) -20400454: 0c010113 addi sp,sp,192 -20400458: 00008067 ret - -2040045c : -2040045c: f9010113 addi sp,sp,-112 -20400460: 06112623 sw ra,108(sp) -20400464: 06812423 sw s0,104(sp) -20400468: 07212223 sw s2,100(sp) -2040046c: 07312023 sw s3,96(sp) -20400470: 07010413 addi s0,sp,112 -20400474: faa42623 sw a0,-84(s0) -20400478: fab42423 sw a1,-88(s0) -2040047c: fac42023 sw a2,-96(s0) -20400480: fad42223 sw a3,-92(s0) -20400484: f8e42e23 sw a4,-100(s0) -20400488: f8f42c23 sw a5,-104(s0) -2040048c: fa042783 lw a5,-96(s0) -20400490: fa442803 lw a6,-92(s0) -20400494: fcf42c23 sw a5,-40(s0) -20400498: fd042e23 sw a6,-36(s0) -2040049c: fd842783 lw a5,-40(s0) -204004a0: fdc42803 lw a6,-36(s0) -204004a4: 00080793 mv a5,a6 -204004a8: 0207da63 bgez a5,204004dc -204004ac: fac42783 lw a5,-84(s0) -204004b0: fa842583 lw a1,-88(s0) -204004b4: 02d00513 li a0,45 -204004b8: 000780e7 jalr a5 -204004bc: fd842783 lw a5,-40(s0) -204004c0: fdc42803 lw a6,-36(s0) -204004c4: fff7f913 andi s2,a5,-1 -204004c8: 80000737 lui a4,0x80000 -204004cc: fff74713 not a4,a4 -204004d0: 00e879b3 and s3,a6,a4 -204004d4: fd242c23 sw s2,-40(s0) -204004d8: fd342e23 sw s3,-36(s0) -204004dc: fe042623 sw zero,-20(s0) -204004e0: 0400006f j 20400520 -204004e4: fd842783 lw a5,-40(s0) -204004e8: fdc42803 lw a6,-36(s0) -204004ec: 20402737 lui a4,0x20402 -204004f0: 19072603 lw a2,400(a4) # 20402190 <__clzsi2+0x1b0> -204004f4: 19472683 lw a3,404(a4) -204004f8: 00078513 mv a0,a5 -204004fc: 00080593 mv a1,a6 -20400500: 31c010ef jal ra,2040181c <__muldf3> -20400504: 00050793 mv a5,a0 -20400508: 00058813 mv a6,a1 -2040050c: fcf42c23 sw a5,-40(s0) -20400510: fd042e23 sw a6,-36(s0) -20400514: fec42783 lw a5,-20(s0) -20400518: 00178793 addi a5,a5,1 -2040051c: fef42623 sw a5,-20(s0) -20400520: fec42703 lw a4,-20(s0) -20400524: f9842783 lw a5,-104(s0) -20400528: faf74ee3 blt a4,a5,204004e4 -2040052c: fb840793 addi a5,s0,-72 -20400530: faf42a23 sw a5,-76(s0) -20400534: fd842783 lw a5,-40(s0) -20400538: fdc42803 lw a6,-36(s0) -2040053c: 00078513 mv a0,a5 -20400540: 00080593 mv a1,a6 -20400544: 149010ef jal ra,20401e8c <__fixunsdfsi> -20400548: 00050613 mv a2,a0 -2040054c: fb440593 addi a1,s0,-76 -20400550: 00000793 li a5,0 -20400554: 00000713 li a4,0 -20400558: 00a00693 li a3,10 -2040055c: 20400537 lui a0,0x20400 -20400560: 21850513 addi a0,a0,536 # 20400218 -20400564: dc9ff0ef jal ra,2040032c -20400568: f9842783 lw a5,-104(s0) -2040056c: 06f05863 blez a5,204005dc -20400570: fe042423 sw zero,-24(s0) -20400574: 0380006f j 204005ac -20400578: fb442703 lw a4,-76(s0) -2040057c: fe842783 lw a5,-24(s0) -20400580: fff7c793 not a5,a5 -20400584: 00f70733 add a4,a4,a5 -20400588: fb442783 lw a5,-76(s0) -2040058c: fe842683 lw a3,-24(s0) -20400590: 40d006b3 neg a3,a3 -20400594: 00d787b3 add a5,a5,a3 -20400598: 00074703 lbu a4,0(a4) -2040059c: 00e78023 sb a4,0(a5) -204005a0: fe842783 lw a5,-24(s0) -204005a4: 00178793 addi a5,a5,1 -204005a8: fef42423 sw a5,-24(s0) -204005ac: fe842703 lw a4,-24(s0) -204005b0: f9842783 lw a5,-104(s0) -204005b4: fcf742e3 blt a4,a5,20400578 -204005b8: fb442783 lw a5,-76(s0) -204005bc: f9842703 lw a4,-104(s0) -204005c0: 40e00733 neg a4,a4 -204005c4: 00e787b3 add a5,a5,a4 -204005c8: 02e00713 li a4,46 -204005cc: 00e78023 sb a4,0(a5) -204005d0: fb442783 lw a5,-76(s0) -204005d4: 00178793 addi a5,a5,1 -204005d8: faf42a23 sw a5,-76(s0) -204005dc: fb840793 addi a5,s0,-72 -204005e0: fef42223 sw a5,-28(s0) -204005e4: 0280006f j 2040060c -204005e8: fe442783 lw a5,-28(s0) -204005ec: 0007c783 lbu a5,0(a5) -204005f0: fac42703 lw a4,-84(s0) -204005f4: fa842583 lw a1,-88(s0) -204005f8: 00078513 mv a0,a5 -204005fc: 000700e7 jalr a4 -20400600: fe442783 lw a5,-28(s0) -20400604: 00178793 addi a5,a5,1 -20400608: fef42223 sw a5,-28(s0) -2040060c: fb442783 lw a5,-76(s0) -20400610: fe442703 lw a4,-28(s0) -20400614: fcf76ae3 bltu a4,a5,204005e8 -20400618: 00000013 nop -2040061c: 06c12083 lw ra,108(sp) -20400620: 06812403 lw s0,104(sp) -20400624: 06412903 lw s2,100(sp) -20400628: 06012983 lw s3,96(sp) -2040062c: 07010113 addi sp,sp,112 -20400630: 00008067 ret - -20400634 : -20400634: fc010113 addi sp,sp,-64 -20400638: 02112e23 sw ra,60(sp) -2040063c: 02812c23 sw s0,56(sp) -20400640: 02912a23 sw s1,52(sp) -20400644: 03212823 sw s2,48(sp) -20400648: 04010413 addi s0,sp,64 -2040064c: fca42623 sw a0,-52(s0) -20400650: fcb42423 sw a1,-56(s0) -20400654: fcc42223 sw a2,-60(s0) -20400658: fcd42023 sw a3,-64(s0) -2040065c: 0240006f j 20400680 -20400660: 3a048863 beqz s1,20400a10 -20400664: fc442783 lw a5,-60(s0) -20400668: 00178793 addi a5,a5,1 -2040066c: fcf42223 sw a5,-60(s0) -20400670: fcc42783 lw a5,-52(s0) -20400674: fc842583 lw a1,-56(s0) -20400678: 00048513 mv a0,s1 -2040067c: 000780e7 jalr a5 -20400680: fc442783 lw a5,-60(s0) -20400684: 0007c783 lbu a5,0(a5) -20400688: 00078493 mv s1,a5 -2040068c: 02500793 li a5,37 -20400690: fcf498e3 bne s1,a5,20400660 -20400694: fc442783 lw a5,-60(s0) -20400698: 00178793 addi a5,a5,1 -2040069c: fcf42223 sw a5,-60(s0) -204006a0: fc442783 lw a5,-60(s0) -204006a4: fcf42a23 sw a5,-44(s0) -204006a8: 02000793 li a5,32 -204006ac: fcf40da3 sb a5,-37(s0) -204006b0: fff00793 li a5,-1 -204006b4: fef42023 sw a5,-32(s0) -204006b8: fff00793 li a5,-1 -204006bc: fcf42e23 sw a5,-36(s0) -204006c0: fe042223 sw zero,-28(s0) -204006c4: fc042823 sw zero,-48(s0) -204006c8: fc442783 lw a5,-60(s0) -204006cc: 00178713 addi a4,a5,1 -204006d0: fce42223 sw a4,-60(s0) -204006d4: 0007c783 lbu a5,0(a5) -204006d8: 00078493 mv s1,a5 -204006dc: fdd48793 addi a5,s1,-35 -204006e0: 05500713 li a4,85 -204006e4: 30f76663 bltu a4,a5,204009f0 -204006e8: 00279713 slli a4,a5,0x2 -204006ec: 204027b7 lui a5,0x20402 -204006f0: 03878793 addi a5,a5,56 # 20402038 <__clzsi2+0x58> -204006f4: 00f707b3 add a5,a4,a5 -204006f8: 0007a783 lw a5,0(a5) -204006fc: 00078067 jr a5 -20400700: 02d00793 li a5,45 -20400704: fcf40da3 sb a5,-37(s0) -20400708: fc1ff06f j 204006c8 -2040070c: 03000793 li a5,48 -20400710: fcf40da3 sb a5,-37(s0) -20400714: fb5ff06f j 204006c8 -20400718: fc042e23 sw zero,-36(s0) -2040071c: fdc42703 lw a4,-36(s0) -20400720: 00070793 mv a5,a4 -20400724: 00279793 slli a5,a5,0x2 -20400728: 00e787b3 add a5,a5,a4 -2040072c: 00179793 slli a5,a5,0x1 -20400730: 00f487b3 add a5,s1,a5 -20400734: fd078793 addi a5,a5,-48 -20400738: fcf42e23 sw a5,-36(s0) -2040073c: fc442783 lw a5,-60(s0) -20400740: 0007c783 lbu a5,0(a5) -20400744: 00078493 mv s1,a5 -20400748: 02f00793 li a5,47 -2040074c: 0497d863 bge a5,s1,2040079c -20400750: 03900793 li a5,57 -20400754: 0497c463 blt a5,s1,2040079c -20400758: fc442783 lw a5,-60(s0) -2040075c: 00178793 addi a5,a5,1 -20400760: fcf42223 sw a5,-60(s0) -20400764: fb9ff06f j 2040071c -20400768: fc042783 lw a5,-64(s0) -2040076c: 00478713 addi a4,a5,4 -20400770: fce42023 sw a4,-64(s0) -20400774: 0007a783 lw a5,0(a5) -20400778: fcf42e23 sw a5,-36(s0) -2040077c: 0240006f j 204007a0 -20400780: fe042783 lw a5,-32(s0) -20400784: f407d2e3 bgez a5,204006c8 -20400788: fe042023 sw zero,-32(s0) -2040078c: f3dff06f j 204006c8 -20400790: 00100793 li a5,1 -20400794: fcf42823 sw a5,-48(s0) -20400798: f31ff06f j 204006c8 -2040079c: 00000013 nop -204007a0: fe042783 lw a5,-32(s0) -204007a4: f207d2e3 bgez a5,204006c8 -204007a8: fdc42783 lw a5,-36(s0) -204007ac: fef42023 sw a5,-32(s0) -204007b0: fff00793 li a5,-1 -204007b4: fcf42e23 sw a5,-36(s0) -204007b8: f11ff06f j 204006c8 -204007bc: fe442783 lw a5,-28(s0) -204007c0: 22079663 bnez a5,204009ec -204007c4: f05ff06f j 204006c8 -204007c8: fc042783 lw a5,-64(s0) -204007cc: 00478713 addi a4,a5,4 -204007d0: fce42023 sw a4,-64(s0) -204007d4: 0007a783 lw a5,0(a5) -204007d8: fcc42703 lw a4,-52(s0) -204007dc: fc842583 lw a1,-56(s0) -204007e0: 00078513 mv a0,a5 -204007e4: 000700e7 jalr a4 -204007e8: 2240006f j 20400a0c -204007ec: fc042783 lw a5,-64(s0) -204007f0: 00778793 addi a5,a5,7 -204007f4: ff87f793 andi a5,a5,-8 -204007f8: 00878713 addi a4,a5,8 -204007fc: fce42023 sw a4,-64(s0) -20400800: 0007a603 lw a2,0(a5) -20400804: 0047a683 lw a3,4(a5) -20400808: fdc42783 lw a5,-36(s0) -2040080c: fe042703 lw a4,-32(s0) -20400810: fc842583 lw a1,-56(s0) -20400814: fcc42503 lw a0,-52(s0) -20400818: c45ff0ef jal ra,2040045c -2040081c: 1f00006f j 20400a0c -20400820: fc042783 lw a5,-64(s0) -20400824: 00478713 addi a4,a5,4 -20400828: fce42023 sw a4,-64(s0) -2040082c: 0007a903 lw s2,0(a5) -20400830: 00091663 bnez s2,2040083c -20400834: 204027b7 lui a5,0x20402 -20400838: 03078913 addi s2,a5,48 # 20402030 <__clzsi2+0x50> -2040083c: fe042783 lw a5,-32(s0) -20400840: 08f05063 blez a5,204008c0 -20400844: fdb44703 lbu a4,-37(s0) -20400848: 02d00793 li a5,45 -2040084c: 06f70a63 beq a4,a5,204008c0 -20400850: fdc42783 lw a5,-36(s0) -20400854: 00078593 mv a1,a5 -20400858: 00090513 mv a0,s2 -2040085c: 5bd000ef jal ra,20401618 -20400860: 00050713 mv a4,a0 -20400864: fe042783 lw a5,-32(s0) -20400868: 40e787b3 sub a5,a5,a4 -2040086c: fef42023 sw a5,-32(s0) -20400870: 0240006f j 20400894 -20400874: fdb44783 lbu a5,-37(s0) -20400878: fcc42703 lw a4,-52(s0) -2040087c: fc842583 lw a1,-56(s0) -20400880: 00078513 mv a0,a5 -20400884: 000700e7 jalr a4 -20400888: fe042783 lw a5,-32(s0) -2040088c: fff78793 addi a5,a5,-1 -20400890: fef42023 sw a5,-32(s0) -20400894: fe042783 lw a5,-32(s0) -20400898: fcf04ee3 bgtz a5,20400874 -2040089c: 0240006f j 204008c0 -204008a0: fcc42783 lw a5,-52(s0) -204008a4: fc842583 lw a1,-56(s0) -204008a8: 00048513 mv a0,s1 -204008ac: 000780e7 jalr a5 -204008b0: 00190913 addi s2,s2,1 -204008b4: fe042783 lw a5,-32(s0) -204008b8: fff78793 addi a5,a5,-1 -204008bc: fef42023 sw a5,-32(s0) -204008c0: 00094783 lbu a5,0(s2) -204008c4: 00078493 mv s1,a5 -204008c8: 04048063 beqz s1,20400908 -204008cc: fdc42783 lw a5,-36(s0) -204008d0: fc07c8e3 bltz a5,204008a0 -204008d4: fdc42783 lw a5,-36(s0) -204008d8: fff78793 addi a5,a5,-1 -204008dc: fcf42e23 sw a5,-36(s0) -204008e0: fdc42783 lw a5,-36(s0) -204008e4: fa07dee3 bgez a5,204008a0 -204008e8: 0200006f j 20400908 -204008ec: fcc42783 lw a5,-52(s0) -204008f0: fc842583 lw a1,-56(s0) -204008f4: 02000513 li a0,32 -204008f8: 000780e7 jalr a5 -204008fc: fe042783 lw a5,-32(s0) -20400900: fff78793 addi a5,a5,-1 -20400904: fef42023 sw a5,-32(s0) -20400908: fe042783 lw a5,-32(s0) -2040090c: fef040e3 bgtz a5,204008ec -20400910: 0fc0006f j 20400a0c -20400914: fc040793 addi a5,s0,-64 -20400918: fe442583 lw a1,-28(s0) -2040091c: 00078513 mv a0,a5 -20400920: 9adff0ef jal ra,204002cc -20400924: 00050793 mv a5,a0 -20400928: fef42623 sw a5,-20(s0) -2040092c: fec42783 lw a5,-20(s0) -20400930: 0207d063 bgez a5,20400950 -20400934: fcc42783 lw a5,-52(s0) -20400938: fc842583 lw a1,-56(s0) -2040093c: 02d00513 li a0,45 -20400940: 000780e7 jalr a5 -20400944: fec42783 lw a5,-20(s0) -20400948: 40f007b3 neg a5,a5 -2040094c: fef42623 sw a5,-20(s0) -20400950: 00a00793 li a5,10 -20400954: fef42423 sw a5,-24(s0) -20400958: 0600006f j 204009b8 -2040095c: 00a00793 li a5,10 -20400960: fef42423 sw a5,-24(s0) -20400964: 0400006f j 204009a4 -20400968: 00800793 li a5,8 -2040096c: fef42423 sw a5,-24(s0) -20400970: 0340006f j 204009a4 -20400974: 00100793 li a5,1 -20400978: fef42223 sw a5,-28(s0) -2040097c: fcc42783 lw a5,-52(s0) -20400980: fc842583 lw a1,-56(s0) -20400984: 03000513 li a0,48 -20400988: 000780e7 jalr a5 -2040098c: fcc42783 lw a5,-52(s0) -20400990: fc842583 lw a1,-56(s0) -20400994: 07800513 li a0,120 -20400998: 000780e7 jalr a5 -2040099c: 01000793 li a5,16 -204009a0: fef42423 sw a5,-24(s0) -204009a4: fc040793 addi a5,s0,-64 -204009a8: fe442583 lw a1,-28(s0) -204009ac: 00078513 mv a0,a5 -204009b0: 8bdff0ef jal ra,2040026c -204009b4: fea42623 sw a0,-20(s0) -204009b8: fe842683 lw a3,-24(s0) -204009bc: fdb44783 lbu a5,-37(s0) -204009c0: fe042703 lw a4,-32(s0) -204009c4: fec42603 lw a2,-20(s0) -204009c8: fc842583 lw a1,-56(s0) -204009cc: fcc42503 lw a0,-52(s0) -204009d0: 95dff0ef jal ra,2040032c -204009d4: 0380006f j 20400a0c -204009d8: fcc42783 lw a5,-52(s0) -204009dc: fc842583 lw a1,-56(s0) -204009e0: 00048513 mv a0,s1 -204009e4: 000780e7 jalr a5 -204009e8: 0240006f j 20400a0c -204009ec: 00000013 nop -204009f0: fcc42783 lw a5,-52(s0) -204009f4: fc842583 lw a1,-56(s0) -204009f8: 02500513 li a0,37 -204009fc: 000780e7 jalr a5 -20400a00: fd442783 lw a5,-44(s0) -20400a04: fcf42223 sw a5,-60(s0) -20400a08: 00000013 nop -20400a0c: c75ff06f j 20400680 -20400a10: 00000013 nop -20400a14: 03c12083 lw ra,60(sp) -20400a18: 03812403 lw s0,56(sp) -20400a1c: 03412483 lw s1,52(sp) -20400a20: 03012903 lw s2,48(sp) -20400a24: 04010113 addi sp,sp,64 -20400a28: 00008067 ret - -20400a2c <__wrap_printf>: -20400a2c: fb010113 addi sp,sp,-80 -20400a30: 02112623 sw ra,44(sp) -20400a34: 02812423 sw s0,40(sp) -20400a38: 03010413 addi s0,sp,48 -20400a3c: fca42e23 sw a0,-36(s0) -20400a40: 00b42223 sw a1,4(s0) -20400a44: 00c42423 sw a2,8(s0) -20400a48: 00d42623 sw a3,12(s0) -20400a4c: 00e42823 sw a4,16(s0) -20400a50: 00f42a23 sw a5,20(s0) -20400a54: 01042c23 sw a6,24(s0) -20400a58: 01142e23 sw a7,28(s0) -20400a5c: 02040793 addi a5,s0,32 -20400a60: fe478793 addi a5,a5,-28 -20400a64: fef42623 sw a5,-20(s0) -20400a68: fec42783 lw a5,-20(s0) -20400a6c: 00078693 mv a3,a5 -20400a70: fdc42603 lw a2,-36(s0) -20400a74: 00000593 li a1,0 -20400a78: 204007b7 lui a5,0x20400 -20400a7c: 1c478513 addi a0,a5,452 # 204001c4 -20400a80: bb5ff0ef jal ra,20400634 -20400a84: 00000793 li a5,0 -20400a88: 00078513 mv a0,a5 -20400a8c: 02c12083 lw ra,44(sp) -20400a90: 02812403 lw s0,40(sp) -20400a94: 05010113 addi sp,sp,80 -20400a98: 00008067 ret - -20400a9c <__wrap_sprintf>: -20400a9c: fb010113 addi sp,sp,-80 -20400aa0: 02112623 sw ra,44(sp) -20400aa4: 02812423 sw s0,40(sp) -20400aa8: 03010413 addi s0,sp,48 -20400aac: fca42e23 sw a0,-36(s0) -20400ab0: fcb42c23 sw a1,-40(s0) -20400ab4: 00c42423 sw a2,8(s0) -20400ab8: 00d42623 sw a3,12(s0) -20400abc: 00e42823 sw a4,16(s0) -20400ac0: 00f42a23 sw a5,20(s0) -20400ac4: 01042c23 sw a6,24(s0) -20400ac8: 01142e23 sw a7,28(s0) -20400acc: fdc42783 lw a5,-36(s0) -20400ad0: fef42623 sw a5,-20(s0) -20400ad4: 02040793 addi a5,s0,32 -20400ad8: fe878793 addi a5,a5,-24 -20400adc: fef42423 sw a5,-24(s0) -20400ae0: fe842703 lw a4,-24(s0) -20400ae4: fdc40793 addi a5,s0,-36 -20400ae8: 00070693 mv a3,a4 -20400aec: fd842603 lw a2,-40(s0) -20400af0: 00078593 mv a1,a5 -20400af4: 204007b7 lui a5,0x20400 -20400af8: 21878513 addi a0,a5,536 # 20400218 -20400afc: b39ff0ef jal ra,20400634 -20400b00: fdc42783 lw a5,-36(s0) -20400b04: 00078023 sb zero,0(a5) -20400b08: fdc42703 lw a4,-36(s0) -20400b0c: fec42783 lw a5,-20(s0) -20400b10: 40f707b3 sub a5,a4,a5 -20400b14: 00078513 mv a0,a5 -20400b18: 02c12083 lw ra,44(sp) -20400b1c: 02812403 lw s0,40(sp) -20400b20: 05010113 addi sp,sp,80 -20400b24: 00008067 ret - -20400b28 : -20400b28: fd010113 addi sp,sp,-48 -20400b2c: 02112623 sw ra,44(sp) -20400b30: 02812423 sw s0,40(sp) -20400b34: 03010413 addi s0,sp,48 -20400b38: fca42e23 sw a0,-36(s0) -20400b3c: 00100793 li a5,1 -20400b40: fef42423 sw a5,-24(s0) -20400b44: 00100793 li a5,1 -20400b48: fef42623 sw a5,-20(s0) -20400b4c: 0280006f j 20400b74 -20400b50: fe842783 lw a5,-24(s0) -20400b54: fec42583 lw a1,-20(s0) -20400b58: 00078513 mv a0,a5 -20400b5c: 3ac010ef jal ra,20401f08 <__mulsi3> -20400b60: 00050793 mv a5,a0 -20400b64: fef42423 sw a5,-24(s0) -20400b68: fec42783 lw a5,-20(s0) -20400b6c: 00178793 addi a5,a5,1 -20400b70: fef42623 sw a5,-20(s0) -20400b74: fec42703 lw a4,-20(s0) -20400b78: fdc42783 lw a5,-36(s0) -20400b7c: fce7dae3 bge a5,a4,20400b50 -20400b80: fe842783 lw a5,-24(s0) -20400b84: 00078513 mv a0,a5 -20400b88: 02c12083 lw ra,44(sp) -20400b8c: 02812403 lw s0,40(sp) -20400b90: 03010113 addi sp,sp,48 -20400b94: 00008067 ret - -20400b98
: -20400b98: fc010113 addi sp,sp,-64 -20400b9c: 02112e23 sw ra,60(sp) -20400ba0: 02812c23 sw s0,56(sp) -20400ba4: 04010413 addi s0,sp,64 -20400ba8: 100127b7 lui a5,0x10012 -20400bac: 03878793 addi a5,a5,56 # 10012038 <__stack_size+0x10011838> -20400bb0: 0007a683 lw a3,0(a5) -20400bb4: 100127b7 lui a5,0x10012 -20400bb8: 03878793 addi a5,a5,56 # 10012038 <__stack_size+0x10011838> -20400bbc: 00030737 lui a4,0x30 -20400bc0: 00e6e733 or a4,a3,a4 -20400bc4: 00e7a023 sw a4,0(a5) -20400bc8: f14027f3 csrr a5,mhartid -20400bcc: fef42623 sw a5,-20(s0) -20400bd0: fec42783 lw a5,-20(s0) -20400bd4: fef42423 sw a5,-24(s0) -20400bd8: 900007b7 lui a5,0x90000 -20400bdc: fef42223 sw a5,-28(s0) -20400be0: 800007b7 lui a5,0x80000 -20400be4: fef42023 sw a5,-32(s0) -20400be8: fe842783 lw a5,-24(s0) -20400bec: 04079663 bnez a5,20400c38 -20400bf0: 00500793 li a5,5 -20400bf4: fcf42e23 sw a5,-36(s0) -20400bf8: 00a00793 li a5,10 -20400bfc: fcf42c23 sw a5,-40(s0) -20400c00: fe442783 lw a5,-28(s0) -20400c04: fdc42703 lw a4,-36(s0) -20400c08: 00e7a023 sw a4,0(a5) # 80000000 <_sp+0xffffc000> -20400c0c: fe442783 lw a5,-28(s0) -20400c10: 00478793 addi a5,a5,4 -20400c14: 00078713 mv a4,a5 -20400c18: fd842783 lw a5,-40(s0) -20400c1c: 00f72023 sw a5,0(a4) # 30000 <__stack_size+0x2f800> -20400c20: fd842683 lw a3,-40(s0) -20400c24: fdc42603 lw a2,-36(s0) -20400c28: fe842583 lw a1,-24(s0) -20400c2c: 204027b7 lui a5,0x20402 -20400c30: 19878513 addi a0,a5,408 # 20402198 <__clzsi2+0x1b8> -20400c34: df9ff0ef jal ra,20400a2c <__wrap_printf> -20400c38: 00a00513 li a0,10 -20400c3c: eedff0ef jal ra,20400b28 -20400c40: fca42a23 sw a0,-44(s0) -20400c44: fd442603 lw a2,-44(s0) -20400c48: fe842583 lw a1,-24(s0) -20400c4c: 204027b7 lui a5,0x20402 -20400c50: 1dc78513 addi a0,a5,476 # 204021dc <__clzsi2+0x1fc> -20400c54: dd9ff0ef jal ra,20400a2c <__wrap_printf> -20400c58: fe842703 lw a4,-24(s0) -20400c5c: 00100793 li a5,1 -20400c60: 06f71863 bne a4,a5,20400cd0 -20400c64: fe042783 lw a5,-32(s0) -20400c68: 0007a783 lw a5,0(a5) -20400c6c: fcf42823 sw a5,-48(s0) -20400c70: fe042783 lw a5,-32(s0) -20400c74: 00478793 addi a5,a5,4 -20400c78: 0007a783 lw a5,0(a5) -20400c7c: fcf42623 sw a5,-52(s0) -20400c80: fd042703 lw a4,-48(s0) -20400c84: fcc42783 lw a5,-52(s0) -20400c88: 00f707b3 add a5,a4,a5 -20400c8c: fcf42423 sw a5,-56(s0) -20400c90: fc842703 lw a4,-56(s0) -20400c94: 00f00793 li a5,15 -20400c98: 00f71e63 bne a4,a5,20400cb4 -20400c9c: fc842603 lw a2,-56(s0) -20400ca0: fe842583 lw a1,-24(s0) -20400ca4: 204027b7 lui a5,0x20402 -20400ca8: 22078513 addi a0,a5,544 # 20402220 <__clzsi2+0x240> -20400cac: d81ff0ef jal ra,20400a2c <__wrap_printf> -20400cb0: 0200006f j 20400cd0 -20400cb4: fc842603 lw a2,-56(s0) -20400cb8: fe842583 lw a1,-24(s0) -20400cbc: 204027b7 lui a5,0x20402 -20400cc0: 24478513 addi a0,a5,580 # 20402244 <__clzsi2+0x264> -20400cc4: d69ff0ef jal ra,20400a2c <__wrap_printf> -20400cc8: 00100793 li a5,1 -20400ccc: 0140006f j 20400ce0 -20400cd0: 204027b7 lui a5,0x20402 -20400cd4: 28078513 addi a0,a5,640 # 20402280 <__clzsi2+0x2a0> -20400cd8: d55ff0ef jal ra,20400a2c <__wrap_printf> -20400cdc: 00000793 li a5,0 -20400ce0: 00078513 mv a0,a5 -20400ce4: 03c12083 lw ra,60(sp) -20400ce8: 03812403 lw s0,56(sp) -20400cec: 04010113 addi sp,sp,64 -20400cf0: 00008067 ret - -20400cf4 : -20400cf4: ff010113 addi sp,sp,-16 -20400cf8: 00812623 sw s0,12(sp) -20400cfc: 01010413 addi s0,sp,16 -20400d00: 0200c7b7 lui a5,0x200c -20400d04: ff878793 addi a5,a5,-8 # 200bff8 <__stack_size+0x200b7f8> -20400d08: 0007a783 lw a5,0(a5) -20400d0c: 00078513 mv a0,a5 -20400d10: 00c12403 lw s0,12(sp) -20400d14: 01010113 addi sp,sp,16 -20400d18: 00008067 ret - -20400d1c : -20400d1c: ff010113 addi sp,sp,-16 -20400d20: 00112623 sw ra,12(sp) -20400d24: 00812423 sw s0,8(sp) -20400d28: 01212223 sw s2,4(sp) -20400d2c: 01312023 sw s3,0(sp) -20400d30: 01010413 addi s0,sp,16 -20400d34: fc1ff0ef jal ra,20400cf4 -20400d38: 00050793 mv a5,a0 -20400d3c: 00078913 mv s2,a5 -20400d40: 00000993 li s3,0 -20400d44: 00090793 mv a5,s2 -20400d48: 00098813 mv a6,s3 -20400d4c: 00078513 mv a0,a5 -20400d50: 00080593 mv a1,a6 -20400d54: 00c12083 lw ra,12(sp) -20400d58: 00812403 lw s0,8(sp) -20400d5c: 00412903 lw s2,4(sp) -20400d60: 00012983 lw s3,0(sp) -20400d64: 01010113 addi sp,sp,16 -20400d68: 00008067 ret - -20400d6c : -20400d6c: ff010113 addi sp,sp,-16 -20400d70: 00812623 sw s0,12(sp) -20400d74: 01010413 addi s0,sp,16 -20400d78: 000087b7 lui a5,0x8 -20400d7c: 00078513 mv a0,a5 -20400d80: 00c12403 lw s0,12(sp) -20400d84: 01010113 addi sp,sp,16 -20400d88: 00008067 ret - -20400d8c : -20400d8c: fe010113 addi sp,sp,-32 -20400d90: 00812e23 sw s0,28(sp) -20400d94: 02010413 addi s0,sp,32 -20400d98: fea42623 sw a0,-20(s0) -20400d9c: feb42423 sw a1,-24(s0) -20400da0: fec42783 lw a5,-20(s0) -20400da4: 02f7f713 andi a4,a5,47 -20400da8: fe842783 lw a5,-24(s0) -20400dac: 01079693 slli a3,a5,0x10 -20400db0: 001f07b7 lui a5,0x1f0 -20400db4: 00f6f7b3 and a5,a3,a5 -20400db8: 00f76733 or a4,a4,a5 -20400dbc: 400007b7 lui a5,0x40000 -20400dc0: 00f76733 or a4,a4,a5 -20400dc4: 100087b7 lui a5,0x10008 -20400dc8: 00e7a023 sw a4,0(a5) # 10008000 <__stack_size+0x10007800> -20400dcc: 00000013 nop -20400dd0: 100087b7 lui a5,0x10008 -20400dd4: 0007a783 lw a5,0(a5) # 10008000 <__stack_size+0x10007800> -20400dd8: fe07dce3 bgez a5,20400dd0 -20400ddc: 100087b7 lui a5,0x10008 -20400de0: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400de4: 0007a683 lw a3,0(a5) -20400de8: 100087b7 lui a5,0x10008 -20400dec: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400df0: ffff0737 lui a4,0xffff0 -20400df4: fff70713 addi a4,a4,-1 # fffeffff <_sp+0x7ffebfff> -20400df8: 00e6f733 and a4,a3,a4 -20400dfc: 00e7a023 sw a4,0(a5) -20400e00: 00000013 nop -20400e04: 01c12403 lw s0,28(sp) -20400e08: 02010113 addi sp,sp,32 -20400e0c: 00008067 ret - -20400e10 : -20400e10: fc010113 addi sp,sp,-64 -20400e14: 02112e23 sw ra,60(sp) -20400e18: 02812c23 sw s0,56(sp) -20400e1c: 04010413 addi s0,sp,64 -20400e20: fca42e23 sw a0,-36(s0) -20400e24: fcb42c23 sw a1,-40(s0) -20400e28: fcc42a23 sw a2,-44(s0) -20400e2c: fcd42823 sw a3,-48(s0) -20400e30: fce42623 sw a4,-52(s0) -20400e34: 100087b7 lui a5,0x10008 -20400e38: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400e3c: 0007a703 lw a4,0(a5) -20400e40: 000107b7 lui a5,0x10 -20400e44: 00f777b3 and a5,a4,a5 -20400e48: 00078863 beqz a5,20400e58 -20400e4c: 01000593 li a1,16 -20400e50: 00400513 li a0,4 -20400e54: f39ff0ef jal ra,20400d8c -20400e58: fe042623 sw zero,-20(s0) -20400e5c: fdc42783 lw a5,-36(s0) -20400e60: 01179793 slli a5,a5,0x11 -20400e64: 00078713 mv a4,a5 -20400e68: 000207b7 lui a5,0x20 -20400e6c: 00f777b3 and a5,a4,a5 -20400e70: fec42703 lw a4,-20(s0) -20400e74: 00f767b3 or a5,a4,a5 -20400e78: fef42623 sw a5,-20(s0) -20400e7c: fd842783 lw a5,-40(s0) -20400e80: 02078c63 beqz a5,20400eb8 -20400e84: fec42703 lw a4,-20(s0) -20400e88: 000407b7 lui a5,0x40 -20400e8c: 00f767b3 or a5,a4,a5 -20400e90: fef42623 sw a5,-20(s0) -20400e94: 100087b7 lui a5,0x10008 -20400e98: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400e9c: fec42703 lw a4,-20(s0) -20400ea0: 00e7a023 sw a4,0(a5) -20400ea4: 100087b7 lui a5,0x10008 -20400ea8: 00c78793 addi a5,a5,12 # 1000800c <__stack_size+0x1000780c> -20400eac: 10000713 li a4,256 -20400eb0: 00e7a023 sw a4,0(a5) -20400eb4: 0ec0006f j 20400fa0 -20400eb8: 100147b7 lui a5,0x10014 -20400ebc: 00800713 li a4,8 -20400ec0: 00e7a023 sw a4,0(a5) # 10014000 <__stack_size+0x10013800> -20400ec4: fec42703 lw a4,-20(s0) -20400ec8: 000407b7 lui a5,0x40 -20400ecc: 00f767b3 or a5,a4,a5 -20400ed0: fef42623 sw a5,-20(s0) -20400ed4: fd442783 lw a5,-44(s0) -20400ed8: 0077f793 andi a5,a5,7 -20400edc: fec42703 lw a4,-20(s0) -20400ee0: 00f767b3 or a5,a4,a5 -20400ee4: fef42623 sw a5,-20(s0) -20400ee8: fd042783 lw a5,-48(s0) -20400eec: 00479793 slli a5,a5,0x4 -20400ef0: 3f07f793 andi a5,a5,1008 -20400ef4: fec42703 lw a4,-20(s0) -20400ef8: 00f767b3 or a5,a4,a5 -20400efc: fef42623 sw a5,-20(s0) -20400f00: fcc42783 lw a5,-52(s0) -20400f04: 00a79793 slli a5,a5,0xa -20400f08: 00078713 mv a4,a5 -20400f0c: 000017b7 lui a5,0x1 -20400f10: c0078793 addi a5,a5,-1024 # c00 <__stack_size+0x400> -20400f14: 00f777b3 and a5,a4,a5 -20400f18: fec42703 lw a4,-20(s0) -20400f1c: 00f767b3 or a5,a4,a5 -20400f20: fef42623 sw a5,-20(s0) -20400f24: 100087b7 lui a5,0x10008 -20400f28: 00c78793 addi a5,a5,12 # 1000800c <__stack_size+0x1000780c> -20400f2c: 10000713 li a4,256 -20400f30: 00e7a023 sw a4,0(a5) -20400f34: 100087b7 lui a5,0x10008 -20400f38: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400f3c: fec42703 lw a4,-20(s0) -20400f40: 00e7a023 sw a4,0(a5) -20400f44: 100087b7 lui a5,0x10008 -20400f48: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400f4c: 0007a683 lw a3,0(a5) -20400f50: 100087b7 lui a5,0x10008 -20400f54: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400f58: fffc0737 lui a4,0xfffc0 -20400f5c: fff70713 addi a4,a4,-1 # fffbffff <_sp+0x7ffbbfff> -20400f60: 00e6f733 and a4,a3,a4 -20400f64: 00e7a023 sw a4,0(a5) -20400f68: d8dff0ef jal ra,20400cf4 -20400f6c: fea42423 sw a0,-24(s0) -20400f70: 00000013 nop -20400f74: d81ff0ef jal ra,20400cf4 -20400f78: 00050713 mv a4,a0 -20400f7c: fe842783 lw a5,-24(s0) -20400f80: 40f70733 sub a4,a4,a5 -20400f84: 00300793 li a5,3 -20400f88: fee7f6e3 bgeu a5,a4,20400f74 -20400f8c: 00000013 nop -20400f90: 100087b7 lui a5,0x10008 -20400f94: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400f98: 0007a783 lw a5,0(a5) -20400f9c: fe07dae3 bgez a5,20400f90 -20400fa0: 100087b7 lui a5,0x10008 -20400fa4: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400fa8: 0007a683 lw a3,0(a5) -20400fac: 100087b7 lui a5,0x10008 -20400fb0: 00878793 addi a5,a5,8 # 10008008 <__stack_size+0x10007808> -20400fb4: 00010737 lui a4,0x10 -20400fb8: 00e6e733 or a4,a3,a4 -20400fbc: 00e7a023 sw a4,0(a5) -20400fc0: 00000013 nop -20400fc4: 03c12083 lw ra,60(sp) -20400fc8: 03812403 lw s0,56(sp) -20400fcc: 04010113 addi sp,sp,64 -20400fd0: 00008067 ret - -20400fd4 : -20400fd4: ff010113 addi sp,sp,-16 -20400fd8: 00112623 sw ra,12(sp) -20400fdc: 00812423 sw s0,8(sp) -20400fe0: 01010413 addi s0,sp,16 -20400fe4: 100007b7 lui a5,0x10000 -20400fe8: 07078793 addi a5,a5,112 # 10000070 <__stack_size+0xffff870> -20400fec: 0007a683 lw a3,0(a5) -20400ff0: 100007b7 lui a5,0x10000 -20400ff4: 07078793 addi a5,a5,112 # 10000070 <__stack_size+0xffff870> -20400ff8: c0000737 lui a4,0xc0000 -20400ffc: fff70713 addi a4,a4,-1 # bfffffff <_sp+0x3fffbfff> -20401000: 00e6f733 and a4,a3,a4 -20401004: 00e7a023 sw a4,0(a5) -20401008: 01000593 li a1,16 -2040100c: 00400513 li a0,4 -20401010: d7dff0ef jal ra,20400d8c -20401014: 00000013 nop -20401018: 00c12083 lw ra,12(sp) -2040101c: 00812403 lw s0,8(sp) -20401020: 01010113 addi sp,sp,16 -20401024: 00008067 ret - -20401028 : -20401028: fc010113 addi sp,sp,-64 -2040102c: 02112e23 sw ra,60(sp) -20401030: 02812c23 sw s0,56(sp) -20401034: 02912a23 sw s1,52(sp) -20401038: 04010413 addi s0,sp,64 -2040103c: fca42623 sw a0,-52(s0) -20401040: d2dff0ef jal ra,20400d6c -20401044: fea42623 sw a0,-20(s0) -20401048: cadff0ef jal ra,20400cf4 -2040104c: fea42423 sw a0,-24(s0) -20401050: ca5ff0ef jal ra,20400cf4 -20401054: fea42223 sw a0,-28(s0) -20401058: fe442703 lw a4,-28(s0) -2040105c: fe842783 lw a5,-24(s0) -20401060: fef708e3 beq a4,a5,20401050 -20401064: b00027f3 csrr a5,mcycle -20401068: fef42023 sw a5,-32(s0) -2040106c: fe042783 lw a5,-32(s0) -20401070: fcf42e23 sw a5,-36(s0) -20401074: c81ff0ef jal ra,20400cf4 -20401078: 00050713 mv a4,a0 -2040107c: fe442783 lw a5,-28(s0) -20401080: 40f707b3 sub a5,a4,a5 -20401084: fcf42c23 sw a5,-40(s0) -20401088: fd842703 lw a4,-40(s0) -2040108c: fcc42783 lw a5,-52(s0) -20401090: fef762e3 bltu a4,a5,20401074 -20401094: b00027f3 csrr a5,mcycle -20401098: fcf42a23 sw a5,-44(s0) -2040109c: fd442703 lw a4,-44(s0) -204010a0: fdc42783 lw a5,-36(s0) -204010a4: 40f707b3 sub a5,a4,a5 -204010a8: fcf42823 sw a5,-48(s0) -204010ac: fd842583 lw a1,-40(s0) -204010b0: fd042503 lw a0,-48(s0) -204010b4: 681000ef jal ra,20401f34 <__udivsi3> -204010b8: 00050793 mv a5,a0 -204010bc: fec42583 lw a1,-20(s0) -204010c0: 00078513 mv a0,a5 -204010c4: 645000ef jal ra,20401f08 <__mulsi3> -204010c8: 00050793 mv a5,a0 -204010cc: 00078493 mv s1,a5 -204010d0: fd042783 lw a5,-48(s0) -204010d4: fd842583 lw a1,-40(s0) -204010d8: 00078513 mv a0,a5 -204010dc: 6a1000ef jal ra,20401f7c <__umodsi3> -204010e0: 00050793 mv a5,a0 -204010e4: fec42583 lw a1,-20(s0) -204010e8: 00078513 mv a0,a5 -204010ec: 61d000ef jal ra,20401f08 <__mulsi3> -204010f0: 00050793 mv a5,a0 -204010f4: fd842583 lw a1,-40(s0) -204010f8: 00078513 mv a0,a5 -204010fc: 639000ef jal ra,20401f34 <__udivsi3> -20401100: 00050793 mv a5,a0 -20401104: 00f487b3 add a5,s1,a5 -20401108: 00078513 mv a0,a5 -2040110c: 03c12083 lw ra,60(sp) -20401110: 03812403 lw s0,56(sp) -20401114: 03412483 lw s1,52(sp) -20401118: 04010113 addi sp,sp,64 -2040111c: 00008067 ret - -20401120 : -20401120: ff010113 addi sp,sp,-16 -20401124: 00112623 sw ra,12(sp) -20401128: 00812423 sw s0,8(sp) -2040112c: 01010413 addi s0,sp,16 -20401130: 800007b7 lui a5,0x80000 -20401134: 4307a783 lw a5,1072(a5) # 80000430 <_sp+0xffffc430> -20401138: 02079063 bnez a5,20401158 -2040113c: 00100513 li a0,1 -20401140: ee9ff0ef jal ra,20401028 -20401144: 00a00513 li a0,10 -20401148: ee1ff0ef jal ra,20401028 -2040114c: 00050713 mv a4,a0 -20401150: 800007b7 lui a5,0x80000 -20401154: 42e7a823 sw a4,1072(a5) # 80000430 <_sp+0xffffc430> -20401158: 800007b7 lui a5,0x80000 -2040115c: 4307a783 lw a5,1072(a5) # 80000430 <_sp+0xffffc430> -20401160: 00078513 mv a0,a5 -20401164: 00c12083 lw ra,12(sp) -20401168: 00812403 lw s0,8(sp) -2040116c: 01010113 addi sp,sp,16 -20401170: 00008067 ret - -20401174 : -20401174: fe010113 addi sp,sp,-32 -20401178: 00112e23 sw ra,28(sp) -2040117c: 00812c23 sw s0,24(sp) -20401180: 02010413 addi s0,sp,32 -20401184: fea42623 sw a0,-20(s0) -20401188: 100127b7 lui a5,0x10012 -2040118c: 03c78793 addi a5,a5,60 # 1001203c <__stack_size+0x1001183c> -20401190: 0007a683 lw a3,0(a5) -20401194: 100127b7 lui a5,0x10012 -20401198: 03c78793 addi a5,a5,60 # 1001203c <__stack_size+0x1001183c> -2040119c: fffd0737 lui a4,0xfffd0 -204011a0: fff70713 addi a4,a4,-1 # fffcffff <_sp+0x7ffcbfff> -204011a4: 00e6f733 and a4,a3,a4 -204011a8: 00e7a023 sw a4,0(a5) -204011ac: 100127b7 lui a5,0x10012 -204011b0: 03878793 addi a5,a5,56 # 10012038 <__stack_size+0x10011838> -204011b4: 0007a683 lw a3,0(a5) -204011b8: 100127b7 lui a5,0x10012 -204011bc: 03878793 addi a5,a5,56 # 10012038 <__stack_size+0x10011838> -204011c0: 00030737 lui a4,0x30 -204011c4: 00e6e733 or a4,a3,a4 -204011c8: 00e7a023 sw a4,0(a5) -204011cc: f55ff0ef jal ra,20401120 -204011d0: 00050793 mv a5,a0 -204011d4: fec42583 lw a1,-20(s0) -204011d8: 00078513 mv a0,a5 -204011dc: 559000ef jal ra,20401f34 <__udivsi3> -204011e0: 00050793 mv a5,a0 -204011e4: 00078713 mv a4,a5 -204011e8: 100137b7 lui a5,0x10013 -204011ec: 01878793 addi a5,a5,24 # 10013018 <__stack_size+0x10012818> -204011f0: fff70713 addi a4,a4,-1 # 2ffff <__stack_size+0x2f7ff> -204011f4: 00e7a023 sw a4,0(a5) -204011f8: 100137b7 lui a5,0x10013 -204011fc: 00878793 addi a5,a5,8 # 10013008 <__stack_size+0x10012808> -20401200: 0007a703 lw a4,0(a5) -20401204: 100137b7 lui a5,0x10013 -20401208: 00878793 addi a5,a5,8 # 10013008 <__stack_size+0x10012808> -2040120c: 00176713 ori a4,a4,1 -20401210: 00e7a023 sw a4,0(a5) -20401214: 00000013 nop -20401218: 01c12083 lw ra,28(sp) -2040121c: 01812403 lw s0,24(sp) -20401220: 02010113 addi sp,sp,32 -20401224: 00008067 ret - -20401228 : -20401228: fe010113 addi sp,sp,-32 -2040122c: 00112e23 sw ra,28(sp) -20401230: 00812c23 sw s0,24(sp) -20401234: 02010413 addi s0,sp,32 -20401238: fea42623 sw a0,-20(s0) -2040123c: feb42423 sw a1,-24(s0) -20401240: 00500613 li a2,5 -20401244: 204027b7 lui a5,0x20402 -20401248: 29478593 addi a1,a5,660 # 20402294 <__clzsi2+0x2b4> -2040124c: 00100513 li a0,1 -20401250: 0e4000ef jal ra,20401334 <__wrap_write> -20401254: fec42783 lw a5,-20(s0) -20401258: 00178793 addi a5,a5,1 -2040125c: 00078513 mv a0,a5 -20401260: 1f0000ef jal ra,20401450 <__wrap__exit> - -20401264 <_init>: -20401264: fe010113 addi sp,sp,-32 -20401268: 00112e23 sw ra,28(sp) -2040126c: 00812c23 sw s0,24(sp) -20401270: 02010413 addi s0,sp,32 -20401274: d61ff0ef jal ra,20400fd4 -20401278: 00100713 li a4,1 -2040127c: 01f00693 li a3,31 -20401280: 00100613 li a2,1 -20401284: 00000593 li a1,0 -20401288: 00000513 li a0,0 -2040128c: b85ff0ef jal ra,20400e10 -20401290: 0001c7b7 lui a5,0x1c -20401294: 20078513 addi a0,a5,512 # 1c200 <__stack_size+0x1ba00> -20401298: eddff0ef jal ra,20401174 -2040129c: e85ff0ef jal ra,20401120 -204012a0: 00050793 mv a5,a0 -204012a4: 00078593 mv a1,a5 -204012a8: 204027b7 lui a5,0x20402 -204012ac: 29c78513 addi a0,a5,668 # 2040229c <__clzsi2+0x2bc> -204012b0: f7cff0ef jal ra,20400a2c <__wrap_printf> -204012b4: 204007b7 lui a5,0x20400 -204012b8: 09c78793 addi a5,a5,156 # 2040009c -204012bc: 30579073 csrw mtvec,a5 -204012c0: 301027f3 csrr a5,misa -204012c4: fef42623 sw a5,-20(s0) -204012c8: fec42783 lw a5,-20(s0) -204012cc: 0207f793 andi a5,a5,32 -204012d0: 00078863 beqz a5,204012e0 <_init+0x7c> -204012d4: 000067b7 lui a5,0x6 -204012d8: 30079073 csrw mstatus,a5 -204012dc: 00305073 csrwi fcsr,0 -204012e0: 00000013 nop -204012e4: 01c12083 lw ra,28(sp) -204012e8: 01812403 lw s0,24(sp) -204012ec: 02010113 addi sp,sp,32 -204012f0: 00008067 ret - -204012f4 <_fini>: -204012f4: ff010113 addi sp,sp,-16 -204012f8: 00812623 sw s0,12(sp) -204012fc: 01010413 addi s0,sp,16 -20401300: 00000013 nop -20401304: 00c12403 lw s0,12(sp) -20401308: 01010113 addi sp,sp,16 -2040130c: 00008067 ret - -20401310 <_stub>: -20401310: fe010113 addi sp,sp,-32 -20401314: 00812e23 sw s0,28(sp) -20401318: 02010413 addi s0,sp,32 -2040131c: fea42623 sw a0,-20(s0) -20401320: fff00793 li a5,-1 -20401324: 00078513 mv a0,a5 -20401328: 01c12403 lw s0,28(sp) -2040132c: 02010113 addi sp,sp,32 -20401330: 00008067 ret - -20401334 <__wrap_write>: -20401334: fd010113 addi sp,sp,-48 -20401338: 02112623 sw ra,44(sp) -2040133c: 02812423 sw s0,40(sp) -20401340: 03010413 addi s0,sp,48 -20401344: fca42e23 sw a0,-36(s0) -20401348: fcb42c23 sw a1,-40(s0) -2040134c: fcc42a23 sw a2,-44(s0) -20401350: fd842783 lw a5,-40(s0) -20401354: fef42423 sw a5,-24(s0) -20401358: fdc42503 lw a0,-36(s0) -2040135c: 0b0000ef jal ra,2040140c <__wrap_isatty> -20401360: 00050793 mv a5,a0 -20401364: 08078463 beqz a5,204013ec <__wrap_write+0xb8> -20401368: fe042623 sw zero,-20(s0) -2040136c: 06c0006f j 204013d8 <__wrap_write+0xa4> -20401370: 00000013 nop -20401374: 100137b7 lui a5,0x10013 -20401378: 0007a783 lw a5,0(a5) # 10013000 <__stack_size+0x10012800> -2040137c: fe07cce3 bltz a5,20401374 <__wrap_write+0x40> -20401380: fe842703 lw a4,-24(s0) -20401384: fec42783 lw a5,-20(s0) -20401388: 00f707b3 add a5,a4,a5 -2040138c: 0007c703 lbu a4,0(a5) -20401390: 100137b7 lui a5,0x10013 -20401394: 00e7a023 sw a4,0(a5) # 10013000 <__stack_size+0x10012800> -20401398: fe842703 lw a4,-24(s0) -2040139c: fec42783 lw a5,-20(s0) -204013a0: 00f707b3 add a5,a4,a5 -204013a4: 0007c703 lbu a4,0(a5) -204013a8: 00a00793 li a5,10 -204013ac: 02f71063 bne a4,a5,204013cc <__wrap_write+0x98> -204013b0: 00000013 nop -204013b4: 100137b7 lui a5,0x10013 -204013b8: 0007a783 lw a5,0(a5) # 10013000 <__stack_size+0x10012800> -204013bc: fe07cce3 bltz a5,204013b4 <__wrap_write+0x80> -204013c0: 100137b7 lui a5,0x10013 -204013c4: 00d00713 li a4,13 -204013c8: 00e7a023 sw a4,0(a5) # 10013000 <__stack_size+0x10012800> -204013cc: fec42783 lw a5,-20(s0) -204013d0: 00178793 addi a5,a5,1 -204013d4: fef42623 sw a5,-20(s0) -204013d8: fec42703 lw a4,-20(s0) -204013dc: fd442783 lw a5,-44(s0) -204013e0: f8f768e3 bltu a4,a5,20401370 <__wrap_write+0x3c> -204013e4: fd442783 lw a5,-44(s0) -204013e8: 0100006f j 204013f8 <__wrap_write+0xc4> -204013ec: 00900513 li a0,9 -204013f0: f21ff0ef jal ra,20401310 <_stub> -204013f4: 00050793 mv a5,a0 -204013f8: 00078513 mv a0,a5 -204013fc: 02c12083 lw ra,44(sp) -20401400: 02812403 lw s0,40(sp) -20401404: 03010113 addi sp,sp,48 -20401408: 00008067 ret - -2040140c <__wrap_isatty>: -2040140c: fe010113 addi sp,sp,-32 -20401410: 00812e23 sw s0,28(sp) -20401414: 02010413 addi s0,sp,32 -20401418: fea42623 sw a0,-20(s0) -2040141c: fec42703 lw a4,-20(s0) -20401420: 00100793 li a5,1 -20401424: 00f70863 beq a4,a5,20401434 <__wrap_isatty+0x28> -20401428: fec42703 lw a4,-20(s0) -2040142c: 00200793 li a5,2 -20401430: 00f71663 bne a4,a5,2040143c <__wrap_isatty+0x30> -20401434: 00100793 li a5,1 -20401438: 0080006f j 20401440 <__wrap_isatty+0x34> -2040143c: 00000793 li a5,0 -20401440: 00078513 mv a0,a5 -20401444: 01c12403 lw s0,28(sp) -20401448: 02010113 addi sp,sp,32 -2040144c: 00008067 ret - -20401450 <__wrap__exit>: -20401450: fc010113 addi sp,sp,-64 -20401454: 02112e23 sw ra,60(sp) -20401458: 02812c23 sw s0,56(sp) -2040145c: 04010413 addi s0,sp,64 -20401460: fca42623 sw a0,-52(s0) -20401464: 204027b7 lui a5,0x20402 -20401468: 2b478793 addi a5,a5,692 # 204022b4 <__clzsi2+0x2d4> -2040146c: 0007a883 lw a7,0(a5) -20401470: 0047a803 lw a6,4(a5) -20401474: 0087a503 lw a0,8(a5) -20401478: 00c7a583 lw a1,12(a5) -2040147c: 0107a603 lw a2,16(a5) -20401480: 0147a683 lw a3,20(a5) -20401484: 0187a703 lw a4,24(a5) -20401488: fd142823 sw a7,-48(s0) -2040148c: fd042a23 sw a6,-44(s0) -20401490: fca42c23 sw a0,-40(s0) -20401494: fcb42e23 sw a1,-36(s0) -20401498: fec42023 sw a2,-32(s0) -2040149c: fed42223 sw a3,-28(s0) -204014a0: fee42423 sw a4,-24(s0) -204014a4: 01c7d783 lhu a5,28(a5) -204014a8: fef41623 sh a5,-20(s0) -204014ac: fd040793 addi a5,s0,-48 -204014b0: 01d00613 li a2,29 -204014b4: 00078593 mv a1,a5 -204014b8: 00200513 li a0,2 -204014bc: e79ff0ef jal ra,20401334 <__wrap_write> -204014c0: 00100613 li a2,1 -204014c4: 204027b7 lui a5,0x20402 -204014c8: 2b078593 addi a1,a5,688 # 204022b0 <__clzsi2+0x2d0> -204014cc: 00200513 li a0,2 -204014d0: e65ff0ef jal ra,20401334 <__wrap_write> -204014d4: 0000006f j 204014d4 <__wrap__exit+0x84> - -204014d8 : -204014d8: 00050593 mv a1,a0 -204014dc: 00000693 li a3,0 -204014e0: 00000613 li a2,0 -204014e4: 00000513 li a0,0 -204014e8: 1740006f j 2040165c <__register_exitproc> - -204014ec : -204014ec: ff010113 addi sp,sp,-16 -204014f0: 00000593 li a1,0 -204014f4: 00812423 sw s0,8(sp) -204014f8: 00112623 sw ra,12(sp) -204014fc: 00050413 mv s0,a0 -20401500: 1fc000ef jal ra,204016fc <__call_exitprocs> -20401504: 5fbff797 auipc a5,0x5fbff -20401508: f2478793 addi a5,a5,-220 # 80000428 <_global_impure_ptr> -2040150c: 0007a503 lw a0,0(a5) -20401510: 03c52783 lw a5,60(a0) -20401514: 00078463 beqz a5,2040151c -20401518: 000780e7 jalr a5 -2040151c: 00040513 mv a0,s0 -20401520: f31ff0ef jal ra,20401450 <__wrap__exit> - -20401524 <__libc_fini_array>: -20401524: ff010113 addi sp,sp,-16 -20401528: 00812423 sw s0,8(sp) -2040152c: 00001797 auipc a5,0x1 -20401530: ee878793 addi a5,a5,-280 # 20402414 <__fini_array_end> -20401534: 00001417 auipc s0,0x1 -20401538: ee040413 addi s0,s0,-288 # 20402414 <__fini_array_end> -2040153c: 40f40433 sub s0,s0,a5 -20401540: 00112623 sw ra,12(sp) -20401544: 00912223 sw s1,4(sp) -20401548: 40245413 srai s0,s0,0x2 -2040154c: 02040263 beqz s0,20401570 <__libc_fini_array+0x4c> -20401550: 00241493 slli s1,s0,0x2 -20401554: ffc48493 addi s1,s1,-4 -20401558: 00f484b3 add s1,s1,a5 -2040155c: 0004a783 lw a5,0(s1) -20401560: fff40413 addi s0,s0,-1 -20401564: ffc48493 addi s1,s1,-4 -20401568: 000780e7 jalr a5 -2040156c: fe0418e3 bnez s0,2040155c <__libc_fini_array+0x38> -20401570: 00c12083 lw ra,12(sp) -20401574: 00812403 lw s0,8(sp) -20401578: 00412483 lw s1,4(sp) -2040157c: 01010113 addi sp,sp,16 -20401580: 00008067 ret - -20401584 <__libc_init_array>: -20401584: ff010113 addi sp,sp,-16 -20401588: 00812423 sw s0,8(sp) -2040158c: 01212023 sw s2,0(sp) -20401590: 00001417 auipc s0,0x1 -20401594: e8040413 addi s0,s0,-384 # 20402410 <__init_array_start> -20401598: 00001917 auipc s2,0x1 -2040159c: e7890913 addi s2,s2,-392 # 20402410 <__init_array_start> -204015a0: 40890933 sub s2,s2,s0 -204015a4: 00112623 sw ra,12(sp) -204015a8: 00912223 sw s1,4(sp) -204015ac: 40295913 srai s2,s2,0x2 -204015b0: 00090e63 beqz s2,204015cc <__libc_init_array+0x48> -204015b4: 00000493 li s1,0 -204015b8: 00042783 lw a5,0(s0) -204015bc: 00148493 addi s1,s1,1 -204015c0: 00440413 addi s0,s0,4 -204015c4: 000780e7 jalr a5 -204015c8: fe9918e3 bne s2,s1,204015b8 <__libc_init_array+0x34> -204015cc: 00001417 auipc s0,0x1 -204015d0: e4440413 addi s0,s0,-444 # 20402410 <__init_array_start> -204015d4: 00001917 auipc s2,0x1 -204015d8: e4090913 addi s2,s2,-448 # 20402414 <__fini_array_end> -204015dc: 40890933 sub s2,s2,s0 -204015e0: 40295913 srai s2,s2,0x2 -204015e4: 00090e63 beqz s2,20401600 <__libc_init_array+0x7c> -204015e8: 00000493 li s1,0 -204015ec: 00042783 lw a5,0(s0) -204015f0: 00148493 addi s1,s1,1 -204015f4: 00440413 addi s0,s0,4 -204015f8: 000780e7 jalr a5 -204015fc: fe9918e3 bne s2,s1,204015ec <__libc_init_array+0x68> -20401600: 00c12083 lw ra,12(sp) -20401604: 00812403 lw s0,8(sp) -20401608: 00412483 lw s1,4(sp) -2040160c: 00012903 lw s2,0(sp) -20401610: 01010113 addi sp,sp,16 -20401614: 00008067 ret - -20401618 : -20401618: 02058463 beqz a1,20401640 -2040161c: 00054783 lbu a5,0(a0) -20401620: 02078a63 beqz a5,20401654 -20401624: 00b506b3 add a3,a0,a1 -20401628: 00050793 mv a5,a0 -2040162c: 00c0006f j 20401638 -20401630: 0007c703 lbu a4,0(a5) -20401634: 00070a63 beqz a4,20401648 -20401638: 00178793 addi a5,a5,1 -2040163c: fed79ae3 bne a5,a3,20401630 -20401640: 00058513 mv a0,a1 -20401644: 00008067 ret -20401648: 40a785b3 sub a1,a5,a0 -2040164c: 00058513 mv a0,a1 -20401650: 00008067 ret -20401654: 00000593 li a1,0 -20401658: fe9ff06f j 20401640 - -2040165c <__register_exitproc>: -2040165c: 5fbff797 auipc a5,0x5fbff -20401660: dcc78793 addi a5,a5,-564 # 80000428 <_global_impure_ptr> -20401664: 0007a703 lw a4,0(a5) -20401668: 14872783 lw a5,328(a4) -2040166c: 04078c63 beqz a5,204016c4 <__register_exitproc+0x68> -20401670: 0047a703 lw a4,4(a5) -20401674: 01f00813 li a6,31 -20401678: 06e84e63 blt a6,a4,204016f4 <__register_exitproc+0x98> -2040167c: 00271813 slli a6,a4,0x2 -20401680: 02050663 beqz a0,204016ac <__register_exitproc+0x50> -20401684: 01078333 add t1,a5,a6 -20401688: 08c32423 sw a2,136(t1) -2040168c: 1887a883 lw a7,392(a5) -20401690: 00100613 li a2,1 -20401694: 00e61633 sll a2,a2,a4 -20401698: 00c8e8b3 or a7,a7,a2 -2040169c: 1917a423 sw a7,392(a5) -204016a0: 10d32423 sw a3,264(t1) -204016a4: 00200693 li a3,2 -204016a8: 02d50463 beq a0,a3,204016d0 <__register_exitproc+0x74> -204016ac: 00170713 addi a4,a4,1 -204016b0: 00e7a223 sw a4,4(a5) -204016b4: 010787b3 add a5,a5,a6 -204016b8: 00b7a423 sw a1,8(a5) -204016bc: 00000513 li a0,0 -204016c0: 00008067 ret -204016c4: 14c70793 addi a5,a4,332 -204016c8: 14f72423 sw a5,328(a4) -204016cc: fa5ff06f j 20401670 <__register_exitproc+0x14> -204016d0: 18c7a683 lw a3,396(a5) -204016d4: 00170713 addi a4,a4,1 -204016d8: 00e7a223 sw a4,4(a5) -204016dc: 00c6e633 or a2,a3,a2 -204016e0: 18c7a623 sw a2,396(a5) -204016e4: 010787b3 add a5,a5,a6 -204016e8: 00b7a423 sw a1,8(a5) -204016ec: 00000513 li a0,0 -204016f0: 00008067 ret -204016f4: fff00513 li a0,-1 -204016f8: 00008067 ret - -204016fc <__call_exitprocs>: -204016fc: fd010113 addi sp,sp,-48 -20401700: 5fbff797 auipc a5,0x5fbff -20401704: d2878793 addi a5,a5,-728 # 80000428 <_global_impure_ptr> -20401708: 01812423 sw s8,8(sp) -2040170c: 0007ac03 lw s8,0(a5) -20401710: 01312e23 sw s3,28(sp) -20401714: 01412c23 sw s4,24(sp) -20401718: 01512a23 sw s5,20(sp) -2040171c: 01612823 sw s6,16(sp) -20401720: 02112623 sw ra,44(sp) -20401724: 02812423 sw s0,40(sp) -20401728: 02912223 sw s1,36(sp) -2040172c: 03212023 sw s2,32(sp) -20401730: 01712623 sw s7,12(sp) -20401734: 00050a93 mv s5,a0 -20401738: 00058b13 mv s6,a1 -2040173c: 00100a13 li s4,1 -20401740: fff00993 li s3,-1 -20401744: 148c2903 lw s2,328(s8) -20401748: 02090863 beqz s2,20401778 <__call_exitprocs+0x7c> -2040174c: 00492483 lw s1,4(s2) -20401750: fff48413 addi s0,s1,-1 -20401754: 02044263 bltz s0,20401778 <__call_exitprocs+0x7c> -20401758: 00249493 slli s1,s1,0x2 -2040175c: 009904b3 add s1,s2,s1 -20401760: 040b0463 beqz s6,204017a8 <__call_exitprocs+0xac> -20401764: 1044a783 lw a5,260(s1) -20401768: 05678063 beq a5,s6,204017a8 <__call_exitprocs+0xac> -2040176c: fff40413 addi s0,s0,-1 -20401770: ffc48493 addi s1,s1,-4 -20401774: ff3416e3 bne s0,s3,20401760 <__call_exitprocs+0x64> -20401778: 02c12083 lw ra,44(sp) -2040177c: 02812403 lw s0,40(sp) -20401780: 02412483 lw s1,36(sp) -20401784: 02012903 lw s2,32(sp) -20401788: 01c12983 lw s3,28(sp) -2040178c: 01812a03 lw s4,24(sp) -20401790: 01412a83 lw s5,20(sp) -20401794: 01012b03 lw s6,16(sp) -20401798: 00c12b83 lw s7,12(sp) -2040179c: 00812c03 lw s8,8(sp) -204017a0: 03010113 addi sp,sp,48 -204017a4: 00008067 ret -204017a8: 00492783 lw a5,4(s2) -204017ac: 0044a683 lw a3,4(s1) -204017b0: fff78793 addi a5,a5,-1 -204017b4: 04878a63 beq a5,s0,20401808 <__call_exitprocs+0x10c> -204017b8: 0004a223 sw zero,4(s1) -204017bc: fa0688e3 beqz a3,2040176c <__call_exitprocs+0x70> -204017c0: 18892783 lw a5,392(s2) -204017c4: 008a1733 sll a4,s4,s0 -204017c8: 00492b83 lw s7,4(s2) -204017cc: 00f777b3 and a5,a4,a5 -204017d0: 00079e63 bnez a5,204017ec <__call_exitprocs+0xf0> -204017d4: 000680e7 jalr a3 -204017d8: 00492783 lw a5,4(s2) -204017dc: f77794e3 bne a5,s7,20401744 <__call_exitprocs+0x48> -204017e0: 148c2783 lw a5,328(s8) -204017e4: f92784e3 beq a5,s2,2040176c <__call_exitprocs+0x70> -204017e8: f5dff06f j 20401744 <__call_exitprocs+0x48> -204017ec: 18c92783 lw a5,396(s2) -204017f0: 0844a583 lw a1,132(s1) -204017f4: 00f77733 and a4,a4,a5 -204017f8: 00071c63 bnez a4,20401810 <__call_exitprocs+0x114> -204017fc: 000a8513 mv a0,s5 -20401800: 000680e7 jalr a3 -20401804: fd5ff06f j 204017d8 <__call_exitprocs+0xdc> -20401808: 00892223 sw s0,4(s2) -2040180c: fb1ff06f j 204017bc <__call_exitprocs+0xc0> -20401810: 00058513 mv a0,a1 -20401814: 000680e7 jalr a3 -20401818: fc1ff06f j 204017d8 <__call_exitprocs+0xdc> - -2040181c <__muldf3>: -2040181c: fd010113 addi sp,sp,-48 -20401820: 01312e23 sw s3,28(sp) -20401824: 0145d993 srli s3,a1,0x14 -20401828: 02812423 sw s0,40(sp) -2040182c: 02912223 sw s1,36(sp) -20401830: 01412c23 sw s4,24(sp) -20401834: 01512a23 sw s5,20(sp) -20401838: 01612823 sw s6,16(sp) -2040183c: 00c59493 slli s1,a1,0xc -20401840: 02112623 sw ra,44(sp) -20401844: 03212023 sw s2,32(sp) -20401848: 01712623 sw s7,12(sp) -2040184c: 7ff9f993 andi s3,s3,2047 -20401850: 00050413 mv s0,a0 -20401854: 00060b13 mv s6,a2 -20401858: 00068a93 mv s5,a3 -2040185c: 00c4d493 srli s1,s1,0xc -20401860: 01f5da13 srli s4,a1,0x1f -20401864: 0a098463 beqz s3,2040190c <__muldf3+0xf0> -20401868: 7ff00793 li a5,2047 -2040186c: 10f98263 beq s3,a5,20401970 <__muldf3+0x154> -20401870: 01d55793 srli a5,a0,0x1d -20401874: 00349493 slli s1,s1,0x3 -20401878: 0097e4b3 or s1,a5,s1 -2040187c: 008007b7 lui a5,0x800 -20401880: 00f4e4b3 or s1,s1,a5 -20401884: 00351913 slli s2,a0,0x3 -20401888: c0198993 addi s3,s3,-1023 -2040188c: 00000b93 li s7,0 -20401890: 014ad513 srli a0,s5,0x14 -20401894: 00ca9413 slli s0,s5,0xc -20401898: 7ff57513 andi a0,a0,2047 -2040189c: 00c45413 srli s0,s0,0xc -204018a0: 01fada93 srli s5,s5,0x1f -204018a4: 10050263 beqz a0,204019a8 <__muldf3+0x18c> -204018a8: 7ff00793 li a5,2047 -204018ac: 16f50263 beq a0,a5,20401a10 <__muldf3+0x1f4> -204018b0: 01db5793 srli a5,s6,0x1d -204018b4: 00341413 slli s0,s0,0x3 -204018b8: 0087e433 or s0,a5,s0 -204018bc: 008007b7 lui a5,0x800 -204018c0: 00f46433 or s0,s0,a5 -204018c4: c0150513 addi a0,a0,-1023 -204018c8: 003b1793 slli a5,s6,0x3 -204018cc: 00000713 li a4,0 -204018d0: 002b9693 slli a3,s7,0x2 -204018d4: 00e6e6b3 or a3,a3,a4 -204018d8: 00a989b3 add s3,s3,a0 -204018dc: fff68693 addi a3,a3,-1 -204018e0: 00e00613 li a2,14 -204018e4: 015a4833 xor a6,s4,s5 -204018e8: 00198893 addi a7,s3,1 -204018ec: 14d66e63 bltu a2,a3,20401a48 <__muldf3+0x22c> -204018f0: 00001617 auipc a2,0x1 -204018f4: 9e460613 addi a2,a2,-1564 # 204022d4 <__clzsi2+0x2f4> -204018f8: 00269693 slli a3,a3,0x2 -204018fc: 00c686b3 add a3,a3,a2 -20401900: 0006a683 lw a3,0(a3) -20401904: 00c686b3 add a3,a3,a2 -20401908: 00068067 jr a3 -2040190c: 00a4e933 or s2,s1,a0 -20401910: 06090c63 beqz s2,20401988 <__muldf3+0x16c> -20401914: 04048063 beqz s1,20401954 <__muldf3+0x138> -20401918: 00048513 mv a0,s1 -2040191c: 6c4000ef jal ra,20401fe0 <__clzsi2> -20401920: ff550713 addi a4,a0,-11 -20401924: 01c00793 li a5,28 -20401928: 02e7cc63 blt a5,a4,20401960 <__muldf3+0x144> -2040192c: 01d00793 li a5,29 -20401930: ff850913 addi s2,a0,-8 -20401934: 40e787b3 sub a5,a5,a4 -20401938: 012494b3 sll s1,s1,s2 -2040193c: 00f457b3 srl a5,s0,a5 -20401940: 0097e4b3 or s1,a5,s1 -20401944: 01241933 sll s2,s0,s2 -20401948: c0d00993 li s3,-1011 -2040194c: 40a989b3 sub s3,s3,a0 -20401950: f3dff06f j 2040188c <__muldf3+0x70> -20401954: 68c000ef jal ra,20401fe0 <__clzsi2> -20401958: 02050513 addi a0,a0,32 -2040195c: fc5ff06f j 20401920 <__muldf3+0x104> -20401960: fd850493 addi s1,a0,-40 -20401964: 009414b3 sll s1,s0,s1 -20401968: 00000913 li s2,0 -2040196c: fddff06f j 20401948 <__muldf3+0x12c> -20401970: 00a4e933 or s2,s1,a0 -20401974: 02090263 beqz s2,20401998 <__muldf3+0x17c> -20401978: 00050913 mv s2,a0 -2040197c: 7ff00993 li s3,2047 -20401980: 00300b93 li s7,3 -20401984: f0dff06f j 20401890 <__muldf3+0x74> -20401988: 00000493 li s1,0 -2040198c: 00000993 li s3,0 -20401990: 00100b93 li s7,1 -20401994: efdff06f j 20401890 <__muldf3+0x74> -20401998: 00000493 li s1,0 -2040199c: 7ff00993 li s3,2047 -204019a0: 00200b93 li s7,2 -204019a4: eedff06f j 20401890 <__muldf3+0x74> -204019a8: 016467b3 or a5,s0,s6 -204019ac: 06078e63 beqz a5,20401a28 <__muldf3+0x20c> -204019b0: 04040063 beqz s0,204019f0 <__muldf3+0x1d4> -204019b4: 00040513 mv a0,s0 -204019b8: 628000ef jal ra,20401fe0 <__clzsi2> -204019bc: ff550693 addi a3,a0,-11 -204019c0: 01c00793 li a5,28 -204019c4: 02d7ce63 blt a5,a3,20401a00 <__muldf3+0x1e4> -204019c8: 01d00713 li a4,29 -204019cc: ff850793 addi a5,a0,-8 -204019d0: 40d70733 sub a4,a4,a3 -204019d4: 00f41433 sll s0,s0,a5 -204019d8: 00eb5733 srl a4,s6,a4 -204019dc: 00876433 or s0,a4,s0 -204019e0: 00fb17b3 sll a5,s6,a5 -204019e4: c0d00713 li a4,-1011 -204019e8: 40a70533 sub a0,a4,a0 -204019ec: ee1ff06f j 204018cc <__muldf3+0xb0> -204019f0: 000b0513 mv a0,s6 -204019f4: 5ec000ef jal ra,20401fe0 <__clzsi2> -204019f8: 02050513 addi a0,a0,32 -204019fc: fc1ff06f j 204019bc <__muldf3+0x1a0> -20401a00: fd850413 addi s0,a0,-40 -20401a04: 008b1433 sll s0,s6,s0 -20401a08: 00000793 li a5,0 -20401a0c: fd9ff06f j 204019e4 <__muldf3+0x1c8> -20401a10: 016467b3 or a5,s0,s6 -20401a14: 02078263 beqz a5,20401a38 <__muldf3+0x21c> -20401a18: 000b0793 mv a5,s6 -20401a1c: 7ff00513 li a0,2047 -20401a20: 00300713 li a4,3 -20401a24: eadff06f j 204018d0 <__muldf3+0xb4> -20401a28: 00000413 li s0,0 -20401a2c: 00000513 li a0,0 -20401a30: 00100713 li a4,1 -20401a34: e9dff06f j 204018d0 <__muldf3+0xb4> -20401a38: 00000413 li s0,0 -20401a3c: 7ff00513 li a0,2047 -20401a40: 00200713 li a4,2 -20401a44: e8dff06f j 204018d0 <__muldf3+0xb4> -20401a48: 000102b7 lui t0,0x10 -20401a4c: fff28313 addi t1,t0,-1 # ffff <__stack_size+0xf7ff> -20401a50: 01095f13 srli t5,s2,0x10 -20401a54: 0107df93 srli t6,a5,0x10 -20401a58: 00697933 and s2,s2,t1 -20401a5c: 0067f7b3 and a5,a5,t1 -20401a60: 00090513 mv a0,s2 -20401a64: 00078593 mv a1,a5 -20401a68: 4a0000ef jal ra,20401f08 <__mulsi3> -20401a6c: 00050e93 mv t4,a0 -20401a70: 000f8593 mv a1,t6 -20401a74: 00090513 mv a0,s2 -20401a78: 490000ef jal ra,20401f08 <__mulsi3> -20401a7c: 00050e13 mv t3,a0 -20401a80: 00078593 mv a1,a5 -20401a84: 000f0513 mv a0,t5 -20401a88: 480000ef jal ra,20401f08 <__mulsi3> -20401a8c: 00050a13 mv s4,a0 -20401a90: 000f8593 mv a1,t6 -20401a94: 000f0513 mv a0,t5 -20401a98: 470000ef jal ra,20401f08 <__mulsi3> -20401a9c: 010ed713 srli a4,t4,0x10 -20401aa0: 014e0e33 add t3,t3,s4 -20401aa4: 01c70733 add a4,a4,t3 -20401aa8: 00050393 mv t2,a0 -20401aac: 01477463 bgeu a4,s4,20401ab4 <__muldf3+0x298> -20401ab0: 005503b3 add t2,a0,t0 -20401ab4: 00677e33 and t3,a4,t1 -20401ab8: 006efeb3 and t4,t4,t1 -20401abc: 01045a13 srli s4,s0,0x10 -20401ac0: 010e1e13 slli t3,t3,0x10 -20401ac4: 00647433 and s0,s0,t1 -20401ac8: 01075293 srli t0,a4,0x10 -20401acc: 01de0e33 add t3,t3,t4 -20401ad0: 00090513 mv a0,s2 -20401ad4: 00040593 mv a1,s0 -20401ad8: 430000ef jal ra,20401f08 <__mulsi3> -20401adc: 00050e93 mv t4,a0 -20401ae0: 000a0593 mv a1,s4 -20401ae4: 00090513 mv a0,s2 -20401ae8: 420000ef jal ra,20401f08 <__mulsi3> -20401aec: 00050713 mv a4,a0 -20401af0: 00040593 mv a1,s0 -20401af4: 000f0513 mv a0,t5 -20401af8: 410000ef jal ra,20401f08 <__mulsi3> -20401afc: 00050313 mv t1,a0 -20401b00: 000a0593 mv a1,s4 -20401b04: 000f0513 mv a0,t5 -20401b08: 400000ef jal ra,20401f08 <__mulsi3> -20401b0c: 010ed693 srli a3,t4,0x10 -20401b10: 00670733 add a4,a4,t1 -20401b14: 00e686b3 add a3,a3,a4 -20401b18: 0066f663 bgeu a3,t1,20401b24 <__muldf3+0x308> -20401b1c: 00010737 lui a4,0x10 -20401b20: 00e50533 add a0,a0,a4 -20401b24: 00010ab7 lui s5,0x10 -20401b28: fffa8613 addi a2,s5,-1 # ffff <__stack_size+0xf7ff> -20401b2c: 0106d713 srli a4,a3,0x10 -20401b30: 00c6f6b3 and a3,a3,a2 -20401b34: 01069693 slli a3,a3,0x10 -20401b38: 00cefeb3 and t4,t4,a2 -20401b3c: 00a70f33 add t5,a4,a0 -20401b40: 01d68eb3 add t4,a3,t4 -20401b44: 0104d713 srli a4,s1,0x10 -20401b48: 00c4f4b3 and s1,s1,a2 -20401b4c: 01d282b3 add t0,t0,t4 -20401b50: 00048513 mv a0,s1 -20401b54: 00078593 mv a1,a5 -20401b58: 3b0000ef jal ra,20401f08 <__mulsi3> -20401b5c: 00050913 mv s2,a0 -20401b60: 000f8593 mv a1,t6 -20401b64: 00048513 mv a0,s1 -20401b68: 3a0000ef jal ra,20401f08 <__mulsi3> -20401b6c: 00050313 mv t1,a0 -20401b70: 00078593 mv a1,a5 -20401b74: 00070513 mv a0,a4 -20401b78: 390000ef jal ra,20401f08 <__mulsi3> -20401b7c: 00050b13 mv s6,a0 -20401b80: 000f8593 mv a1,t6 -20401b84: 00070513 mv a0,a4 -20401b88: 380000ef jal ra,20401f08 <__mulsi3> -20401b8c: 01095793 srli a5,s2,0x10 -20401b90: 01630333 add t1,t1,s6 -20401b94: 006787b3 add a5,a5,t1 -20401b98: 0167f463 bgeu a5,s6,20401ba0 <__muldf3+0x384> -20401b9c: 01550533 add a0,a0,s5 -20401ba0: 00010ab7 lui s5,0x10 -20401ba4: fffa8693 addi a3,s5,-1 # ffff <__stack_size+0xf7ff> -20401ba8: 00d7f333 and t1,a5,a3 -20401bac: 0107d613 srli a2,a5,0x10 -20401bb0: 00d97933 and s2,s2,a3 -20401bb4: 01031313 slli t1,t1,0x10 -20401bb8: 00a60fb3 add t6,a2,a0 -20401bbc: 01230333 add t1,t1,s2 -20401bc0: 00048513 mv a0,s1 -20401bc4: 00040593 mv a1,s0 -20401bc8: 340000ef jal ra,20401f08 <__mulsi3> -20401bcc: 00050793 mv a5,a0 -20401bd0: 000a0593 mv a1,s4 -20401bd4: 00048513 mv a0,s1 -20401bd8: 330000ef jal ra,20401f08 <__mulsi3> -20401bdc: 00050493 mv s1,a0 -20401be0: 00040593 mv a1,s0 -20401be4: 00070513 mv a0,a4 -20401be8: 320000ef jal ra,20401f08 <__mulsi3> -20401bec: 00050913 mv s2,a0 -20401bf0: 000a0593 mv a1,s4 -20401bf4: 00070513 mv a0,a4 -20401bf8: 310000ef jal ra,20401f08 <__mulsi3> -20401bfc: 0107d693 srli a3,a5,0x10 -20401c00: 012484b3 add s1,s1,s2 -20401c04: 009686b3 add a3,a3,s1 -20401c08: 0126f463 bgeu a3,s2,20401c10 <__muldf3+0x3f4> -20401c0c: 01550533 add a0,a0,s5 -20401c10: 00010637 lui a2,0x10 -20401c14: fff60613 addi a2,a2,-1 # ffff <__stack_size+0xf7ff> -20401c18: 00c6f733 and a4,a3,a2 -20401c1c: 00c7f7b3 and a5,a5,a2 -20401c20: 01071713 slli a4,a4,0x10 -20401c24: 007282b3 add t0,t0,t2 -20401c28: 00f70733 add a4,a4,a5 -20401c2c: 01d2beb3 sltu t4,t0,t4 -20401c30: 01e70733 add a4,a4,t5 -20401c34: 01d70433 add s0,a4,t4 -20401c38: 006282b3 add t0,t0,t1 -20401c3c: 01f40633 add a2,s0,t6 -20401c40: 0062b333 sltu t1,t0,t1 -20401c44: 006605b3 add a1,a2,t1 -20401c48: 01e73733 sltu a4,a4,t5 -20401c4c: 01d43433 sltu s0,s0,t4 -20401c50: 00876433 or s0,a4,s0 -20401c54: 0106d693 srli a3,a3,0x10 -20401c58: 01f63633 sltu a2,a2,t6 -20401c5c: 0065b333 sltu t1,a1,t1 -20401c60: 00d40433 add s0,s0,a3 -20401c64: 00666333 or t1,a2,t1 -20401c68: 00640433 add s0,s0,t1 -20401c6c: 00929793 slli a5,t0,0x9 -20401c70: 00a40433 add s0,s0,a0 -20401c74: 01c7e7b3 or a5,a5,t3 -20401c78: 00941413 slli s0,s0,0x9 -20401c7c: 0175d513 srli a0,a1,0x17 -20401c80: 00f037b3 snez a5,a5 -20401c84: 0172de13 srli t3,t0,0x17 -20401c88: 00959713 slli a4,a1,0x9 -20401c8c: 00a46433 or s0,s0,a0 -20401c90: 01c7e7b3 or a5,a5,t3 -20401c94: 00e7e7b3 or a5,a5,a4 -20401c98: 00741713 slli a4,s0,0x7 -20401c9c: 10075263 bgez a4,20401da0 <__muldf3+0x584> -20401ca0: 0017d713 srli a4,a5,0x1 -20401ca4: 0017f793 andi a5,a5,1 -20401ca8: 00f767b3 or a5,a4,a5 -20401cac: 01f41713 slli a4,s0,0x1f -20401cb0: 00e7e7b3 or a5,a5,a4 -20401cb4: 00145413 srli s0,s0,0x1 -20401cb8: 3ff88693 addi a3,a7,1023 -20401cbc: 0ed05663 blez a3,20401da8 <__muldf3+0x58c> -20401cc0: 0077f713 andi a4,a5,7 -20401cc4: 02070063 beqz a4,20401ce4 <__muldf3+0x4c8> -20401cc8: 00f7f713 andi a4,a5,15 -20401ccc: 00400613 li a2,4 -20401cd0: 00c70a63 beq a4,a2,20401ce4 <__muldf3+0x4c8> -20401cd4: 00478713 addi a4,a5,4 # 800004 <__stack_size+0x7ff804> -20401cd8: 00f737b3 sltu a5,a4,a5 -20401cdc: 00f40433 add s0,s0,a5 -20401ce0: 00070793 mv a5,a4 -20401ce4: 00741713 slli a4,s0,0x7 -20401ce8: 00075a63 bgez a4,20401cfc <__muldf3+0x4e0> -20401cec: ff000737 lui a4,0xff000 -20401cf0: fff70713 addi a4,a4,-1 # feffffff <_sp+0x7effbfff> -20401cf4: 00e47433 and s0,s0,a4 -20401cf8: 40088693 addi a3,a7,1024 -20401cfc: 7fe00713 li a4,2046 -20401d00: 16d74663 blt a4,a3,20401e6c <__muldf3+0x650> -20401d04: 0037d713 srli a4,a5,0x3 -20401d08: 01d41793 slli a5,s0,0x1d -20401d0c: 00e7e7b3 or a5,a5,a4 -20401d10: 00345413 srli s0,s0,0x3 -20401d14: 00c41413 slli s0,s0,0xc -20401d18: 7ff6f713 andi a4,a3,2047 -20401d1c: 01471713 slli a4,a4,0x14 -20401d20: 00c45413 srli s0,s0,0xc -20401d24: 00e46433 or s0,s0,a4 -20401d28: 01f81813 slli a6,a6,0x1f -20401d2c: 01046733 or a4,s0,a6 -20401d30: 02c12083 lw ra,44(sp) -20401d34: 02812403 lw s0,40(sp) -20401d38: 02412483 lw s1,36(sp) -20401d3c: 02012903 lw s2,32(sp) -20401d40: 01c12983 lw s3,28(sp) -20401d44: 01812a03 lw s4,24(sp) -20401d48: 01412a83 lw s5,20(sp) -20401d4c: 01012b03 lw s6,16(sp) -20401d50: 00c12b83 lw s7,12(sp) -20401d54: 00078513 mv a0,a5 -20401d58: 00070593 mv a1,a4 -20401d5c: 03010113 addi sp,sp,48 -20401d60: 00008067 ret -20401d64: 000a0813 mv a6,s4 -20401d68: 00048413 mv s0,s1 -20401d6c: 00090793 mv a5,s2 -20401d70: 000b8713 mv a4,s7 -20401d74: 00200693 li a3,2 -20401d78: 0ed70a63 beq a4,a3,20401e6c <__muldf3+0x650> -20401d7c: 00300693 li a3,3 -20401d80: 0cd70c63 beq a4,a3,20401e58 <__muldf3+0x63c> -20401d84: 00100693 li a3,1 -20401d88: f2d718e3 bne a4,a3,20401cb8 <__muldf3+0x49c> -20401d8c: 00000413 li s0,0 -20401d90: 00000793 li a5,0 -20401d94: 0880006f j 20401e1c <__muldf3+0x600> -20401d98: 000a8813 mv a6,s5 -20401d9c: fd9ff06f j 20401d74 <__muldf3+0x558> -20401da0: 00098893 mv a7,s3 -20401da4: f15ff06f j 20401cb8 <__muldf3+0x49c> -20401da8: 00100613 li a2,1 -20401dac: 40d60633 sub a2,a2,a3 -20401db0: 03800713 li a4,56 -20401db4: fcc74ce3 blt a4,a2,20401d8c <__muldf3+0x570> -20401db8: 01f00713 li a4,31 -20401dbc: 06c74463 blt a4,a2,20401e24 <__muldf3+0x608> -20401dc0: 41e88893 addi a7,a7,1054 -20401dc4: 01141733 sll a4,s0,a7 -20401dc8: 00c7d6b3 srl a3,a5,a2 -20401dcc: 011797b3 sll a5,a5,a7 -20401dd0: 00d76733 or a4,a4,a3 -20401dd4: 00f037b3 snez a5,a5 -20401dd8: 00f767b3 or a5,a4,a5 -20401ddc: 00c45433 srl s0,s0,a2 -20401de0: 0077f713 andi a4,a5,7 -20401de4: 02070063 beqz a4,20401e04 <__muldf3+0x5e8> -20401de8: 00f7f713 andi a4,a5,15 -20401dec: 00400693 li a3,4 -20401df0: 00d70a63 beq a4,a3,20401e04 <__muldf3+0x5e8> -20401df4: 00478713 addi a4,a5,4 -20401df8: 00f737b3 sltu a5,a4,a5 -20401dfc: 00f40433 add s0,s0,a5 -20401e00: 00070793 mv a5,a4 -20401e04: 00841713 slli a4,s0,0x8 -20401e08: 06074a63 bltz a4,20401e7c <__muldf3+0x660> -20401e0c: 01d41713 slli a4,s0,0x1d -20401e10: 0037d793 srli a5,a5,0x3 -20401e14: 00f767b3 or a5,a4,a5 -20401e18: 00345413 srli s0,s0,0x3 -20401e1c: 00000693 li a3,0 -20401e20: ef5ff06f j 20401d14 <__muldf3+0x4f8> -20401e24: fe100713 li a4,-31 -20401e28: 40d70733 sub a4,a4,a3 -20401e2c: 02000593 li a1,32 -20401e30: 00e45733 srl a4,s0,a4 -20401e34: 00000693 li a3,0 -20401e38: 00b60663 beq a2,a1,20401e44 <__muldf3+0x628> -20401e3c: 43e88893 addi a7,a7,1086 -20401e40: 011416b3 sll a3,s0,a7 -20401e44: 00f6e7b3 or a5,a3,a5 -20401e48: 00f037b3 snez a5,a5 -20401e4c: 00f767b3 or a5,a4,a5 -20401e50: 00000413 li s0,0 -20401e54: f8dff06f j 20401de0 <__muldf3+0x5c4> -20401e58: 00080437 lui s0,0x80 -20401e5c: 00000793 li a5,0 -20401e60: 7ff00693 li a3,2047 -20401e64: 00000813 li a6,0 -20401e68: eadff06f j 20401d14 <__muldf3+0x4f8> -20401e6c: 00000413 li s0,0 -20401e70: 00000793 li a5,0 -20401e74: 7ff00693 li a3,2047 -20401e78: e9dff06f j 20401d14 <__muldf3+0x4f8> -20401e7c: 00000413 li s0,0 -20401e80: 00000793 li a5,0 -20401e84: 00100693 li a3,1 -20401e88: e8dff06f j 20401d14 <__muldf3+0x4f8> - -20401e8c <__fixunsdfsi>: -20401e8c: 0145d713 srli a4,a1,0x14 -20401e90: 001006b7 lui a3,0x100 -20401e94: 00050613 mv a2,a0 -20401e98: fff68793 addi a5,a3,-1 # fffff <__stack_size+0xff7ff> -20401e9c: 7ff77713 andi a4,a4,2047 -20401ea0: 3fe00513 li a0,1022 -20401ea4: 00b7f7b3 and a5,a5,a1 -20401ea8: 01f5d593 srli a1,a1,0x1f -20401eac: 04e55a63 bge a0,a4,20401f00 <__fixunsdfsi+0x74> -20401eb0: 00000513 li a0,0 -20401eb4: 00059863 bnez a1,20401ec4 <__fixunsdfsi+0x38> -20401eb8: 41e00593 li a1,1054 -20401ebc: fff00513 li a0,-1 -20401ec0: 00e5d463 bge a1,a4,20401ec8 <__fixunsdfsi+0x3c> -20401ec4: 00008067 ret -20401ec8: 00d7e7b3 or a5,a5,a3 -20401ecc: 43300693 li a3,1075 -20401ed0: 40e686b3 sub a3,a3,a4 -20401ed4: 01f00593 li a1,31 -20401ed8: 00d5cc63 blt a1,a3,20401ef0 <__fixunsdfsi+0x64> -20401edc: bed70713 addi a4,a4,-1043 -20401ee0: 00e797b3 sll a5,a5,a4 -20401ee4: 00d65533 srl a0,a2,a3 -20401ee8: 00a7e533 or a0,a5,a0 -20401eec: 00008067 ret -20401ef0: 41300513 li a0,1043 -20401ef4: 40e50533 sub a0,a0,a4 -20401ef8: 00a7d533 srl a0,a5,a0 -20401efc: 00008067 ret -20401f00: 00000513 li a0,0 -20401f04: 00008067 ret - -20401f08 <__mulsi3>: -20401f08: 00050613 mv a2,a0 -20401f0c: 00000513 li a0,0 -20401f10: 0015f693 andi a3,a1,1 -20401f14: 00068463 beqz a3,20401f1c <__mulsi3+0x14> -20401f18: 00c50533 add a0,a0,a2 -20401f1c: 0015d593 srli a1,a1,0x1 -20401f20: 00161613 slli a2,a2,0x1 -20401f24: fe0596e3 bnez a1,20401f10 <__mulsi3+0x8> -20401f28: 00008067 ret - -20401f2c <__divsi3>: -20401f2c: 06054063 bltz a0,20401f8c <__umodsi3+0x10> -20401f30: 0605c663 bltz a1,20401f9c <__umodsi3+0x20> - -20401f34 <__udivsi3>: -20401f34: 00058613 mv a2,a1 -20401f38: 00050593 mv a1,a0 -20401f3c: fff00513 li a0,-1 -20401f40: 02060c63 beqz a2,20401f78 <__udivsi3+0x44> -20401f44: 00100693 li a3,1 -20401f48: 00b67a63 bgeu a2,a1,20401f5c <__udivsi3+0x28> -20401f4c: 00c05863 blez a2,20401f5c <__udivsi3+0x28> -20401f50: 00161613 slli a2,a2,0x1 -20401f54: 00169693 slli a3,a3,0x1 -20401f58: feb66ae3 bltu a2,a1,20401f4c <__udivsi3+0x18> -20401f5c: 00000513 li a0,0 -20401f60: 00c5e663 bltu a1,a2,20401f6c <__udivsi3+0x38> -20401f64: 40c585b3 sub a1,a1,a2 -20401f68: 00d56533 or a0,a0,a3 -20401f6c: 0016d693 srli a3,a3,0x1 -20401f70: 00165613 srli a2,a2,0x1 -20401f74: fe0696e3 bnez a3,20401f60 <__udivsi3+0x2c> -20401f78: 00008067 ret - -20401f7c <__umodsi3>: -20401f7c: 00008293 mv t0,ra -20401f80: fb5ff0ef jal ra,20401f34 <__udivsi3> -20401f84: 00058513 mv a0,a1 -20401f88: 00028067 jr t0 -20401f8c: 40a00533 neg a0,a0 -20401f90: 0005d863 bgez a1,20401fa0 <__umodsi3+0x24> -20401f94: 40b005b3 neg a1,a1 -20401f98: f9dff06f j 20401f34 <__udivsi3> -20401f9c: 40b005b3 neg a1,a1 -20401fa0: 00008293 mv t0,ra -20401fa4: f91ff0ef jal ra,20401f34 <__udivsi3> -20401fa8: 40a00533 neg a0,a0 -20401fac: 00028067 jr t0 - -20401fb0 <__modsi3>: -20401fb0: 00008293 mv t0,ra -20401fb4: 0005ca63 bltz a1,20401fc8 <__modsi3+0x18> -20401fb8: 00054c63 bltz a0,20401fd0 <__modsi3+0x20> -20401fbc: f79ff0ef jal ra,20401f34 <__udivsi3> -20401fc0: 00058513 mv a0,a1 -20401fc4: 00028067 jr t0 -20401fc8: 40b005b3 neg a1,a1 -20401fcc: fe0558e3 bgez a0,20401fbc <__modsi3+0xc> -20401fd0: 40a00533 neg a0,a0 -20401fd4: f61ff0ef jal ra,20401f34 <__udivsi3> -20401fd8: 40b00533 neg a0,a1 -20401fdc: 00028067 jr t0 - -20401fe0 <__clzsi2>: -20401fe0: 000107b7 lui a5,0x10 -20401fe4: 02f57a63 bgeu a0,a5,20402018 <__clzsi2+0x38> -20401fe8: 0ff00793 li a5,255 -20401fec: 00a7b7b3 sltu a5,a5,a0 -20401ff0: 00379793 slli a5,a5,0x3 -20401ff4: 02000713 li a4,32 -20401ff8: 40f70733 sub a4,a4,a5 -20401ffc: 00f557b3 srl a5,a0,a5 -20402000: 00000517 auipc a0,0x0 -20402004: 31050513 addi a0,a0,784 # 20402310 <__clz_tab> -20402008: 00f507b3 add a5,a0,a5 -2040200c: 0007c503 lbu a0,0(a5) # 10000 <__stack_size+0xf800> -20402010: 40a70533 sub a0,a4,a0 -20402014: 00008067 ret -20402018: 01000737 lui a4,0x1000 -2040201c: 01000793 li a5,16 -20402020: fce56ae3 bltu a0,a4,20401ff4 <__clzsi2+0x14> -20402024: 01800793 li a5,24 -20402028: fcdff06f j 20401ff4 <__clzsi2+0x14> diff --git a/raven/src/bsp.h b/raven/src/bsp.h new file mode 100644 index 0000000..f04f4f4 --- /dev/null +++ b/raven/src/bsp.h @@ -0,0 +1,22 @@ +/* + * bsp.h + * + * Created on: 30.07.2018 + * Author: eyck + */ + +#ifndef BSP_H_ +#define BSP_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +extern void trap_entry(); +#ifdef __cplusplus +} +#endif + +#endif /* BSP_H_ */ diff --git a/raven/src/delay.c b/raven/src/delay.c new file mode 100644 index 0000000..24070b4 --- /dev/null +++ b/raven/src/delay.c @@ -0,0 +1,123 @@ +/* + * delay.c + * + * Created on: 30.07.2018 + * Author: eyck + */ + +#include "delay.h" + +#define rdmcycle(x) { \ + uint32_t lo, hi, hi2; \ + __asm__ __volatile__ ("1:\n\t" \ + "csrr %0, mcycleh\n\t" \ + "csrr %1, mcycle\n\t" \ + "csrr %2, mcycleh\n\t" \ + "bne %0, %2, 1b\n\t" \ + : "=r" (hi), "=r" (lo), "=r" (hi2)) ; \ + *(x) = lo | ((uint64_t) hi << 32); \ + } + +typedef struct { + uint32_t n; + uint32_t mult; + uint32_t shift; +} int_inverse ; + +int_inverse f_cpu_1000_inv; +int_inverse f_cpu_1000000_inv; + +uint32_t F_CPU=1000000; + +void calc_inv(uint32_t n, int_inverse * res){ + uint32_t one = ~0; + uint32_t d = one/n; + uint32_t r = one%n + 1; + if (r >= n) ++d; + if (d == 0) --d; + uint32_t shift = 0; + while ((d & 0x80000000) == 0){ + d <<= 1; + ++shift; + } + res->n = n; + res->mult = d; + res->shift = shift; +} + +uint32_t divide32_using_inverse(uint32_t n, int_inverse *inv){ + uint32_t d = (uint32_t)(((uint64_t)n * inv->mult) >> 32); + d >>= inv->shift; + if (n - d*inv->n >= inv->n) ++d; + return d; +} + +// Almost full-range 64/32 divide. +// If divisor-1 has i bits, then the answer is exact for n of up to 64-i bits +// e.g. for divisors up to a million, n can have up to 45 bits +// On RV32IM with divide32_using_inverse inlines this uses 5 multiplies, +// 33 instructions, zero branches, 3 loads, 0 stores. +uint64_t divide64_using_inverse(uint64_t n, int_inverse *inv){ + uint32_t preshift = (31 - inv->shift) & 31; + uint64_t d = (uint64_t)divide32_using_inverse(n >> preshift, inv) << preshift; + uint32_t r = n - d * inv->n; + d += divide32_using_inverse(r, inv); + return d; +} + + +uint32_t millis(){ + uint64_t x; + rdmcycle(&x); + x = divide64_using_inverse(x, &f_cpu_1000_inv); + return((uint32_t) (x & 0xFFFFFFFF)); +} + +uint32_t micros(void){ + uint64_t x; + rdmcycle(&x); + // For Power-of-two MHz F_CPU, + // this compiles into a simple shift, + // and is faster than the general solution. +#if F_CPU==16000000 + x = x / (F_CPU / 1000000); +#else +#if F_CPU==256000000 + x = x / (F_CPU / 1000000); +#else + x = divide64_using_inverse(x, &f_cpu_1000000_inv); +#endif +#endif + return((uint32_t) (x & 0xFFFFFFFF)); +} + + +void delayMS(uint32_t dwMs){ + uint64_t current, later; + rdmcycle(¤t); + later = current + dwMs * (F_CPU/1000); + if (later > current){ // usual case + while (later > current) + rdmcycle(¤t); + } else { // wrap. Though this is unlikely to be hit w/ 64-bit mcycle + while (later < current) + rdmcycle(¤t); + while (current < later) + rdmcycle(¤t); + } +} + +void delayUS(uint32_t dwUs){ + uint64_t current, later; + rdmcycle(¤t); + later = current + dwUs * (F_CPU/1000000); + if (later > current){ // usual case + while (later > current) + rdmcycle(¤t); + } else {// wrap. Though this is unlikely to be hit w/ 64-bit mcycle + while (later < current) + rdmcycle(¤t); + while (current < later) + rdmcycle(¤t); + } +} diff --git a/raven/src/delay.h b/raven/src/delay.h new file mode 100644 index 0000000..36ce098 --- /dev/null +++ b/raven/src/delay.h @@ -0,0 +1,25 @@ +/* + * delay.h + * + * Created on: 30.07.2018 + * Author: eyck + */ + +#ifndef DELAY_H_ +#define DELAY_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern uint32_t F_CPU; + +void delayMS(uint32_t dwMs); +void delayUS(uint32_t dwUs); + +#ifdef __cplusplus +} +#endif + +#endif /* DELAY_H_ */ diff --git a/raven/src/hello_raven.cpp b/raven/src/hello_raven.cpp new file mode 100644 index 0000000..60f558e --- /dev/null +++ b/raven/src/hello_raven.cpp @@ -0,0 +1,148 @@ +#include "hello_raven.h" +#include "delay.h" +#include "bsp.h" +#include "plic/plic_driver.h" + +#include +#include + +#include "hifive1_io.h" + + + +#define IOF_ENABLE_TERMINAL (0x30000) + + +typedef void (*function_ptr_t) (void); +//! Instance data for the PLIC. +plic_instance_t g_plic; +std::array g_ext_interrupt_handlers; + + +char * end = (char *)0x80001000; // TODO: end supposed to be a RAM section according to the linker file falsh.lds, but for some reason it's not initialized + +/*! \brief external interrupt handler + * + * routes the peripheral interrupts to the the respective handler + * + */ +extern "C" void handle_m_ext_interrupt() { + plic_source int_num = PLIC_claim_interrupt(&g_plic); + if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS)) + g_ext_interrupt_handlers[int_num](); + else + exit(1 + (uintptr_t) int_num); + PLIC_complete_interrupt(&g_plic, int_num); +} +/*! \brief mtime interval interrupt + * + */ +extern "C" void handle_m_time_interrupt(){ + clear_csr(mie, MIP_MTIP); + // Reset the timer for 3s in the future. + // This also clears the existing timer interrupt. + volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME); + volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now = *mtime; + uint64_t then = now + RTC_FREQ; + *mtimecmp = then; + // Re-enable the timer interrupt. + set_csr(mie, MIP_MTIP); +} +/*! \brief dummy interrupt handler + * + */ +void no_interrupt_handler (void) {}; +/*! \brief configure the per-interrupt handler + * + */ +void configure_irq(size_t irq_num, function_ptr_t handler, unsigned char prio=1) { + g_ext_interrupt_handlers[irq_num] = handler; + // Priority must be set > 0 to trigger the interrupt. + PLIC_set_priority(&g_plic, irq_num, prio); + // Have to enable the interrupt both at the GPIO level, and at the PLIC level. + PLIC_enable_interrupt(&g_plic, irq_num); +} + +static void msi_interrupt_handler(){ + int * local_mem_base = (int *) end; + int hartid = read_csr(mhartid); + + int val_a = *local_mem_base; + int val_b = *(local_mem_base+1); + int sum = val_a + val_b; + *(local_mem_base+100) = sum; + if (sum == 0xF) + printf("HW thread ID %d: sum of A+B=0x%x\n", hartid, sum); + else { + printf("HW thread ID %d: sum of A+B is not 0x%x. Test FAILED!!!\n", hartid, sum); + } +} + +/*!\brief initializes platform + * + */ +void platform_init(){ + // configure clocks + PRCI_use_hfxosc(1); // is equivalent to + qspi1::sckdiv_reg() = 8; + + F_CPU=PRCI_measure_mcycle_freq(20, RTC_FREQ); + printf("core freq at %d Hz\n", F_CPU); + // initialie interupt & trap handling + write_csr(mtvec, &trap_entry); + + PLIC_init(&g_plic, PLIC_CTRL_ADDR, PLIC_NUM_INTERRUPTS, PLIC_NUM_PRIORITIES, 0); + // Disable the machine & timer interrupts until setup is done. + clear_csr(mie, MIP_MEIP); + clear_csr(mie, MIP_MTIP); + for (auto& h:g_ext_interrupt_handlers) h=no_interrupt_handler; + configure_irq(1, msi_interrupt_handler); + // Set the machine timer to go off in 1 second. + volatile uint64_t * mtime = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME); + volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now = *mtime; + uint64_t then = now + RTC_FREQ; + *mtimecmp = then; + // Enable the Machine-External bit in MIE + set_csr(mie, MIP_MEIP); + // Enable the Machine-Timer bit in MIE + set_csr(mie, MIP_MTIP); + // Enable interrupts in general. + set_csr(mstatus, MSTATUS_MIE); +} + +/*! \brief main function + * + */ +int main() { + volatile int * target_mem_base = (int *)(end + 0x10000000); + int * local_mem_base = (int *) end; + int * plic_b_pending = (int *)(0xA0000000+PLIC_PENDING_OFFSET); + + int * local_sync_bit = (int *)(local_mem_base + 10); + int * target_sync_bit = (int *)(target_mem_base + 10); + + int hartid = read_csr(mhartid); + + *local_sync_bit = 0; + GPIO_REG(GPIO_IOF_EN) |= IOF_ENABLE_TERMINAL; // enable GPIO connection to the terminal + platform_init(); + // Enable the Machine-External bit in MIE + set_csr(mie, MIP_MEIP); + + if (hartid == 0) { + int val_a = 5; + int val_b = 0xA; + *target_mem_base = val_a; + *(target_mem_base+1) = val_b; + *(plic_b_pending) = 2; + printf("HW thread ID %d: write value A=0x%x and value B=0x%x to thread 1\n", hartid, val_a, val_b); + } + + *local_sync_bit++; + while (*target_sync_bit < *local_sync_bit); + + printf("End of execution"); + return 0; +} diff --git a/raven/src/hello_raven.h b/raven/src/hello_raven.h new file mode 100644 index 0000000..ec287f6 --- /dev/null +++ b/raven/src/hello_raven.h @@ -0,0 +1,7 @@ +#ifndef HELLO_RAVEN_H_ +#define HELLO_RAVEN_H_ + +extern "C" void handle_m_ext_interrupt(); +extern "C" void handle_m_time_interrupt(); + +#endif /* HELLO_RAVEN_H_ */ diff --git a/raven/src/hifive1_io.cpp b/raven/src/hifive1_io.cpp new file mode 100644 index 0000000..2822762 --- /dev/null +++ b/raven/src/hifive1_io.cpp @@ -0,0 +1,16 @@ +/* + * peripherals.c + * + * Created on: 10.09.2018 + * Author: eyck + */ + +#include "hifive1_io.h" + +template<> volatile bool qspi0::spi_active=false; +template<> volatile bool qspi1::spi_active=false; +template<> volatile bool qspi2::spi_active=false; +template<> volatile bool pwm0::pwm_active=false; +template<> volatile bool pwm1::pwm_active=false; +template<> volatile bool pwm2::pwm_active=false; + diff --git a/raven/src/hifive1_io.h b/raven/src/hifive1_io.h new file mode 100644 index 0000000..9dc4325 --- /dev/null +++ b/raven/src/hifive1_io.h @@ -0,0 +1,26 @@ +/* + * peripherals.h + * + * Created on: 29.07.2018 + * Author: eyck + */ + +#ifndef HIFIVE1_IO_H_ +#define HIFIVE1_IO_H_ + +#include "io/gpio.h" +#include "io/spi.h" +#include "io/pwm.h" +#include "io/uart.h" + +using gpio0=gpio_regs<0x10012000>; +using uart0=uart_regs<0x10013000>; +using uart1=uart_regs<0x10023000>; +using qspi0=spi_regs<0x10014000>; +using qspi1=spi_regs<0x10024000>; +using qspi2=spi_regs<0x10034000>; +using pwm0 =pwm_regs<0x10015000>; +using pwm1 =pwm_regs<0x10025000>; +using pwm2 =pwm_regs<0x10035000>; + +#endif /* HIFIVE1_IO_H_ */ diff --git a/raven/src/io/gpio.h b/raven/src/io/gpio.h new file mode 100644 index 0000000..466f2d2 --- /dev/null +++ b/raven/src/io/gpio.h @@ -0,0 +1,89 @@ +/* + * gpio.h + * + * Created on: 29.07.2018 + * Author: eyck + */ + +#ifndef GPIO_H_ +#define GPIO_H_ + +#include +#include + +template +class gpio_regs { +public: + static inline uint32_t& value_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_INPUT_VAL); + } + + static inline uint32_t& input_en_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_INPUT_EN); + } + + static inline uint32_t& output_en_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_OUTPUT_EN); + } + + static inline uint32_t& port_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_OUTPUT_VAL); + } + + static inline uint32_t& pue_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_PULLUP_EN); + } + + static inline uint32_t& ds_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_DRIVE); + } + + static inline uint32_t& rise_ie_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_RISE_IE); + } + + static inline uint32_t& rise_ip_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_RISE_IP); + } + + static inline uint32_t& fall_ie_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_FALL_IE); + } + + static inline uint32_t& fall_ip_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_FALL_IP); + } + + static inline uint32_t& high_ie_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_HIGH_IE); + } + + static inline uint32_t& high_ip_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_HIGH_IP); + } + + static inline uint32_t& low_ie_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_LOW_IE); + } + + static inline uint32_t& low_ip_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_LOW_IP); + } + + static inline uint32_t& iof_en_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_IOF_EN); + } + + static inline uint32_t& iof_sel_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_IOF_SEL); + } + + static inline uint32_t& out_xor_reg(){ + return *reinterpret_cast(BASE_ADDR+GPIO_OUTPUT_XOR); + } + +}; + + + +#endif /* GPIO_H_ */ diff --git a/raven/src/io/pwm.h b/raven/src/io/pwm.h new file mode 100644 index 0000000..2aab61b --- /dev/null +++ b/raven/src/io/pwm.h @@ -0,0 +1,122 @@ +/* + * pwm.h + * + * Created on: 29.07.2018 + * Author: eyck + */ + +#ifndef PWM_H_ +#define PWM_H_ + +#include +#include "util/bit_field.h" +#include +#include + +template +class pwm_regs { +public: + BEGIN_BF_DECL(pwmcfg_t, uint32_t); + BF_FIELD(scale, 0, 4); + BF_FIELD(sticky, 8, 1); + BF_FIELD(zerocmp, 9, 1); + BF_FIELD(deglitch, 10, 1); + BF_FIELD(enalways, 12, 1); + BF_FIELD(enoneshot, 13, 1); + BF_FIELD(cmp0center, 16, 1); + BF_FIELD(cmp1center, 17, 1); + BF_FIELD(cmp2center, 18, 1); + BF_FIELD(cmp3center, 19, 1); + BF_FIELD(cmp0gang, 24, 1); + BF_FIELD(cmp1gang, 25, 1); + BF_FIELD(cmp2gang, 26, 1); + BF_FIELD(cmp3gang, 27, 1); + BF_FIELD(cmp0ip, 28, 1); + BF_FIELD(cmp1ip, 29, 1); + BF_FIELD(cmp2ip, 30, 1); + BF_FIELD(cmp3ip, 31, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(pwms_t, uint32_t); + BF_FIELD(s, 0, 16); + END_BF_DECL() r_pwms; + + BEGIN_BF_DECL(pwmcmp0_t, uint32_t); + BF_FIELD(cmp0, 0, 16); + END_BF_DECL() r_pwmcmp0; + + BEGIN_BF_DECL(pwmcmp1_t, uint32_t); + BF_FIELD(cmp0, 0, 16); + END_BF_DECL() r_pwmcmp1; + + BEGIN_BF_DECL(pwmcmp2_t, uint32_t); + BF_FIELD(cmp0, 0, 16); + END_BF_DECL() r_pwmcmp2; + + BEGIN_BF_DECL(pwmcmp3_t, uint32_t); + BF_FIELD(cmp0, 0, 16); + END_BF_DECL() r_pwmcmp3; + + static inline pwmcfg_t& cfg_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_CFG); + } + + static inline uint32_t& count_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_COUNT); + } + + static inline pwms_t& s_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_S); + } + + static inline pwmcmp0_t& cmp0_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_CMP0); + } + + static inline pwmcmp1_t& cmp1_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_CMP1); + } + + static inline pwmcmp2_t& cmp2_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_CMP2); + } + + static inline pwmcmp3_t& cmp3_reg(){ + return *reinterpret_cast(BASE_ADDR+PWM_CMP3); + } + + static inline bool oneshot_delay(long delay_us){ + auto scaling_factor=0; + while(delay_us/(1< std::numeric_limits::max()){ + scaling_factor++; + } + cfg_reg()=0; + count_reg()=0; + cfg_reg().scale=4+scaling_factor; // divide by 16 so we get 1us per pwm clock + cmp0_reg().cmp0 = delay_us/(1< +#include "util/bit_field.h" +#include +#include + +template +class spi_regs { +public: + // storage declarations + BEGIN_BF_DECL(sckdiv_t, uint32_t); + BF_FIELD(div, 0, 12); + END_BF_DECL(); + + BEGIN_BF_DECL(sckmode_t, uint32_t); + BF_FIELD(pha, 0, 1); + BF_FIELD(pol, 1, 1); + END_BF_DECL(); + + uint32_t r_csid; + + uint32_t r_csdef; + + BEGIN_BF_DECL(csmode_t, uint32_t); + BF_FIELD(mode, 0, 2); + END_BF_DECL(); + + BEGIN_BF_DECL(delay0_t, uint32_t); + BF_FIELD(cssck, 0, 8); + BF_FIELD(sckcs, 16, 8); + END_BF_DECL(); + + BEGIN_BF_DECL(delay1_t, uint32_t); + BF_FIELD(intercs, 0, 16); + BF_FIELD(interxfr, 16, 8); + END_BF_DECL(); + + BEGIN_BF_DECL(fmt_t, uint32_t); + BF_FIELD(proto, 0, 2); + BF_FIELD(endian, 2, 1); + BF_FIELD(dir, 3, 1); + BF_FIELD(len, 16, 4); + END_BF_DECL(); + + BEGIN_BF_DECL(txdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(full, 31, 1); + END_BF_DECL() r_txdata; + + BEGIN_BF_DECL(rxdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(empty, 31, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(txmark_t, uint32_t); + BF_FIELD(txmark, 0, 3); + END_BF_DECL(); + + BEGIN_BF_DECL(rxmark_t, uint32_t); + BF_FIELD(rxmark, 0, 3); + END_BF_DECL(); + + BEGIN_BF_DECL(fctrl_t, uint32_t); + BF_FIELD(en, 0, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(ffmt_t, uint32_t); + BF_FIELD(cmd_en, 0, 1); + BF_FIELD(addr_len, 1, 2); + BF_FIELD(pad_cnt, 3, 4); + BF_FIELD(cmd_proto, 7, 2); + BF_FIELD(addr_proto, 9, 2); + BF_FIELD(data_proto, 11, 2); + BF_FIELD(cmd_code, 16, 8); + BF_FIELD(pad_code, 24, 8); + END_BF_DECL(); + + BEGIN_BF_DECL(ie_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(ip_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL(); + + static inline sckdiv_t& sckdiv_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_SCKDIV); + } + + static inline sckmode_t& sckmode_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_SCKMODE); + } + + static inline uint32_t& csid_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_CSID); + } + + static inline uint32_t& csdef_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_CSDEF); + } + + static inline csmode_t& csmode_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_CSMODE); + } + + static inline delay0_t& dcssck_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_DCSSCK); + } + + static inline uint32_t& dsckcs_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_DSCKCS); + } + + static inline delay1_t& dintercs_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_DINTERCS); + } + + static inline uint32_t& dinterxfr_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_DINTERXFR); + } + + static inline fmt_t& fmt_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_FMT); + } + + static inline txdata_t& txfifo_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_TXFIFO); + } + + static inline rxdata_t& rxfifo_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_RXFIFO); + } + + static inline txmark_t& txctrl_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_TXCTRL); + } + + static inline rxmark_t& rxctrl_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_RXCTRL); + } + + static inline fctrl_t& fctrl_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_FCTRL); + } + + static inline ffmt_t& ffmt_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_FFMT); + } + + static inline ie_t& ie_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_IE); + } + + static inline ip_t& ip_reg(){ + return *reinterpret_cast(BASE_ADDR+SPI_REG_IP); + } + + template + static bool transfer(std::array& bytes){ + csmode_reg().mode=2; // HOLD mode + rxctrl_reg().rxmark=bytes.size()-1; // trigger irq if more than 2 bytes are received; + ie_reg().rxwm=1; + // write data bytes + for(size_t i=0; i +#include "util/bit_field.h" +#include + +template +class uart_regs { +public: + BEGIN_BF_DECL(txdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(full, 31, 1); + END_BF_DECL() ; + + BEGIN_BF_DECL(rxdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(empty, 31, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(txctrl_t, uint32_t); + BF_FIELD(txen, 0, 1); + BF_FIELD(nstop, 1, 1); + BF_FIELD(txcnt, 16, 3); + END_BF_DECL(); + + BEGIN_BF_DECL(rxctrl_t, uint32_t); + BF_FIELD(rxen, 0, 1); + BF_FIELD(rxcnt, 16, 3); + END_BF_DECL(); + + BEGIN_BF_DECL(ie_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(ip_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL(); + + BEGIN_BF_DECL(div_t, uint32_t); + BF_FIELD(div, 0, 16); + END_BF_DECL(); + + static inline txdata_t& txdata_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_TXFIFO); + } + + static inline rxdata_t& rxdata_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_RXFIFO); + } + + static inline txctrl_t& txctrl_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_TXCTRL); + } + + static inline rxctrl_t& rxctrl_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_RXCTRL); + } + + static inline ie_t& ie_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_IE); + } + + static inline ip_t& ip_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_IP); + } + + static inline div_t& div_reg(){ + return *reinterpret_cast(BASE_ADDR+UART_REG_DIV); + } + +}; + +#endif /* SPI_H_ */ diff --git a/raven/src/util/bit_field.h b/raven/src/util/bit_field.h new file mode 100644 index 0000000..d4aff48 --- /dev/null +++ b/raven/src/util/bit_field.h @@ -0,0 +1,179 @@ +/*--------------------------------------------------------- +Copyright (c) 2015 Jeff Preshing + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +---------------------------------------------------------*/ + +#ifndef BIT_FIELD_H_ +#define BIT_FIELD_H_ + +#ifndef __CPP11OM_BITFIELD_H__ +#define __CPP11OM_BITFIELD_H__ + +#include + +//--------------------------------------------------------- +// BitFieldMember<>: Used internally by ADD_BITFIELD_MEMBER macro. +// All members are public to simplify compliance with sections 9.0.7 and +// 9.5.1 of the C++11 standard, thereby avoiding undefined behavior. +//--------------------------------------------------------- +template struct BitFieldMember { + T value; + + static_assert(Offset + Bits <= (int)sizeof(T) * 8, "Member exceeds bitfield boundaries"); + static_assert(Bits < (int)sizeof(T) * 8, "Can't fill entire bitfield with one member"); + + static const T Maximum = (T(1) << Bits) - 1; + static const T Mask = Maximum << Offset; + T maximum() const { return Maximum; } + T one() const { return T(1) << Offset; } + + operator T() const { return (value >> Offset) & Maximum; } + + BitFieldMember &operator=(T v) { + assert(v <= Maximum); // v must fit inside the bitfield member + value = (value & ~Mask) | (v << Offset); + return *this; + } + + BitFieldMember &operator+=(T v) { + assert(T(*this) + v <= Maximum); // result must fit inside the bitfield member + value += v << Offset; + return *this; + } + + BitFieldMember &operator-=(T v) { + assert(T(*this) >= v); // result must not underflow + value -= v << Offset; + return *this; + } + + BitFieldMember &operator++() { return *this += 1; } + BitFieldMember operator++(int) { // postfix form + BitFieldMember tmp(*this); + operator++(); + return tmp; + } + BitFieldMember &operator--() { return *this -= 1; } + BitFieldMember operator--(int) { // postfix form + BitFieldMember tmp(*this); + operator--(); + return tmp; + } +}; + +//--------------------------------------------------------- +// BitFieldArray<>: Used internally by ADD_BITFIELD_ARRAY macro. +// All members are public to simplify compliance with sections 9.0.7 and +// 9.5.1 of the C++11 standard, thereby avoiding undefined behavior. +//--------------------------------------------------------- +template class BitFieldArray { +public: + T value; + + static_assert(BaseOffset + BitsPerItem * NumItems <= (int)sizeof(T) * 8, "Array exceeds bitfield boundaries"); + static_assert(BitsPerItem < (int)sizeof(T) * 8, "Can't fill entire bitfield with one array element"); + + static const T Maximum = (T(1) << BitsPerItem) - 1; + T maximum() const { return Maximum; } + int numItems() const { return NumItems; } + + class Element { + private: + T &value; + int offset; + + public: + Element(T &value, int offset) + : value(value) + , offset(offset) {} + T mask() const { return Maximum << offset; } + + operator T() const { return (value >> offset) & Maximum; } + + Element &operator=(T v) { + assert(v <= Maximum); // v must fit inside the bitfield member + value = (value & ~mask()) | (v << offset); + return *this; + } + + Element &operator+=(T v) { + assert(T(*this) + v <= Maximum); // result must fit inside the bitfield member + value += v << offset; + return *this; + } + + Element &operator-=(T v) { + assert(T(*this) >= v); // result must not underflow + value -= v << offset; + return *this; + } + + Element &operator++() { return *this += 1; } + Element operator++(int) { // postfix form + Element tmp(*this); + operator++(); + return tmp; + } + Element &operator--() { return *this -= 1; } + Element operator--(int) { // postfix form + Element tmp(*this); + operator--(); + return tmp; + } + }; + + Element operator[](int i) { + assert(i >= 0 && i < NumItems); // array index must be in range + return Element(value, BaseOffset + BitsPerItem * i); + } + + const Element operator[](int i) const { + assert(i >= 0 && i < NumItems); // array index must be in range + return Element(value, BaseOffset + BitsPerItem * i); + } +}; + +//--------------------------------------------------------- +// Bitfield definition macros. +// All members are public to simplify compliance with sections 9.0.7 and +// 9.5.1 of the C++11 standard, thereby avoiding undefined behavior. +//--------------------------------------------------------- +#define BEGIN_BF_DECL(typeName, T) \ + union typeName { \ + struct Wrapper { \ + T value; \ + }; \ + Wrapper flat; \ + typeName(T v = 0) { flat.value = v; } \ + typeName &operator=(T v) { \ + flat.value = v; \ + return *this; \ + } \ + operator T &() { return flat.value; } \ + operator T() const { return flat.value; } \ + using StorageType = T; + +#define BF_FIELD(memberName, offset, bits) BitFieldMember memberName; + +#define BF_ARRAY(memberName, offset, bits, numItems) BitFieldArray memberName; + +#define END_BF_DECL() } + +#endif // __CPP11OM_BITFIELD_H__ + +#endif /* BIT_FIELD_H_ */ diff --git a/raven/wrap_printf.c b/raven/src/wrap_printf.c similarity index 99% rename from raven/wrap_printf.c rename to raven/src/wrap_printf.c index 025d231..af23b1a 100644 --- a/raven/wrap_printf.c +++ b/raven/src/wrap_printf.c @@ -11,7 +11,7 @@ #undef putchar int putchar(int ch) { - return write(1, &ch, 1) == 1 ? ch : -1; + return write(STDOUT_FILENO, &ch, 1) == 1 ? ch : -1; } static void sprintf_putch(int ch, void** data) diff --git a/raven/toolchain-rv32.cmake b/raven/toolchain-rv32.cmake new file mode 100644 index 0000000..bd5ee3b --- /dev/null +++ b/raven/toolchain-rv32.cmake @@ -0,0 +1,33 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR riscv) + +set(TOOLCHAIN_DIR /opt/riscv/tools) +set(ARCHITECTURE riscv64-unknown-elf) + +set(CMAKE_C_COMPILER ${ARCHITECTURE}-gcc +set(CMAKE_CXX_COMPILER ${ARCHITECTURE}-g++ +set(RISCV_LINUX_SYSROOT /opt/riscv/tools CACHE PATH "RISC-V cross compilation system root") # search path for the cross compile toolchain + +set(CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags") +set(CMAKE_C_FLAGS "" CACHE STRING "c flags") +set(CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "shared linker flags") +set(CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "module linker flags") +set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "executable linker flags") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv32imac -mabi=ilp32") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv32imac -mabi=ilp32") +#set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") +#set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -march=rv32imac -mabi=ilp32") + +set(COMPILER_IS_RV32 "1") #flags for the CMakeList.txt +#add_definitions(-D_ARM_TEGRA3) # C/C++ preprocessor macro, which will be used in many many files + +set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}/${ARCHITECTURE}) + +include_directories(${TOOLCHAIN_DIR}/${ARCHITECTURE}/include) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) \ No newline at end of file