13 Commits

8 changed files with 398 additions and 22 deletions

3
.gitignore vendored
View File

@ -151,3 +151,6 @@ compile_commands.json
CTestTestfile.cmake
*.dump
.vscode/c_cpp_properties.json
semihosting_test/build/semihosting_test
semihosting_test/build/Makefile

View File

@ -1,19 +1,172 @@
if (NOT DEFINED BOARD)
set(BOARD iss)
cmake_minimum_required(VERSION 3.12)
# Set default RISC-V toolchain if not specified
if(NOT DEFINED RISCV_TOOLCHAIN_PATH)
set(RISCV_TOOLCHAIN_PATH "/opt/shared/cross-toolchains/gcc13/CentOS/riscv64-unknown-elf/bin" CACHE STRING "Path to RISC-V toolchain")
endif()
if (NOT DEFINED ISA)
set(ISA imc)
# Allow override of compiler executables
if(NOT DEFINED RISCV_GCC)
set(RISCV_GCC "/opt/shared/cross-toolchains/gcc13/CentOS/riscv64-unknown-elf/bin/riscv64-unknown-elf-gcc" CACHE STRING "RISC-V GCC compiler")
endif()
message(STATUS "Building firmware using ${BOARD} board configuration")
add_custom_target(fw-hello-world ALL
COMMAND make -C ${riscvfw_SOURCE_DIR}/hello-world BOARD=${BOARD} ISA=${ISA}
USES_TERMINAL
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(fw-dhrystone ALL
COMMAND make -C ${riscvfw_SOURCE_DIR}/benchmarks/dhrystone BOARD=${BOARD} ISA=${ISA}
USES_TERMINAL
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(fw-coremark ALL
COMMAND make -C ${riscvfw_SOURCE_DIR}/benchmarks/coremark BOARD=${BOARD} ISA=${ISA}
USES_TERMINAL
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT DEFINED RISCV_GXX)
set(RISCV_GXX "${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf-g++" CACHE STRING "RISC-V G++ compiler")
endif()
if(NOT DEFINED RISCV_OBJCOPY)
set(RISCV_OBJCOPY "${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf-objcopy" CACHE STRING "RISC-V objcopy")
endif()
if(NOT DEFINED RISCV_OBJDUMP)
set(RISCV_OBJDUMP "${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf-objdump" CACHE STRING "RISC-V objdump")
endif()
# Set the compilers
set(CMAKE_C_COMPILER ${RISCV_GCC})
set(CMAKE_CXX_COMPILER ${RISCV_GXX})
project(Firmware)
# Define supported configurations
set(SUPPORTED_BOARDS iss)
set(SUPPORTED_ISAS "rv32i;rv32im;rv32imc;rv64i;rv64im;rv64imc;imc")
set(SUPPORTED_ABIS "ilp32;ilp32f;lp64;lp64f")
# Build target options
option(BUILD_HELLO_WORLD "Build hello-world example" ON)
option(BUILD_DHRYSTONE "Build dhrystone benchmark" OFF)
option(BUILD_COREMARK "Build coremark benchmark" OFF)
option(BUILD_ALL "Build all targets" OFF)
# If BUILD_ALL is ON, enable all targets
if(BUILD_ALL)
set(BUILD_HELLO_WORLD ON)
set(BUILD_DHRYSTONE ON)
set(BUILD_COREMARK ON)
endif()
# Set default values and validate configurations
if(NOT DEFINED BOARD)
set(BOARD iss CACHE STRING "Target board")
endif()
if(NOT DEFINED ISA)
set(ISA rv32imc CACHE STRING "Target ISA")
endif()
if(NOT DEFINED RISCV_ABI)
if(ISA MATCHES "^rv64")
set(RISCV_ABI "lp64" CACHE STRING "RISC-V ABI")
else()
set(RISCV_ABI "ilp32" CACHE STRING "RISC-V ABI")
endif()
endif()
# Validate configurations
if(NOT BOARD IN_LIST SUPPORTED_BOARDS)
message(FATAL_ERROR "Invalid BOARD specified. Supported boards: ${SUPPORTED_BOARDS}")
endif()
if(NOT ISA IN_LIST SUPPORTED_ISAS)
message(FATAL_ERROR "Invalid ISA specified(${ISA}). Supported ISAs: ${SUPPORTED_ISAS}")
endif()
if(NOT RISCV_ABI IN_LIST SUPPORTED_ABIS)
message(FATAL_ERROR "Invalid ABI specified. Supported ABIs: ${SUPPORTED_ABIS}")
endif()
# Set RISC-V architecture based on ISA
if(ISA MATCHES "^rv")
set(RISCV_ARCH ${ISA})
else()
# Default to rv32 for backward compatibility
set(RISCV_ARCH "rv32${ISA}")
endif()
# Set BSP base directory
set(BSP_BASE "${CMAKE_CURRENT_SOURCE_DIR}/bare-metal-bsp")
# Global compile definitions
add_compile_definitions(BOARD_${BOARD})
# RISC-V specific compiler flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -march=${RISCV_ARCH}_zicsr_zifencei -mabi=${RISCV_ABI} -mcmodel=medany")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -g -march=${RISCV_ARCH}_zicsr_zifencei -mabi=${RISCV_ABI} -mcmodel=medany")
#set(CMAKE_ASM_COMPILER riscv64-unknown-elf-as)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -O2 -g -march=${RISCV_ARCH}_zicsr_zifencei -mabi=${RISCV_ABI} -mcmodel=medany")
# Optional: Enable semihosting support
option(SEMIHOSTING "Enable semihosting support" OFF)
if(SEMIHOSTING)
add_compile_definitions(SEMIHOSTING)
endif()
#create interface library for propagating compile options
#add_library(global_compile_options INTERFACE)
# Compile options
#target_compile_options(global_compile_options INTERFACE
# -march=${RISCV_ARCH}_zicsr_zifencei
# -mabi=${RISCV_ABI}
# -mcmodel=medany
# -O2
# -g
# -ffunction-sections
# -fdata-sections
#)
message(STATUS "Building firmware with configuration:")
message(STATUS " Board: ${BOARD}")
message(STATUS " ISA: ${ISA} (Architecture: ${RISCV_ARCH})")
message(STATUS " ABI: ${RISCV_ABI}")
message(STATUS " Semihosting: ${SEMIHOSTING}")
message(STATUS " Toolchain:")
message(STATUS " Path: ${RISCV_TOOLCHAIN_PATH}")
message(STATUS " C Compiler: ${CMAKE_C_COMPILER}")
message(STATUS " C++ Compiler: ${CMAKE_CXX_COMPILER}")
message(STATUS "Targets to build:")
message(STATUS " hello-world: ${BUILD_HELLO_WORLD}")
message(STATUS " dhrystone: ${BUILD_DHRYSTONE}")
message(STATUS " coremark: ${BUILD_COREMARK}")
add_subdirectory(bare-metal-bsp)
# Add subdirectories based on build options
if(BUILD_HELLO_WORLD)
add_subdirectory(hello-world)
endif()
if(BUILD_DHRYSTONE)
add_subdirectory(benchmarks/dhrystone)
endif()
if(BUILD_COREMARK)
add_subdirectory(benchmarks/coremark)
endif()
# Create an all-inclusive target only if BUILD_ALL is ON
if(BUILD_ALL)
add_custom_target(fw-common ALL
DEPENDS
hello-world
dhrystone
coremark
)
endif()
# Print build instructions
message(STATUS "")
message(STATUS "Build instructions:")
message(STATUS " Build all targets: cmake -DBUILD_ALL=ON ..")
message(STATUS " Build specific target: cmake -DBUILD_HELLO_WORLD=ON -DBUILD_DHRYSTONE=OFF -DBUILD_COREMARK=OFF ..")
message(STATUS " Configure board: cmake -DBOARD=iss ..")
message(STATUS " Configure ISA: cmake -DISA=rv32imc ..")
message(STATUS " Configure ABI: cmake -DRISCV_ABI=ilp32 ..")
message(STATUS " Enable semihosting: cmake -DSEMIHOSTING=ON ..")
message(STATUS " Set toolchain path: cmake -DRISCV_TOOLCHAIN_PATH=/path/to/toolchain ..")
message(STATUS " Set specific compiler: cmake -DRISCV_GCC=/path/to/riscv-gcc -DRISCV_GXX=/path/to/riscv-g++ ..")

View File

@ -1,3 +1,25 @@
# Firmware
# MINRES Firmware Repository
## Structure
This repository comes with several executables ready to be built, such as `hello-world` or `coremark` and `dhrystone` in the `benchmark` directory.
Creating the executables in the easiest way possible is done by calling `make`in the corresponding directory.
Using `make clean && bear -- make ` will cause a correct compile_commands.json to be emitted. This allows using completion tools like clangd.
## Prerequisite
This repository requires `riscv64-unknown-elf-gcc` to be located in `$PATH`.
## How to Use
When compiling executables, the target platform needs to be specified using the 'BOARD' variable. When compiling for the TGC5C for example, use `make BOARD=tgc_vp`, when compiling for RTL `make BOARD=rtl`. The default value for the Board variable is 'iss'.
The arch can be set with the 'ISA' variable, the default value is 'imc'.
When compiling for the TGC5A VP for example, the call to create the correct binary is the following:
```
make BOARD=tgc_vp ISA=e
```
## Useful information
Using `bear -- <build-command>` will cause a compile_commands.json to be emitted. This allows using completion tools like clangd.
## Current Limitations
Currently, this repository only supports creation of 32-bit executables (Even when setting the `RISCV_ARCH` and `RISCV_ABI` manually).
Compiling for the 'e' extension / ISA together with any other extension (`ISA=emc` for example), requires setting the `RISCV_ABI=ilp32e` explicitly.
When switching ABI or ARCH ensure that object files in the corresponding 'env' dir in the 'bare-metal-bsp' submodule are removed, so they get created with the appropriate flags (namely the 'init.o' file).

View File

@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.12)
project(coremark C)
# Include BSP libwrap
include(${BSP_BASE}/libwrap/CMakeLists.txt)
# Source files
set(SOURCES
core_portme.c
cvt.c
ee_printf.c
cm/core_list_join.c
cm/core_main.c
cm/core_matrix.c
cm/core_state.c
cm/core_util.c
)
# Create executable
add_executable(coremark ${SOURCES})
# Include directories
target_include_directories(coremark PRIVATE
${BSP_BASE}/include
${BSP_BASE}/drivers
${BSP_BASE}/env
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/cm
)
# Link with libwrap
target_link_libraries(coremark PRIVATE
LIBWRAP_TGC
)
# Add compile definitions
target_compile_definitions(coremark PRIVATE
BOARD_${BOARD}
PERFORMANCE_RUN=1
ITERATIONS=1000
COMPILER_FLAGS="${CMAKE_C_FLAGS}"
COMPILER_VERSION="${CMAKE_C_COMPILER_VERSION}"
)
# Set compile options
target_compile_options(coremark PRIVATE
-march=${RISCV_ARCH}_zicsr_zifencei
-mabi=${RISCV_ABI}
-mcmodel=medany
-ffunction-sections
-fdata-sections
-O2 # Optimization level for benchmarking
)
# Set linker options
target_link_options(coremark PRIVATE
-T${BSP_BASE}/env/${BOARD}/link.ld
-nostartfiles
-Wl,--gc-sections
${LIBWRAP_TGC_LDFLAGS}
)
# Install target
install(TARGETS coremark
RUNTIME DESTINATION bin
)

View File

@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 3.12)
project(dhrystone C)
# Include BSP libwrap
include(${BSP_BASE}/libwrap/CMakeLists.txt)
# Source files
set(SOURCES
dhry_1.c
dhry_2.c
dhry_stubs.c
)
# Create executable
add_executable(dhrystone ${SOURCES})
# Include directories
target_include_directories(dhrystone PRIVATE
${BSP_BASE}/include
${BSP_BASE}/drivers
${BSP_BASE}/env
${CMAKE_CURRENT_SOURCE_DIR}
)
# Link with libwrap
target_link_libraries(dhrystone PRIVATE
LIBWRAP_TGC
)
# Add compile definitions
target_compile_definitions(dhrystone PRIVATE
BOARD_${BOARD}
)
# Set compile options
target_compile_options(dhrystone PRIVATE
-march=${RISCV_ARCH}_zicsr_zifencei
-mabi=${RISCV_ABI}
-mcmodel=medany
-ffunction-sections
-fdata-sections
-O2 # Optimization level for benchmarking
-DTIME # Enable time measurement
-DNOENUM # Disable enum usage as per dhrystone requirements
)
# Set linker options
target_link_options(dhrystone PRIVATE
-T${BSP_BASE}/env/${BOARD}/link.ld
-nostartfiles
-Wl,--gc-sections
${LIBWRAP_TGC_LDFLAGS}
)
# Install target
install(TARGETS dhrystone
RUNTIME DESTINATION bin
)

View File

@ -15,9 +15,8 @@ else
RISCV_ABI:=ilp32
endif
# '-lgcc -lm' are needed to add softfloat routines
CFLAGS := -g -march=$(RISCV_ARCH)_zicsr_zifencei -mabi=$(RISCV_ABI) -mcmodel=medlow -O3 -DITERATIONS=$(ITERATIONS) -DHZ=32768 -DTIME -DNO_INIT -fno-inline -fno-builtin-printf -fno-common -Wno-implicit \
CFLAGS := -g -O3 -DITERATIONS=$(ITERATIONS) -DHZ=32768 -DTIME -DNO_INIT -fno-inline -fno-builtin-printf -fno-common -Wno-implicit \
-funroll-loops -fpeel-loops -fgcse-sm -fgcse-las
LDFLAGS := -g -march=$(RISCV_ARCH)_zicsr_zifencei -mabi=$(RISCV_ABI) -mcmodel=medlow -Wl,--wrap=scanf -Wl,--wrap=printf -Wl,--wrap=exit -lgcc -lm
TOOL_DIR=$(dir $(compiler))

View File

@ -0,0 +1,75 @@
cmake_minimum_required(VERSION 3.12)
project(hello-world C)
# Set default board to iss if not specified
if(NOT DEFINED BOARD)
set(BOARD "iss" CACHE STRING "Target board")
endif()
# Source files
set(SOURCES
hello.c
)
message(STATUS "Building for board: ${BOARD}")
message(STATUS "liu:${PROJECT_NAME} ")
message(STATUS "Using board-specific files from: ${BSP_BASE}/env/${BOARD}")
# Create executable with all objects
add_executable(${PROJECT_NAME}
${SOURCES}
)
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".elf")
# Link with board library
#target_link_libraries(${PROJECT_NAME} PRIVATE
# libwrap
# ${BOARD}
# $<TARGET_OBJECTS:asm_obj>
# #$<TARGET_OBJECTS:env_start>
# )
# Include directories
target_include_directories(${PROJECT_NAME} PRIVATE
${BSP_BASE}/include
${BSP_BASE}/drivers
${BSP_BASE}/env
${BSP_BASE}/env/${BOARD}
${BSP_BASE}/libwrap
)
# Add compile definitions
target_compile_definitions(${PROJECT_NAME} PRIVATE
BOARD_${BOARD}
)
# link global_compile_options to this target ????
#target_link_libraries(${PROJECT_NAME} PRIVATE global_compile_options)
get_target_property(WRAP_LIBRARY_PATH libwrap ARCHIVE_OUTPUT_DIRECTORY)
get_target_property(BOARDLIBRARY_PATH ${BOARD} ARCHIVE_OUTPUT_DIRECTORY)
## TODDO ???
set(ASM_OBJ_LIB "${BOARDLIBRARY_PATH}/CMakeFiles/asm_obj.dir")
message(STATUS "in hello_world WRAP_LIBRARY_PATH : ${WRAP_LIBRARY_PATH}, BOARDLIBRARY_PATH : ${BOARDLIBRARY_PATH} ASM_OBJ_LIB: ${ASM_OBJ_LIB} ")
# Set linker options
target_link_options(${PROJECT_NAME} PRIVATE
--verbose
-L${ASM_OBJ_LIB}
-L${WRAP_LIBRARY_PATH}
-L${BOARDLIBRARY_PATH}
${ASM_OBJ_LIB}/start.S.o
${ASM_OBJ_LIB}/entry.S.o
-L/scratch/hongyu/workarea/Firmwares/build/bare-metal-bsp/env/CMakeFiles/asm_obj.dir
-g -Wl,--wrap=printf -march=rv32imc -mabi=ilp32 -L../bare-metal-bsp/env/ -Wl,--wrap=malloc -Wl,--wrap=open -Wl,--wrap=lseek -Wl,--wrap=_lseek -Wl,--wrap=read -Wl,--wrap=_read -Wl,--wrap=write -Wl,--wrap=_write -Wl,--wrap=fstat -Wl,--wrap=_fstat -Wl,--wrap=stat -Wl,--wrap=close -Wl,--wrap=_close -Wl,--wrap=link -Wl,--wrap=unlink -Wl,--wrap=execve -Wl,--wrap=fork -Wl,--wrap=getpid -Wl,--wrap=kill -Wl,--wrap=wait -Wl,--wrap=isatty -Wl,--wrap=times -Wl,--wrap=sbrk -Wl,--wrap=_sbrk -Wl,--wrap=exit -Wl,--wrap=_exit -Wl,--wrap=puts -Wl,--wrap=_puts -Wl,--wrap=printf -Wl,--wrap=sprintf -L. -Wl,--start-group -llibwrap -liss -lc -Wl,--end-group -T /scratch/hongyu/workarea/Firmwares/bare-metal-bsp/env/iss/link.lds -Wl,--no-warn-rwx-segments -Wl,-Map=hello.map -nostartfiles -o hello.elf
)
# Install target
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)