mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 15:31:22 +01:00

OpenSBI is compiled with -fPIE, which generally implies dynamic linking. This causes the compiler to generate GOT references for global symbols in order to support runtime symbol interposition. However, OpenSBI does not actually perform dynamic linking, so the GOT indirection just adds unnecessary overhead. The GOT references can be avoided by declaring global symbols with hidden visibility, thus making them local to this dynamic object and non-interposable. GCC/Clang's -fvisibility parameter is insufficient for this purpose when referencing objects from other translation units; either __attribute__((visibility(...)) or the pragma is required. Use the pragma since it is easier to apply to every symbol. Additionally clean up the one GOT reference from inline assembly. With this change, a firmware linked with LLD does not contain either a GOT or a PLT, and a firmware linked with BFD ld contains only a GOT with a single (unreferenced, legacy) _GLOBAL_OFFSET_TABLE_ entry. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org>
738 lines
26 KiB
Makefile
738 lines
26 KiB
Makefile
#
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
#
|
|
# Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
|
#
|
|
# Authors:
|
|
# Anup Patel <anup.patel@wdc.com>
|
|
#
|
|
|
|
# Select Make Options:
|
|
# o Do not use make's built-in rules
|
|
# o Do not print "Entering directory ...";
|
|
MAKEFLAGS += -r --no-print-directory
|
|
|
|
# Readlink -f requires GNU readlink
|
|
ifeq ($(shell uname -s),Darwin)
|
|
READLINK ?= greadlink
|
|
else
|
|
READLINK ?= readlink
|
|
endif
|
|
|
|
# Find out source, build, and install directories
|
|
src_dir=$(CURDIR)
|
|
ifdef O
|
|
build_dir=$(shell $(READLINK) -f $(O))
|
|
else
|
|
build_dir=$(CURDIR)/build
|
|
endif
|
|
ifeq ($(build_dir),$(CURDIR))
|
|
$(error Build directory is same as source directory.)
|
|
endif
|
|
install_root_dir_default=$(CURDIR)/install
|
|
ifdef I
|
|
install_root_dir=$(shell $(READLINK) -f $(I))
|
|
else
|
|
install_root_dir=$(install_root_dir_default)/usr
|
|
endif
|
|
ifeq ($(install_root_dir),$(CURDIR))
|
|
$(error Install root directory is same as source directory.)
|
|
endif
|
|
ifeq ($(install_root_dir),$(build_dir))
|
|
$(error Install root directory is same as build directory.)
|
|
endif
|
|
ifdef PLATFORM_DIR
|
|
platform_dir_path=$(shell $(READLINK) -f $(PLATFORM_DIR))
|
|
ifdef PLATFORM
|
|
platform_parent_dir=$(platform_dir_path)
|
|
else
|
|
PLATFORM=$(shell basename $(platform_dir_path))
|
|
platform_parent_dir=$(shell realpath ${platform_dir_path}/..)
|
|
endif
|
|
else
|
|
platform_parent_dir=$(src_dir)/platform
|
|
endif
|
|
ifndef PLATFORM_DEFCONFIG
|
|
PLATFORM_DEFCONFIG=defconfig
|
|
endif
|
|
|
|
# Check if verbosity is ON for build process
|
|
CMD_PREFIX_DEFAULT := @
|
|
ifeq ($(V), 1)
|
|
CMD_PREFIX :=
|
|
else
|
|
CMD_PREFIX := $(CMD_PREFIX_DEFAULT)
|
|
endif
|
|
|
|
# Setup path of directories
|
|
export platform_subdir=$(PLATFORM)
|
|
export platform_src_dir=$(platform_parent_dir)/$(platform_subdir)
|
|
export platform_build_dir=$(build_dir)/platform/$(platform_subdir)
|
|
export include_dir=$(CURDIR)/include
|
|
export libsbi_dir=$(CURDIR)/lib/sbi
|
|
export libsbiutils_dir=$(CURDIR)/lib/utils
|
|
export firmware_dir=$(CURDIR)/firmware
|
|
|
|
# Setup variables for kconfig
|
|
ifdef PLATFORM
|
|
export PYTHONDONTWRITEBYTECODE=1
|
|
export KCONFIG_DIR=$(platform_build_dir)/kconfig
|
|
export KCONFIG_AUTOLIST=$(KCONFIG_DIR)/auto.list
|
|
export KCONFIG_AUTOHEADER=$(KCONFIG_DIR)/autoconf.h
|
|
export KCONFIG_AUTOCONFIG=$(KCONFIG_DIR)/auto.conf
|
|
export KCONFIG_AUTOCMD=$(KCONFIG_DIR)/auto.conf.cmd
|
|
export KCONFIG_CONFIG=$(KCONFIG_DIR)/.config
|
|
# Additional exports for include paths in Kconfig files
|
|
export OPENSBI_SRC_DIR=$(src_dir)
|
|
export OPENSBI_PLATFORM=$(PLATFORM)
|
|
export OPENSBI_PLATFORM_SRC_DIR=$(platform_src_dir)
|
|
endif
|
|
|
|
# Find library version
|
|
OPENSBI_VERSION_MAJOR=`grep "define OPENSBI_VERSION_MAJOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MAJOR.*\([0-9][0-9]*\)/\1/'`
|
|
OPENSBI_VERSION_MINOR=`grep "define OPENSBI_VERSION_MINOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MINOR.*\([0-9][0-9]*\)/\1/'`
|
|
OPENSBI_VERSION_GIT=
|
|
|
|
# Detect 'git' presence before issuing 'git' commands
|
|
GIT_AVAIL=$(shell command -v git 2> /dev/null)
|
|
ifneq ($(GIT_AVAIL),)
|
|
GIT_DIR=$(shell git rev-parse --git-dir 2> /dev/null)
|
|
ifneq ($(GIT_DIR),)
|
|
OPENSBI_VERSION_GIT=$(shell if [ -d $(GIT_DIR) ]; then git describe 2> /dev/null; fi)
|
|
endif
|
|
endif
|
|
|
|
# Setup compilation commands
|
|
ifneq ($(LLVM),)
|
|
CC = clang
|
|
AR = llvm-ar
|
|
LD = ld.lld
|
|
OBJCOPY = llvm-objcopy
|
|
else
|
|
ifdef CROSS_COMPILE
|
|
CC = $(CROSS_COMPILE)gcc
|
|
AR = $(CROSS_COMPILE)ar
|
|
LD = $(CROSS_COMPILE)ld
|
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
|
else
|
|
CC ?= gcc
|
|
AR ?= ar
|
|
LD ?= ld
|
|
OBJCOPY ?= objcopy
|
|
endif
|
|
endif
|
|
CPP = $(CC) -E
|
|
AS = $(CC)
|
|
DTC = dtc
|
|
|
|
ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),)
|
|
CC_IS_CLANG = y
|
|
else
|
|
CC_IS_CLANG = n
|
|
endif
|
|
|
|
ifneq ($(shell $(LD) --version 2>&1 | head -n 1 | grep LLD),)
|
|
LD_IS_LLD = y
|
|
else
|
|
LD_IS_LLD = n
|
|
endif
|
|
|
|
ifeq ($(CC_IS_CLANG),y)
|
|
ifneq ($(CROSS_COMPILE),)
|
|
CLANG_TARGET = --target=$(notdir $(CROSS_COMPILE:%-=%))
|
|
endif
|
|
endif
|
|
|
|
# Guess the compiler's XLEN
|
|
OPENSBI_CC_XLEN := $(shell TMP=`$(CC) $(CLANG_TARGET) -dumpmachine | sed 's/riscv\([0-9][0-9]\).*/\1/'`; echo $${TMP})
|
|
|
|
# Guess the compiler's ABI and ISA
|
|
ifneq ($(CC_IS_CLANG),y)
|
|
OPENSBI_CC_ABI := $(shell TMP=`$(CC) -v 2>&1 | sed -n 's/.*\(with\-abi=\([a-zA-Z0-9]*\)\).*/\2/p'`; echo $${TMP})
|
|
OPENSBI_CC_ISA := $(shell TMP=`$(CC) -v 2>&1 | sed -n 's/.*\(with\-arch=\([a-zA-Z0-9]*\)\).*/\2/p'`; echo $${TMP})
|
|
endif
|
|
|
|
# Setup platform XLEN
|
|
ifndef PLATFORM_RISCV_XLEN
|
|
ifeq ($(OPENSBI_CC_XLEN), 32)
|
|
PLATFORM_RISCV_XLEN = 32
|
|
else
|
|
PLATFORM_RISCV_XLEN = 64
|
|
endif
|
|
endif
|
|
|
|
ifeq ($(CC_IS_CLANG),y)
|
|
ifeq ($(CROSS_COMPILE),)
|
|
CLANG_TARGET = --target=riscv$(PLATFORM_RISCV_XLEN)-unknown-elf
|
|
endif
|
|
endif
|
|
|
|
ifeq ($(LD_IS_LLD),y)
|
|
RELAX_FLAG = -mno-relax
|
|
USE_LD_FLAG = -fuse-ld=lld
|
|
else
|
|
USE_LD_FLAG = -fuse-ld=bfd
|
|
endif
|
|
|
|
# Check whether the linker supports creating PIEs
|
|
OPENSBI_LD_PIE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) $(USE_LD_FLAG) -fPIE -nostdlib -Wl,-pie -x c /dev/null -o /dev/null >/dev/null 2>&1 && echo y || echo n)
|
|
|
|
# Check whether the linker supports --exclude-libs
|
|
OPENSBI_LD_EXCLUDE_LIBS := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) $(USE_LD_FLAG) "-Wl,--exclude-libs,ALL" -x c /dev/null -o /dev/null >/dev/null 2>&1 && echo y || echo n)
|
|
|
|
# Check whether the compiler supports -m(no-)save-restore
|
|
CC_SUPPORT_SAVE_RESTORE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -mno-save-restore -x c /dev/null -o /dev/null 2>&1 | grep -e "-save-restore" >/dev/null && echo n || echo y)
|
|
|
|
# Check whether the compiler supports -m(no-)strict-align
|
|
CC_SUPPORT_STRICT_ALIGN := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -mstrict-align -x c /dev/null -o /dev/null 2>&1 | grep -e "-mstrict-align" -e "-mno-unaligned-access" >/dev/null && echo n || echo y)
|
|
|
|
# Check whether the assembler and the compiler support the Zicsr and Zifencei extensions
|
|
CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y)
|
|
|
|
# Check whether the assembler and the compiler support the Vector extension
|
|
CC_SUPPORT_VECTOR := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)gv -dM -E -x c /dev/null 2>&1 | grep -q riscv.*vector && echo y || echo n)
|
|
|
|
ifneq ($(OPENSBI_LD_PIE),y)
|
|
$(error Your linker does not support creating PIEs, opensbi requires this.)
|
|
endif
|
|
|
|
# Build Info:
|
|
# OPENSBI_BUILD_TIME_STAMP -- the compilation time stamp
|
|
# OPENSBI_BUILD_COMPILER_VERSION -- the compiler version info
|
|
BUILD_INFO ?= n
|
|
ifeq ($(BUILD_INFO),y)
|
|
OPENSBI_BUILD_DATE_FMT = +%Y-%m-%d %H:%M:%S %z
|
|
ifdef SOURCE_DATE_EPOCH
|
|
OPENSBI_BUILD_TIME_STAMP ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" \
|
|
"$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \
|
|
date -u -r "$(SOURCE_DATE_EPOCH)" \
|
|
"$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \
|
|
date -u "$(OPENSBI_BUILD_DATE_FMT)")
|
|
else
|
|
OPENSBI_BUILD_TIME_STAMP ?= $(shell date "$(OPENSBI_BUILD_DATE_FMT)")
|
|
endif
|
|
OPENSBI_BUILD_COMPILER_VERSION=$(shell $(CC) -v 2>&1 | grep ' version ' | \
|
|
sed 's/[[:space:]]*$$//')
|
|
endif
|
|
|
|
# Setup list of objects.mk files
|
|
ifdef PLATFORM
|
|
platform-object-mks=$(shell if [ -d $(platform_src_dir)/ ]; then find $(platform_src_dir) -iname "objects.mk" | sort -r; fi)
|
|
endif
|
|
libsbi-object-mks=$(shell if [ -d $(libsbi_dir) ]; then find $(libsbi_dir) -iname "objects.mk" | sort -r; fi)
|
|
libsbiutils-object-mks=$(shell if [ -d $(libsbiutils_dir) ]; then find $(libsbiutils_dir) -iname "objects.mk" | sort -r; fi)
|
|
firmware-object-mks=$(shell if [ -d $(firmware_dir) ]; then find $(firmware_dir) -iname "objects.mk" | sort -r; fi)
|
|
|
|
# The "make all" rule should always be first rule
|
|
.PHONY: all
|
|
all:
|
|
|
|
# Include platform specific .config
|
|
ifdef PLATFORM
|
|
.PHONY: menuconfig
|
|
menuconfig: $(platform_src_dir)/Kconfig $(src_dir)/Kconfig
|
|
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
|
|
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/menuconfig.py $(src_dir)/Kconfig
|
|
|
|
.PHONY: savedefconfig
|
|
savedefconfig: $(platform_src_dir)/Kconfig $(src_dir)/Kconfig
|
|
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
|
|
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/savedefconfig.py --kconfig $(src_dir)/Kconfig --out $(KCONFIG_DIR)/defconfig
|
|
|
|
$(KCONFIG_CONFIG): $(platform_src_dir)/configs/$(PLATFORM_DEFCONFIG)
|
|
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
|
|
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/defconfig.py --kconfig $(src_dir)/Kconfig $(platform_src_dir)/configs/$(PLATFORM_DEFCONFIG)
|
|
|
|
$(KCONFIG_AUTOCONFIG): $(KCONFIG_CONFIG)
|
|
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/genconfig.py --header-path $(KCONFIG_AUTOHEADER) --sync-deps $(KCONFIG_DIR) --file-list $(KCONFIG_AUTOLIST) $(src_dir)/Kconfig
|
|
|
|
$(KCONFIG_AUTOHEADER): $(KCONFIG_AUTOCONFIG);
|
|
|
|
$(KCONFIG_AUTOLIST): $(KCONFIG_AUTOCONFIG);
|
|
|
|
$(KCONFIG_AUTOCMD): $(KCONFIG_AUTOLIST)
|
|
$(CMD_PREFIX)printf "%s: " $(KCONFIG_CONFIG) > $(KCONFIG_AUTOCMD)
|
|
$(CMD_PREFIX)cat $(KCONFIG_AUTOLIST) | tr '\n' ' ' >> $(KCONFIG_AUTOCMD)
|
|
|
|
include $(KCONFIG_AUTOCONFIG)
|
|
include $(KCONFIG_AUTOCMD)
|
|
endif
|
|
|
|
# Include all objects.mk files
|
|
ifdef PLATFORM
|
|
include $(platform-object-mks)
|
|
endif
|
|
include $(libsbi-object-mks)
|
|
include $(libsbiutils-object-mks)
|
|
include $(firmware-object-mks)
|
|
|
|
# Setup list of objects
|
|
libsbi-objs-path-y=$(foreach obj,$(libsbi-objs-y),$(build_dir)/lib/sbi/$(obj))
|
|
ifdef PLATFORM
|
|
libsbiutils-objs-path-y=$(foreach obj,$(libsbiutils-objs-y),$(platform_build_dir)/lib/utils/$(obj))
|
|
platform-objs-path-y=$(foreach obj,$(platform-objs-y),$(platform_build_dir)/$(obj))
|
|
firmware-bins-path-y=$(foreach bin,$(firmware-bins-y),$(platform_build_dir)/firmware/$(bin))
|
|
endif
|
|
firmware-elfs-path-y=$(firmware-bins-path-y:.bin=.elf)
|
|
firmware-objs-path-y=$(firmware-bins-path-y:.bin=.o)
|
|
|
|
# Setup list of deps files for objects
|
|
deps-y=$(platform-objs-path-y:.o=.dep)
|
|
deps-y+=$(libsbi-objs-path-y:.o=.dep)
|
|
deps-y+=$(libsbiutils-objs-path-y:.o=.dep)
|
|
deps-y+=$(firmware-objs-path-y:.o=.dep)
|
|
deps-y+=$(firmware-elfs-path-y:=.dep)
|
|
|
|
# Setup platform ABI, ISA and Code Model
|
|
ifndef PLATFORM_RISCV_ABI
|
|
ifneq ($(PLATFORM_RISCV_TOOLCHAIN_DEFAULT), 1)
|
|
ifeq ($(PLATFORM_RISCV_XLEN), 32)
|
|
PLATFORM_RISCV_ABI = ilp$(PLATFORM_RISCV_XLEN)
|
|
else
|
|
PLATFORM_RISCV_ABI = lp$(PLATFORM_RISCV_XLEN)
|
|
endif
|
|
else
|
|
PLATFORM_RISCV_ABI = $(OPENSBI_CC_ABI)
|
|
endif
|
|
endif
|
|
ifndef PLATFORM_RISCV_ISA
|
|
ifneq ($(PLATFORM_RISCV_TOOLCHAIN_DEFAULT), 1)
|
|
PLATFORM_RISCV_ISA := rv$(PLATFORM_RISCV_XLEN)imafdc
|
|
ifeq ($(CC_SUPPORT_ZICSR_ZIFENCEI), y)
|
|
PLATFORM_RISCV_ISA := $(PLATFORM_RISCV_ISA)_zicsr_zifencei
|
|
endif
|
|
else
|
|
PLATFORM_RISCV_ISA = $(OPENSBI_CC_ISA)
|
|
endif
|
|
endif
|
|
ifndef PLATFORM_RISCV_CODE_MODEL
|
|
PLATFORM_RISCV_CODE_MODEL = medany
|
|
endif
|
|
|
|
# Setup install directories
|
|
ifdef INSTALL_INCLUDE_PATH
|
|
install_include_path=$(INSTALL_INCLUDE_PATH)
|
|
else
|
|
install_include_path=include
|
|
endif
|
|
ifdef INSTALL_LIB_PATH
|
|
install_lib_path=$(INSTALL_LIB_PATH)
|
|
else
|
|
ifneq ($(origin INSTALL_LIB_SUBDIR), undefined)
|
|
install_lib_subdir=$(INSTALL_LIB_SUBDIR)
|
|
else
|
|
install_lib_subdir=$(PLATFORM_RISCV_ABI)
|
|
endif
|
|
install_lib_path=lib$(subst 32,,$(PLATFORM_RISCV_XLEN))/$(install_lib_subdir)
|
|
endif
|
|
ifdef INSTALL_FIRMWARE_PATH
|
|
install_firmware_path=$(INSTALL_FIRMWARE_PATH)
|
|
else
|
|
install_firmware_path=share/opensbi/$(PLATFORM_RISCV_ABI)
|
|
endif
|
|
ifdef INSTALL_DOCS_PATH
|
|
install_docs_path=$(INSTALL_DOCS_PATH)
|
|
else
|
|
install_docs_path=share/opensbi/docs
|
|
endif
|
|
|
|
# Setup compilation commands flags
|
|
ifeq ($(CC_IS_CLANG),y)
|
|
GENFLAGS += $(CLANG_TARGET)
|
|
GENFLAGS += -Wno-unused-command-line-argument
|
|
endif
|
|
GENFLAGS += -I$(platform_src_dir)/include
|
|
GENFLAGS += -I$(include_dir)
|
|
ifneq ($(OPENSBI_VERSION_GIT),)
|
|
GENFLAGS += -DOPENSBI_VERSION_GIT="\"$(OPENSBI_VERSION_GIT)\""
|
|
endif
|
|
ifeq ($(BUILD_INFO),y)
|
|
GENFLAGS += -DOPENSBI_BUILD_TIME_STAMP="\"$(OPENSBI_BUILD_TIME_STAMP)\""
|
|
GENFLAGS += -DOPENSBI_BUILD_COMPILER_VERSION="\"$(OPENSBI_BUILD_COMPILER_VERSION)\""
|
|
endif
|
|
GENFLAGS += -include $(include_dir)/sbi/sbi_visibility.h
|
|
ifdef PLATFORM
|
|
GENFLAGS += -include $(KCONFIG_AUTOHEADER)
|
|
endif
|
|
GENFLAGS += $(libsbiutils-genflags-y)
|
|
GENFLAGS += $(platform-genflags-y)
|
|
GENFLAGS += $(firmware-genflags-y)
|
|
|
|
CFLAGS = -g -Wall -Werror -ffreestanding -nostdlib -fno-stack-protector -fno-strict-aliasing -ffunction-sections -fdata-sections
|
|
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
|
# Optionally supported flags
|
|
ifeq ($(CC_SUPPORT_VECTOR),y)
|
|
CFLAGS += -DOPENSBI_CC_SUPPORT_VECTOR
|
|
endif
|
|
ifeq ($(CC_SUPPORT_SAVE_RESTORE),y)
|
|
CFLAGS += -mno-save-restore
|
|
endif
|
|
ifeq ($(CC_SUPPORT_STRICT_ALIGN),y)
|
|
CFLAGS += -mstrict-align
|
|
endif
|
|
CFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
|
|
CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
|
|
CFLAGS += $(RELAX_FLAG)
|
|
CFLAGS += $(GENFLAGS)
|
|
CFLAGS += $(platform-cflags-y)
|
|
CFLAGS += -fPIE -pie
|
|
CFLAGS += $(firmware-cflags-y)
|
|
|
|
CPPFLAGS += $(GENFLAGS)
|
|
CPPFLAGS += $(platform-cppflags-y)
|
|
CPPFLAGS += $(firmware-cppflags-y)
|
|
|
|
ASFLAGS = -g -Wall -nostdlib
|
|
ASFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
|
ASFLAGS += -fPIE
|
|
# Optionally supported flags
|
|
ifeq ($(CC_SUPPORT_SAVE_RESTORE),y)
|
|
ASFLAGS += -mno-save-restore
|
|
endif
|
|
ifeq ($(CC_SUPPORT_STRICT_ALIGN),y)
|
|
ASFLAGS += -mstrict-align
|
|
endif
|
|
ASFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
|
|
ASFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
|
|
ASFLAGS += $(RELAX_FLAG)
|
|
ifneq ($(CC_IS_CLANG),y)
|
|
ifneq ($(RELAX_FLAG),)
|
|
ASFLAGS += -Wa,$(RELAX_FLAG)
|
|
endif
|
|
endif
|
|
ASFLAGS += $(GENFLAGS)
|
|
ASFLAGS += $(platform-asflags-y)
|
|
ASFLAGS += $(firmware-asflags-y)
|
|
|
|
ARFLAGS = rcs
|
|
|
|
ELFFLAGS += $(USE_LD_FLAG)
|
|
ELFFLAGS += -Wl,--gc-sections
|
|
ifeq ($(OPENSBI_LD_EXCLUDE_LIBS),y)
|
|
ELFFLAGS += -Wl,--exclude-libs,ALL
|
|
endif
|
|
ELFFLAGS += -Wl,--build-id=none
|
|
ELFFLAGS += -Wl,--no-dynamic-linker -Wl,-pie
|
|
ELFFLAGS += $(platform-ldflags-y)
|
|
ELFFLAGS += $(firmware-ldflags-y)
|
|
|
|
MERGEFLAGS += -r
|
|
ifeq ($(LD_IS_LLD),y)
|
|
MERGEFLAGS += -b elf
|
|
else
|
|
MERGEFLAGS += -b elf$(PLATFORM_RISCV_XLEN)-littleriscv
|
|
endif
|
|
MERGEFLAGS += -m elf$(PLATFORM_RISCV_XLEN)lriscv
|
|
|
|
DTSCPPFLAGS = $(CPPFLAGS) -nostdinc -nostdlib -fno-builtin -D__DTS__ -x assembler-with-cpp
|
|
|
|
ifneq ($(DEBUG),)
|
|
CFLAGS += -O0
|
|
ELFFLAGS += -Wl,--print-gc-sections
|
|
else
|
|
CFLAGS += -O2
|
|
endif
|
|
|
|
# Setup functions for compilation
|
|
define dynamic_flags
|
|
-I$(shell dirname $(2)) -D__OBJNAME__=$(subst -,_,$(shell basename $(1) .o))
|
|
endef
|
|
merge_objs = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " MERGE $(subst $(build_dir)/,,$(1))"; \
|
|
$(LD) $(MERGEFLAGS) $(2) -o $(1)
|
|
merge_deps = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " MERGE-DEP $(subst $(build_dir)/,,$(1))"; \
|
|
cat $(2) > $(1)
|
|
copy_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " COPY $(subst $(build_dir)/,,$(1))"; \
|
|
cp -L -f $(2) $(1)
|
|
inst_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " INSTALL $(subst $(install_root_dir)/,,$(1))"; \
|
|
cp -L -f $(2) $(1)
|
|
inst_file_list = $(CMD_PREFIX)if [ ! -z "$(4)" ]; then \
|
|
mkdir -p $(1)/$(3); \
|
|
for file in $(4) ; do \
|
|
rel_file=`echo $$file | sed -e 's@$(2)/$(subst $(install_firmware_path),platform,$(3))@@'`; \
|
|
dest_file=$(1)"/"$(3)"/"`echo $$rel_file`; \
|
|
dest_dir=`dirname $$dest_file`; \
|
|
echo " INSTALL "$(3)"/"`echo $$rel_file`; \
|
|
mkdir -p $$dest_dir; \
|
|
cp -L -f $$file $$dest_file; \
|
|
done \
|
|
fi
|
|
inst_header_dir = $(CMD_PREFIX)mkdir -p $(1); \
|
|
echo " INSTALL $(subst $(install_root_dir)/,,$(1))"; \
|
|
cp -L -rf $(2) $(1)
|
|
compile_cpp_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " CPP-DEP $(subst $(build_dir)/,,$(1))"; \
|
|
printf %s `dirname $(1)`/ > $(1) && \
|
|
$(CC) $(CPPFLAGS) -x c -MM $(3) \
|
|
-MT `basename $(1:.dep=$(2))` >> $(1) || rm -f $(1)
|
|
compile_cpp = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " CPP $(subst $(build_dir)/,,$(1))"; \
|
|
$(CPP) $(CPPFLAGS) -x c $(2) | grep -v "\#" > $(1)
|
|
compile_cc_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " CC-DEP $(subst $(build_dir)/,,$(1))"; \
|
|
printf %s `dirname $(1)`/ > $(1) && \
|
|
$(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) \
|
|
-MM $(2) >> $(1) || rm -f $(1)
|
|
compile_cc = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " CC $(subst $(build_dir)/,,$(1))"; \
|
|
$(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1)
|
|
compile_as_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " AS-DEP $(subst $(build_dir)/,,$(1))"; \
|
|
printf %s `dirname $(1)`/ > $(1) && \
|
|
$(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) \
|
|
-MM $(2) >> $(1) || rm -f $(1)
|
|
compile_as = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " AS $(subst $(build_dir)/,,$(1))"; \
|
|
$(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1)
|
|
compile_elf = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " ELF $(subst $(build_dir)/,,$(1))"; \
|
|
$(CC) $(CFLAGS) $(3) $(ELFFLAGS) -Wl,-T$(2) -o $(1)
|
|
compile_ar = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " AR $(subst $(build_dir)/,,$(1))"; \
|
|
$(AR) $(ARFLAGS) $(1) $(2)
|
|
compile_objcopy = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " OBJCOPY $(subst $(build_dir)/,,$(1))"; \
|
|
$(OBJCOPY) -S -O binary $(2) $(1)
|
|
compile_dts = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " DTC $(subst $(build_dir)/,,$(1))"; \
|
|
$(CPP) $(DTSCPPFLAGS) $(2) | $(DTC) -O dtb -i `dirname $(2)` -o $(1)
|
|
compile_d2c = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " D2C $(subst $(build_dir)/,,$(1))"; \
|
|
$(if $($(2)-varalign-$(3)),$(eval D2C_ALIGN_BYTES := $($(2)-varalign-$(3))),$(eval D2C_ALIGN_BYTES := $(4))) \
|
|
$(if $($(2)-varprefix-$(3)),$(eval D2C_NAME_PREFIX := $($(2)-varprefix-$(3))),$(eval D2C_NAME_PREFIX := $(5))) \
|
|
$(if $($(2)-padding-$(3)),$(eval D2C_PADDING_BYTES := $($(2)-padding-$(3))),$(eval D2C_PADDING_BYTES := 0)) \
|
|
$(src_dir)/scripts/d2c.sh -i $(6) -a $(D2C_ALIGN_BYTES) -p $(D2C_NAME_PREFIX) -t $(D2C_PADDING_BYTES) > $(1)
|
|
compile_carray = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " CARRAY $(subst $(build_dir)/,,$(1))"; \
|
|
$(eval CARRAY_VAR_LIST := $(carray-$(subst .carray.c,,$(shell basename $(1)))-y)) \
|
|
$(src_dir)/scripts/carray.sh -i $(2) -l "$(CARRAY_VAR_LIST)" > $(1) || rm $(1)
|
|
compile_gen_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
|
|
echo " GEN-DEP $(subst $(build_dir)/,,$(1))"; \
|
|
echo "$(1:.dep=$(2)): $(3)" >> $(1)
|
|
|
|
targets-y = $(build_dir)/lib/libsbi.a
|
|
ifdef PLATFORM
|
|
targets-y += $(platform_build_dir)/lib/libplatsbi.a
|
|
endif
|
|
targets-y += $(firmware-bins-path-y)
|
|
|
|
# The default "make all" rule
|
|
.PHONY: all
|
|
all: $(targets-y)
|
|
|
|
# Preserve all intermediate files
|
|
.SECONDARY:
|
|
|
|
# Rules for lib/sbi sources
|
|
$(build_dir)/lib/libsbi.a: $(libsbi-objs-path-y)
|
|
$(call compile_ar,$@,$^)
|
|
|
|
$(platform_build_dir)/lib/libplatsbi.a: $(libsbi-objs-path-y) $(libsbiutils-objs-path-y) $(platform-objs-path-y)
|
|
$(call compile_ar,$@,$^)
|
|
|
|
$(build_dir)/%.dep: $(src_dir)/%.carray $(KCONFIG_AUTOHEADER)
|
|
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
|
|
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
|
|
|
|
$(build_dir)/%.carray.c: $(src_dir)/%.carray $(src_dir)/scripts/carray.sh
|
|
$(call compile_carray,$@,$<)
|
|
|
|
$(build_dir)/%.dep: $(src_dir)/%.c $(KCONFIG_AUTOHEADER)
|
|
$(call compile_cc_dep,$@,$<)
|
|
|
|
$(build_dir)/%.o: $(src_dir)/%.c
|
|
$(call compile_cc,$@,$<)
|
|
|
|
$(build_dir)/%.o: $(build_dir)/%.c
|
|
$(call compile_cc,$@,$<)
|
|
|
|
ifeq ($(BUILD_INFO),y)
|
|
$(build_dir)/lib/sbi/sbi_init.o: $(libsbi_dir)/sbi_init.c FORCE
|
|
$(call compile_cc,$@,$<)
|
|
endif
|
|
|
|
$(build_dir)/%.dep: $(src_dir)/%.S $(KCONFIG_AUTOHEADER)
|
|
$(call compile_as_dep,$@,$<)
|
|
|
|
$(build_dir)/%.o: $(src_dir)/%.S
|
|
$(call compile_as,$@,$<)
|
|
|
|
# Rules for platform sources
|
|
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.carray $(KCONFIG_AUTOHEADER)
|
|
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
|
|
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
|
|
|
|
$(platform_build_dir)/%.carray.c: $(platform_src_dir)/%.carray $(src_dir)/scripts/carray.sh
|
|
$(call compile_carray,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.c $(KCONFIG_AUTOHEADER)
|
|
$(call compile_cc_dep,$@,$<)
|
|
|
|
$(platform_build_dir)/%.o: $(platform_src_dir)/%.c $(KCONFIG_AUTOHEADER)
|
|
$(call compile_cc,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.S
|
|
$(call compile_as_dep,$@,$<)
|
|
|
|
$(platform_build_dir)/%.o: $(platform_src_dir)/%.S
|
|
$(call compile_as,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.dts $(KCONFIG_AUTOHEADER)
|
|
$(call compile_gen_dep,$@,.dtb,$< $(KCONFIG_AUTOHEADER))
|
|
$(call compile_gen_dep,$@,.c,$(@:.dep=.dtb))
|
|
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
|
|
|
|
$(platform_build_dir)/%.c: $(platform_build_dir)/%.dtb
|
|
$(call compile_d2c,$@,platform,$(subst .dtb,.o,$(subst /,-,$(subst $(platform_build_dir)/,,$<))),16,dt,$<)
|
|
|
|
$(platform_build_dir)/%.dtb: $(platform_src_dir)/%.dts
|
|
$(call compile_dts,$@,$<)
|
|
|
|
# Rules for lib/utils and firmware sources
|
|
$(platform_build_dir)/%.bin: $(platform_build_dir)/%.elf
|
|
$(call compile_objcopy,$@,$<)
|
|
|
|
$(platform_build_dir)/%.elf: $(platform_build_dir)/%.o $(platform_build_dir)/%.elf.ld $(platform_build_dir)/lib/libplatsbi.a
|
|
$(call compile_elf,$@,$@.ld,$< $(platform_build_dir)/lib/libplatsbi.a)
|
|
|
|
$(platform_build_dir)/%.dep: $(src_dir)/%.ldS $(KCONFIG_AUTOHEADER)
|
|
$(call compile_cpp_dep,$@,.ld,$<)
|
|
|
|
$(platform_build_dir)/%.ld: $(src_dir)/%.ldS
|
|
$(call compile_cpp,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(src_dir)/%.carray $(KCONFIG_AUTOHEADER)
|
|
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
|
|
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
|
|
|
|
$(platform_build_dir)/%.carray.c: $(src_dir)/%.carray $(src_dir)/scripts/carray.sh
|
|
$(call compile_carray,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(src_dir)/%.c $(KCONFIG_AUTOHEADER)
|
|
$(call compile_cc_dep,$@,$<)
|
|
|
|
$(platform_build_dir)/%.o: $(src_dir)/%.c
|
|
$(call compile_cc,$@,$<)
|
|
|
|
$(platform_build_dir)/%.dep: $(src_dir)/%.S $(KCONFIG_AUTOHEADER)
|
|
$(call compile_as_dep,$@,$<)
|
|
|
|
$(platform_build_dir)/%.o: $(src_dir)/%.S
|
|
$(call compile_as,$@,$<)
|
|
|
|
# Rule for "make docs"
|
|
$(build_dir)/docs/latex/refman.pdf: $(build_dir)/docs/latex/refman.tex
|
|
$(CMD_PREFIX)mkdir -p $(build_dir)/docs
|
|
$(CMD_PREFIX)$(MAKE) -C $(build_dir)/docs/latex
|
|
$(build_dir)/docs/latex/refman.tex: $(build_dir)/docs/doxygen.cfg
|
|
$(CMD_PREFIX)mkdir -p $(build_dir)/docs
|
|
$(CMD_PREFIX)doxygen $(build_dir)/docs/doxygen.cfg
|
|
$(build_dir)/docs/doxygen.cfg: $(src_dir)/docs/doxygen.cfg
|
|
$(CMD_PREFIX)mkdir -p $(build_dir)/docs
|
|
$(CMD_PREFIX)cat docs/doxygen.cfg | sed -e "s#@@SRC_DIR@@#$(src_dir)#" -e "s#@@BUILD_DIR@@#$(build_dir)#" -e "s#@@OPENSBI_MAJOR@@#$(OPENSBI_VERSION_MAJOR)#" -e "s#@@OPENSBI_MINOR@@#$(OPENSBI_VERSION_MINOR)#" > $(build_dir)/docs/doxygen.cfg
|
|
.PHONY: docs
|
|
docs: $(build_dir)/docs/latex/refman.pdf
|
|
|
|
# Dependency files should only be included after default Makefile rules
|
|
# They should not be included for any "xxxconfig" or "xxxclean" rule
|
|
all-deps-1 = $(if $(findstring config,$(MAKECMDGOALS)),,$(deps-y))
|
|
all-deps-2 = $(if $(findstring clean,$(MAKECMDGOALS)),,$(all-deps-1))
|
|
-include $(all-deps-2)
|
|
|
|
# Include external dependency of firmwares after default Makefile rules
|
|
include $(src_dir)/firmware/external_deps.mk
|
|
|
|
# Convenient "make run" command for emulated platforms
|
|
.PHONY: run
|
|
run: all
|
|
ifneq ($(platform-runcmd),)
|
|
$(platform-runcmd) $(RUN_ARGS)
|
|
else
|
|
ifdef PLATFORM
|
|
@echo "Platform $(PLATFORM) doesn't specify a run command"
|
|
@false
|
|
else
|
|
@echo Run command only available when targeting a platform
|
|
@false
|
|
endif
|
|
endif
|
|
|
|
install_targets-y = install_libsbi
|
|
ifdef PLATFORM
|
|
install_targets-y += install_libplatsbi
|
|
install_targets-y += install_firmwares
|
|
endif
|
|
|
|
# Rule for "make install"
|
|
.PHONY: install
|
|
install: $(install_targets-y)
|
|
|
|
.PHONY: install_libsbi
|
|
install_libsbi: $(build_dir)/lib/libsbi.a
|
|
$(call inst_header_dir,$(install_root_dir)/$(install_include_path),$(include_dir)/sbi)
|
|
$(call inst_file,$(install_root_dir)/$(install_lib_path)/libsbi.a,$(build_dir)/lib/libsbi.a)
|
|
|
|
.PHONY: install_libplatsbi
|
|
install_libplatsbi: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a
|
|
$(call inst_file,$(install_root_dir)/$(install_lib_path)/opensbi/$(platform_subdir)/lib/libplatsbi.a,$(platform_build_dir)/lib/libplatsbi.a)
|
|
|
|
.PHONY: install_firmwares
|
|
install_firmwares: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(firmware-bins-path-y)
|
|
$(call inst_file_list,$(install_root_dir),$(build_dir),$(install_firmware_path)/$(platform_subdir)/firmware,$(firmware-elfs-path-y))
|
|
$(call inst_file_list,$(install_root_dir),$(build_dir),$(install_firmware_path)/$(platform_subdir)/firmware,$(firmware-bins-path-y))
|
|
|
|
.PHONY: install_docs
|
|
install_docs: $(build_dir)/docs/latex/refman.pdf
|
|
$(call inst_file,$(install_root_dir)/$(install_docs_path)/refman.pdf,$(build_dir)/docs/latex/refman.pdf)
|
|
|
|
.PHONY: cscope
|
|
cscope:
|
|
$(CMD_PREFIX)find \
|
|
"$(src_dir)/firmware" \
|
|
"$(src_dir)/include" \
|
|
"$(src_dir)/lib" \
|
|
"$(platform_src_dir)" \
|
|
-name "*.[chS]" -print > cscope.files
|
|
$(CMD_PREFIX)echo "$(KCONFIG_AUTOHEADER)" >> cscope.files
|
|
$(CMD_PREFIX)cscope -bkq -i cscope.files -f cscope.out
|
|
|
|
# Rule for "make clean"
|
|
.PHONY: clean
|
|
clean:
|
|
$(CMD_PREFIX)mkdir -p $(build_dir)
|
|
$(if $(V), @echo " RM $(build_dir)/*.o")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.o" -exec rm -rf {} +
|
|
$(if $(V), @echo " RM $(build_dir)/*.carray.c")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.carray.c" -exec rm -rf {} +
|
|
$(if $(V), @echo " RM $(build_dir)/*.a")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.a" -exec rm -rf {} +
|
|
$(if $(V), @echo " RM $(build_dir)/*.elf")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.elf" -exec rm -rf {} +
|
|
$(if $(V), @echo " RM $(build_dir)/*.bin")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.bin" -exec rm -rf {} +
|
|
$(if $(V), @echo " RM $(build_dir)/*.dtb")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.dtb" -exec rm -rf {} +
|
|
|
|
# Rule for "make distclean"
|
|
.PHONY: distclean
|
|
distclean: clean
|
|
$(CMD_PREFIX)mkdir -p $(build_dir)
|
|
$(if $(V), @echo " RM $(build_dir)/*.dep")
|
|
$(CMD_PREFIX)find $(build_dir) -type f -name "*.dep" -exec rm -rf {} +
|
|
ifeq ($(build_dir),$(CURDIR)/build)
|
|
$(if $(V), @echo " RM $(build_dir)")
|
|
$(CMD_PREFIX)rm -rf $(build_dir)
|
|
endif
|
|
ifeq ($(install_root_dir),$(install_root_dir_default)/usr)
|
|
$(if $(V), @echo " RM $(install_root_dir_default)")
|
|
$(CMD_PREFIX)rm -rf $(install_root_dir_default)
|
|
endif
|
|
$(if $(V), @echo " RM $(src_dir)/cscope*")
|
|
$(CMD_PREFIX)rm -f $(src_dir)/cscope*
|
|
|
|
.PHONY: FORCE
|
|
FORCE:
|