Created
July 21, 2019 17:59
-
-
Save benmezger/697118613191b469d4a1c6b8559faee1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PROGRAM = main | |
############################################################# | |
# Makefile Arguments | |
############################################################# | |
# BSP_DIR sets the path to the target-specific board support package. | |
BSP_DIR ?= $(abspath bsp) | |
# SRC_DIR sets the path to the program source directory | |
SRC_DIR ?= $(abspath kernel) | |
# The configuration defaults to Debug. Valid choices are: | |
# - debug | |
# - release | |
CONFIGURATION ?= debug | |
############################################################# | |
# BSP loading | |
############################################################# | |
# There must be a settings makefile fragment in the BSP's board directory. | |
ifeq ($(wildcard $(BSP_DIR)/settings.mk),) | |
$(error Unable to find BSP for $(TARGET), expected to find $(BSP_DIR)/settings.mk) | |
endif | |
# Include the BSP settings | |
include $(BSP_DIR)/settings.mk | |
# Check that settings.mk sets RISCV_ARCH and RISCV_ABI | |
ifeq ($(RISCV_ARCH),) | |
$(error $(BSP_DIR)/board.mk must set RISCV_ARCH, the RISC-V ISA string to target) | |
endif | |
ifeq ($(RISCV_ABI),) | |
$(error $(BSP_DIR)/board.mk must set RISCV_ABI, the ABI to target) | |
endif | |
ifeq ($(RISCV_CMODEL),) | |
RISCV_CMODEL = medany | |
endif | |
ifeq ($(PROGRAM),dhrystone) | |
ifeq ($(LINK_TARGET),) | |
ifneq ($(TARGET),freedom-e310-arty) | |
ifneq ($(TARGET),sifive-hifive1) | |
ifneq ($(TARGET),sifive-hifive1-revb) | |
LINK_TARGET = ramrodata | |
endif | |
endif | |
endif | |
endif | |
endif | |
ifeq ($(PROGRAM),coremark) | |
ifeq ($(LINK_TARGET),) | |
LINK_TARGET = ramrodata | |
endif | |
endif | |
ifeq ($(LINK_TARGET),) | |
LINK_TARGET = default | |
endif | |
# Determines the XLEN from the toolchain tuple | |
ifeq ($(patsubst rv32%,rv32,$(RISCV_ARCH)),rv32) | |
RISCV_XLEN := 32 | |
else ifeq ($(patsubst rv64%,rv64,$(RISCV_ARCH)),rv64) | |
RISCV_XLEN := 64 | |
else | |
$(error Unable to determine XLEN from $(RISCV_ARCH)) | |
endif | |
############################################################# | |
# Toolchain | |
############################################################# | |
# Allow users to select a different cross compiler. | |
CROSS_COMPILE ?= riscv64-unknown-elf | |
# If users don't specify RISCV_PATH then assume that the tools will just be in | |
# their path. | |
ifeq ($(RISCV_PATH),) | |
RISCV_GCC := $(CROSS_COMPILE)-gcc | |
RISCV_GXX := $(CROSS_COMPILE)-g++ | |
RISCV_OBJDUMP := $(CROSS_COMPILE)-objdump | |
RISCV_OBJCOPY := $(CROSS_COMPILE)-objcopy | |
RISCV_GDB := $(CROSS_COMPILE)-gdb | |
RISCV_AR := $(CROSS_COMPILE)-ar | |
RISCV_SIZE := $(CROSS_COMPILE)-size | |
else | |
RISCV_GCC := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-gcc) | |
RISCV_GXX := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-g++) | |
RISCV_OBJDUMP := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-objdump) | |
RISCV_OBJCOPY := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-objcopy) | |
RISCV_GDB := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-gdb) | |
RISCV_AR := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-ar) | |
RISCV_SIZE := $(abspath $(RISCV_PATH)/bin/$(CROSS_COMPILE)-size) | |
PATH := $(abspath $(RISCV_PATH)/bin):$(PATH) | |
endif | |
SEGGER_JLINK_EXE := JLinkExe | |
SEGGER_JLINK_GDB_SERVER := JLinkGDBServer | |
############################################################# | |
# Software Flags | |
############################################################# | |
# Set the arch, ABI, and code model | |
RISCV_CCASFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=$(RISCV_CMODEL) | |
RISCV_CFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=$(RISCV_CMODEL) | |
RISCV_CXXFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=$(RISCV_CMODEL) | |
RISCV_ASFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=$(RISCV_CMODEL) | |
# Prune unused functions and data | |
RISCV_CFLAGS += -ffunction-sections -fdata-sections | |
RISCV_CXXFLAGS += -ffunction-sections -fdata-sections | |
# Include the Metal headers | |
RISCV_CCASFLAGS += -I$(abspath $(BSP_DIR)/install/include/) | |
RISCV_CFLAGS += -I$(abspath $(BSP_DIR)/install/include/) | |
RISCV_CXXFLAGS += -I$(abspath $(BSP_DIR)/install/include/) | |
# Use newlib-nano | |
RISCV_CCASFLAGS += --specs=nano.specs | |
RISCV_CFLAGS += --specs=nano.specs | |
RISCV_CXXFLAGS += --specs=nano.specs | |
# Turn on garbage collection for unused sections | |
RISCV_LDFLAGS += -Wl,--gc-sections | |
# Turn on linker map file generation | |
RISCV_LDFLAGS += -Wl,-Map,$(PROGRAM).map | |
# Turn off the C standard library | |
RISCV_LDFLAGS += -nostartfiles -nostdlib | |
# Find the archive files and linker scripts | |
RISCV_LDFLAGS += -L$(sort $(dir $(abspath $(filter %.a,$^)))) -T$(abspath $(filter %.lds,$^)) | |
# Link to the relevant libraries | |
RISCV_LDLIBS += -Wl,--start-group -lc -lgcc -lmetal -lmetal-gloss -Wl,--end-group | |
# Load the configuration Makefile | |
CONFIGURATION_FILE = $(wildcard $(CONFIGURATION).mk) | |
ifeq ($(words $(CONFIGURATION_FILE)),0) | |
$(error Unable to find the Makefile $(CONFIGURATION).mk for CONFIGURATION=$(CONFIGURATION)) | |
endif | |
include $(CONFIGURATION).mk | |
# Benchmark CFLAGS go after loading the CONFIGURATION so that they can override the optimization level | |
ifeq ($(PROGRAM),dhrystone) | |
ifeq ($(DHRY_OPTION),) | |
# Ground rules (default) | |
RISCV_XCFLAGS += -mexplicit-relocs -fno-inline | |
else ifeq ($(DHRY_OPTION),fast) | |
# With inline and without lto | |
RISCV_XCFLAGS += -mexplicit-relocs -finline | |
else ifeq ($(DHRY_OPTION),best) | |
# Best Score | |
RISCV_XCFLAGS += -finline -flto -fwhole-program | |
endif | |
RISCV_XCFLAGS += -DDHRY_ITERS=$(TARGET_DHRY_ITERS) | |
endif | |
ifeq ($(PROGRAM),coremark) | |
ifeq ($(RISCV_SERIES),sifive-7-series) | |
RISCV_XCFLAGS += -O2 -fno-common -funroll-loops -finline-functions -funroll-all-loops --param max-inline-insns-auto=20 -falign-functions=8 -falign-jumps=8 -falign-loops=8 --param inline-min-speedup=10 -mtune=sifive-7-series -ffast-math | |
else | |
RISCV_XCFLAGS += -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4 --param inline-min-speedup=10 | |
endif | |
RISCV_XCFLAGS += -DITERATIONS=$(TARGET_CORE_ITERS) | |
endif | |
############################################################# | |
# Software | |
############################################################# | |
PROGRAM_ELF ?= $(SRC_DIR)/$(CONFIGURATION)/$(PROGRAM).elf | |
PROGRAM_HEX ?= $(SRC_DIR)/$(CONFIGURATION)/$(PROGRAM).hex | |
PROGRAM_LST ?= $(SRC_DIR)/$(CONFIGURATION)/$(PROGRAM).lst | |
.PHONY: all | |
all: software | |
.PHONY: software | |
software: $(PROGRAM_ELF) | |
software: $(PROGRAM_HEX) | |
PROGRAM_SRCS = $(wildcard $(SRC_DIR)/*.c) $(wildcard $(SRC_DIR)/*.h) $(wildcard $(SRC_DIR)/*.S) | |
$(PROGRAM_ELF): \ | |
$(PROGRAM_SRCS) \ | |
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal.a \ | |
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal-gloss.a \ | |
$(BSP_DIR)/metal.$(LINK_TARGET).lds | |
mkdir -p $(dir $@) | |
$(MAKE) -C $(SRC_DIR) $(basename $(notdir $@)) \ | |
PORT_DIR=$(PORT_DIR) \ | |
AR=$(RISCV_AR) \ | |
CC=$(RISCV_GCC) \ | |
CXX=$(RISCV_GXX) \ | |
ASFLAGS="$(RISCV_ASFLAGS)" \ | |
CCASFLAGS="$(RISCV_CCASFLAGS)" \ | |
CFLAGS="$(RISCV_CFLAGS)" \ | |
CXXFLAGS="$(RISCV_CXXFLAGS)" \ | |
XCFLAGS="$(RISCV_XCFLAGS)" \ | |
LDFLAGS="$(RISCV_LDFLAGS)" \ | |
LDLIBS="$(RISCV_LDLIBS)" | |
mv $(SRC_DIR)/$(basename $(notdir $@)).map $(dir $@) | |
mv $(SRC_DIR)/$(basename $(notdir $@)) $@ | |
touch -c $@ | |
$(RISCV_OBJDUMP) --source --all-headers --demangle --line-numbers --wide $@ > $(PROGRAM_LST) | |
$(RISCV_SIZE) $@ | |
# Use elf2hex if we're creating a hex file for RTL simulation | |
ifneq ($(filter rtl,$(TARGET_TAGS)),) | |
.PHONY: software | |
$(PROGRAM_HEX): \ | |
scripts/elf2hex/install/bin/$(CROSS_COMPILE)-elf2hex \ | |
$(PROGRAM_ELF) | |
$< --output $@ --input $(PROGRAM_ELF) --bit-width $(COREIP_MEM_WIDTH) | |
else | |
$(PROGRAM_HEX): \ | |
$(PROGRAM_ELF) | |
$(RISCV_OBJCOPY) -O ihex $(PROGRAM_ELF) $@ | |
endif | |
.PHONY: clean-kernel | |
clean-kernel: | |
rm -rf $(SRC_DIR)/$(CONFIGURATION) | |
rm -rf $(SRC_DIR)/$(PROGRAM) $(PROGRAM).hex | |
.PHONY: clean | |
clean: clean-kernel | |
############################################################# | |
# elf2hex | |
############################################################# | |
scripts/elf2hex/build/Makefile: scripts/elf2hex/configure | |
@rm -rf $(dir $@) | |
@mkdir -p $(dir $@) | |
cd $(dir $@); \ | |
$(abspath $<) \ | |
--prefix=$(abspath $(dir $<))/install \ | |
--target=$(CROSS_COMPILE) | |
scripts/elf2hex/install/bin/$(CROSS_COMPILE)-elf2hex: scripts/elf2hex/build/Makefile | |
$(MAKE) -C $(dir $<) install | |
touch -c $@ | |
.PHONY: clean-elf2hex | |
clean-elf2hex: | |
rm -rf scripts/elf2hex/build scripts/elf2hex/install | |
clean: clean-elf2hex | |
############################################################# | |
# Compiles an instance of Metal targeted at $(TARGET) | |
############################################################# | |
METAL_SOURCE_PATH ?= freedom-metal | |
METAL_LDSCRIPT = $(BSP_DIR)/metal.$(LINK_TARGET).lds | |
METAL_HEADER = $(BSP_DIR)/metal.h | |
METAL_INLINE = $(BSP_DIR)/metal-inline.h | |
PLATFORM_HEADER = $(BSP_DIR)/metal-platform.h | |
METAL_PREFIX = $(abspath $(BSP_DIR)/install) | |
METAL_BUILD_DIR = $(abspath $(BSP_DIR)/build/$(CONFIGURATION)) | |
METAL_LIB_DIR = $(abspath $(BSP_DIR)/install/lib/$(CONFIGURATION)) | |
.PHONY: metal | |
metal: $(METAL_LIB_DIR)/stamp | |
$(METAL_BUILD_DIR)/Makefile: | |
@rm -rf $(dir $@) | |
@mkdir -p $(dir $@) | |
cd $(dir $@) && \ | |
CFLAGS="$(RISCV_CFLAGS)" \ | |
$(abspath $(METAL_SOURCE_PATH)/configure) \ | |
--host=$(CROSS_COMPILE) \ | |
--prefix=$(METAL_PREFIX) \ | |
--libdir=$(METAL_LIB_DIR) \ | |
--disable-maintainer-mode \ | |
--with-preconfigured \ | |
--with-machine-name=$(TARGET) \ | |
--with-machine-header=$(abspath $(METAL_HEADER)) \ | |
--with-machine-inline=$(abspath $(METAL_INLINE)) \ | |
--with-platform-header=$(abspath $(PLATFORM_HEADER)) \ | |
--with-machine-ldscript=$(abspath $(METAL_LDSCRIPT)) \ | |
--with-builtin-libgloss | |
touch -c $@ | |
$(METAL_LIB_DIR)/stamp: $(BSP_DIR)/build/$(CONFIGURATION)/Makefile | |
$(MAKE) -C $(abspath $(BSP_DIR)/build/$(CONFIGURATION)) install | |
date > $@ | |
$(METAL_LIB_DIR)/libriscv%.a: $(METAL_LIB_DIR)/stamp ;@: | |
$(METAL_LIB_DIR)/libmetal.a: $(METAL_LIB_DIR)/libriscv__mmachine__$(TARGET).a | |
cp $< $@ | |
$(METAL_LIB_DIR)/libmetal-gloss.a: $(METAL_LIB_DIR)/libriscv__menv__metal.a | |
cp $< $@ | |
# If we're cleaning the last Metal library for a TARGET, then remove | |
# the install directory, otherwise just remove the built libs for that | |
# CONFIGURATION. | |
ifeq ($(words $(wildcard $(METAL_PREFIX)/lib/*)),1) | |
METAL_CLEAN = $(METAL_PREFIX) | |
else | |
METAL_CLEAN = $(METAL_LIB_DIR) | |
endif | |
.PHONY: clean-metal | |
clean-metal: | |
rm -rf $(METAL_CLEAN) | |
rm -rf $(METAL_BUILD_DIR) | |
clean: clean-metal | |
metal_install: metal | |
$(MAKE) -C $(METAL_SOURCE_PATH) install | |
upload: | |
$(FREEDOME_SDK)/scripts/upload --hex $(SRC_DIR)/debug/main.hex --jlink JLinkExe | |
ifneq ($(filter jlink,$(TARGET_TAGS)),) | |
debug: $(PROGRAM_ELF) | |
$(FREEDOME_SDK)/scripts/debug --elf $(PROGRAM_ELF) --jlink $(SEGGER_JLINK_GDB_SERVER) --gdb $(RISCV_GDB) | |
upload_debug: $(PROGRAM_ELF) | |
$(FREEDOME_SDK)/scripts/debug --elf $(PROGRAM_ELF) --jlink $(SEGGER_JLINK_GDB_SERVER) --gdb $(RISCV_GDB) | |
else | |
debug: $(PROGRAM_ELF) | |
$(FREEDOME_SDK)/scripts/debug --elf $(PROGRAM_ELF) --openocd $(RISCV_OPENOCD) --gdb $(RISCV_GDB) --openocd-config bsp/$(TARGET)/openocd.cfg | |
upload_debug: $(PROGRAM_ELF) | |
$(FREEDOME_SDK)/scripts/debug --elf $(PROGRAM_ELF) --openocd $(RISCV_OPENOCD) --gdb $(RISCV_GDB) --openocd-config bsp/$(TARGET)/openocd.cfg | |
endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment