1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2019 Western Digital Corporation or its affiliates. 5# 6# Authors: 7# Anup Patel <anup.patel@wdc.com> 8# 9 10# Select Make Options: 11# o Do not use make's built-in rules 12# o Do not print "Entering directory ..."; 13MAKEFLAGS += -r --no-print-directory 14 15# Find out source, build, and install directories 16src_dir=$(CURDIR) 17ifdef O 18 build_dir=$(shell readlink -f $(O)) 19else 20 build_dir=$(CURDIR)/build 21endif 22ifeq ($(build_dir),$(CURDIR)) 23$(error Build directory is same as source directory.) 24endif 25ifdef I 26 install_dir=$(shell readlink -f $(I)) 27else 28 install_dir=$(CURDIR)/install 29endif 30ifeq ($(install_dir),$(CURDIR)) 31$(error Install directory is same as source directory.) 32endif 33ifeq ($(install_dir),$(build_dir)) 34$(error Install directory is same as build directory.) 35endif 36ifdef PLATFORM_DIR 37 platform_dir_path=$(shell readlink -f $(PLATFORM_DIR)) 38 ifdef PLATFORM 39 platform_parent_dir=$(platform_dir_path) 40 else 41 PLATFORM=$(shell basename $(platform_dir_path)) 42 platform_parent_dir=$(subst $(PLATFORM),,$(platform_dir_path)) 43 endif 44else 45 platform_parent_dir=$(src_dir)/platform 46endif 47 48# Check if verbosity is ON for build process 49CMD_PREFIX_DEFAULT := @ 50ifeq ($(V), 1) 51 CMD_PREFIX := 52else 53 CMD_PREFIX := $(CMD_PREFIX_DEFAULT) 54endif 55 56# Setup path of directories 57export platform_subdir=$(PLATFORM) 58export platform_src_dir=$(platform_parent_dir)/$(platform_subdir) 59export platform_build_dir=$(build_dir)/platform/$(platform_subdir) 60export include_dir=$(CURDIR)/include 61export libsbi_dir=$(CURDIR)/lib/sbi 62export libsbiutils_dir=$(CURDIR)/lib/utils 63export firmware_dir=$(CURDIR)/firmware 64 65# Find library version 66OPENSBI_VERSION_MAJOR=`grep "define OPENSBI_VERSION_MAJOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MAJOR.*\([0-9][0-9]*\)/\1/'` 67OPENSBI_VERSION_MINOR=`grep "define OPENSBI_VERSION_MINOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MINOR.*\([0-9][0-9]*\)/\1/'` 68OPENSBI_VERSION_GIT=$(shell if [ -d $(src_dir)/.git ]; then git describe 2> /dev/null; fi) 69 70# Setup compilation commands 71ifdef CROSS_COMPILE 72CC = $(CROSS_COMPILE)gcc 73CPP = $(CROSS_COMPILE)cpp 74AR = $(CROSS_COMPILE)ar 75LD = $(CROSS_COMPILE)ld 76OBJCOPY = $(CROSS_COMPILE)objcopy 77else 78CC ?= gcc 79CPP ?= cpp 80AR ?= ar 81LD ?= ld 82OBJCOPY ?= objcopy 83endif 84AS = $(CC) 85DTC = dtc 86 87# Guess the compillers xlen 88OPENSBI_CC_XLEN := $(shell TMP=`$(CC) -dumpmachine | sed 's/riscv\([0-9][0-9]\).*/\1/'`; echo $${TMP}) 89 90# Setup platform XLEN 91ifndef PLATFORM_RISCV_XLEN 92 ifeq ($(OPENSBI_CC_XLEN), 32) 93 PLATFORM_RISCV_XLEN = 32 94 else 95 PLATFORM_RISCV_XLEN = 64 96 endif 97endif 98 99# Setup list of objects.mk files 100ifdef PLATFORM 101platform-object-mks=$(shell if [ -d $(platform_src_dir)/ ]; then find $(platform_src_dir) -iname "objects.mk" | sort -r; fi) 102endif 103libsbi-object-mks=$(shell if [ -d $(libsbi_dir) ]; then find $(libsbi_dir) -iname "objects.mk" | sort -r; fi) 104libsbiutils-object-mks=$(shell if [ -d $(libsbiutils_dir) ]; then find $(libsbiutils_dir) -iname "objects.mk" | sort -r; fi) 105firmware-object-mks=$(shell if [ -d $(firmware_dir) ]; then find $(firmware_dir) -iname "objects.mk" | sort -r; fi) 106 107# Include platform specifig config.mk 108ifdef PLATFORM 109include $(platform_src_dir)/config.mk 110endif 111 112# Include all object.mk files 113ifdef PLATFORM 114include $(platform-object-mks) 115endif 116include $(libsbi-object-mks) 117include $(libsbiutils-object-mks) 118include $(firmware-object-mks) 119 120# Setup list of objects 121libsbi-objs-path-y=$(foreach obj,$(libsbi-objs-y),$(build_dir)/lib/sbi/$(obj)) 122libsbiutils-objs-path-y=$(foreach obj,$(libsbiutils-objs-y),$(build_dir)/lib/utils/$(obj)) 123ifdef PLATFORM 124platform-objs-path-y=$(foreach obj,$(platform-objs-y),$(platform_build_dir)/$(obj)) 125platform-dtb-path-y=$(foreach obj,$(platform-dtb-y),$(platform_build_dir)/$(obj)) 126firmware-bins-path-y=$(foreach bin,$(firmware-bins-y),$(platform_build_dir)/firmware/$(bin)) 127endif 128firmware-elfs-path-y=$(firmware-bins-path-y:.bin=.elf) 129firmware-objs-path-y=$(firmware-bins-path-y:.bin=.o) 130 131# Setup list of deps files for objects 132deps-y=$(platform-objs-path-y:.o=.dep) 133deps-y+=$(libsbi-objs-path-y:.o=.dep) 134deps-y+=$(libsbiutils-objs-path-y:.o=.dep) 135deps-y+=$(firmware-objs-path-y:.o=.dep) 136 137# Setup platform ABI, ISA and Code Model 138ifndef PLATFORM_RISCV_ABI 139 ifeq ($(PLATFORM_RISCV_XLEN), 32) 140 PLATFORM_RISCV_ABI = ilp$(PLATFORM_RISCV_XLEN) 141 else 142 PLATFORM_RISCV_ABI = lp$(PLATFORM_RISCV_XLEN) 143 endif 144endif 145ifndef PLATFORM_RISCV_ISA 146 PLATFORM_RISCV_ISA = rv$(PLATFORM_RISCV_XLEN)imafdc 147endif 148ifndef PLATFORM_RISCV_CODE_MODEL 149 PLATFORM_RISCV_CODE_MODEL = medany 150endif 151 152# Setup compilation commands flags 153GENFLAGS = -I$(platform_src_dir)/include 154GENFLAGS += -I$(include_dir) 155ifneq ($(OPENSBI_VERSION_GIT),) 156GENFLAGS += -DOPENSBI_VERSION_GIT="\"$(OPENSBI_VERSION_GIT)\"" 157endif 158GENFLAGS += $(libsbiutils-genflags-y) 159GENFLAGS += $(platform-genflags-y) 160GENFLAGS += $(firmware-genflags-y) 161 162CFLAGS = -g -Wall -Werror -nostdlib -fno-strict-aliasing -O2 163CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls 164CFLAGS += -mno-save-restore -mstrict-align 165CFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA) 166CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL) 167CFLAGS += $(GENFLAGS) 168CFLAGS += $(platform-cflags-y) 169CFLAGS += $(firmware-cflags-y) 170CFLAGS += -fno-pie -no-pie 171 172CPPFLAGS += $(GENFLAGS) 173CPPFLAGS += $(platform-cppflags-y) 174CPPFLAGS += $(firmware-cppflags-y) 175 176ASFLAGS = -g -Wall -nostdlib -D__ASSEMBLY__ 177ASFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls 178ASFLAGS += -mno-save-restore -mstrict-align 179ASFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA) 180ASFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL) 181ASFLAGS += $(GENFLAGS) 182ASFLAGS += $(platform-asflags-y) 183ASFLAGS += $(firmware-asflags-y) 184 185ARFLAGS = rcs 186 187ELFFLAGS += -Wl,--build-id=none -N -static-libgcc -lgcc 188ELFFLAGS += $(platform-ldflags-y) 189ELFFLAGS += $(firmware-ldflags-y) 190 191MERGEFLAGS += -r 192MERGEFLAGS += -b elf$(PLATFORM_RISCV_XLEN)-littleriscv 193MERGEFLAGS += -m elf$(PLATFORM_RISCV_XLEN)lriscv 194 195DTCFLAGS = -O dtb 196 197# Setup functions for compilation 198define dynamic_flags 199-I$(shell dirname $(2)) -D__OBJNAME__=$(subst -,_,$(shell basename $(1) .o)) 200endef 201merge_objs = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 202 echo " MERGE $(subst $(build_dir)/,,$(1))"; \ 203 $(LD) $(MERGEFLAGS) $(2) -o $(1) 204merge_deps = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 205 echo " MERGE-DEP $(subst $(build_dir)/,,$(1))"; \ 206 cat $(2) > $(1) 207copy_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 208 echo " COPY $(subst $(build_dir)/,,$(1))"; \ 209 cp -f $(2) $(1) 210inst_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 211 echo " INSTALL $(subst $(install_dir)/,,$(1))"; \ 212 cp -f $(2) $(1) 213inst_file_list = $(CMD_PREFIX)if [ ! -z "$(4)" ]; then \ 214 mkdir -p $(1)/$(3); \ 215 for file in $(4) ; do \ 216 rel_file=`echo $$file | sed -e 's@$(2)/$(3)/@@'`; \ 217 dest_file=$(1)"/"$(3)"/"`echo $$rel_file`; \ 218 dest_dir=`dirname $$dest_file`; \ 219 echo " INSTALL "$(3)"/"`echo $$rel_file`; \ 220 mkdir -p $$dest_dir; \ 221 cp -f $$file $$dest_file; \ 222 done \ 223 fi 224inst_header_dir = $(CMD_PREFIX)mkdir -p $(1); \ 225 echo " INSTALL $(subst $(install_dir)/,,$(1))"; \ 226 cp -rf $(2) $(1) 227compile_cpp = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 228 echo " CPP $(subst $(build_dir)/,,$(1))"; \ 229 $(CPP) $(CPPFLAGS) -x c $(2) | grep -v "\#" > $(1) 230compile_cc_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 231 echo " CC-DEP $(subst $(build_dir)/,,$(1))"; \ 232 printf %s `dirname $(1)`/ > $(1) && \ 233 $(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) \ 234 -MM $(2) >> $(1) || rm -f $(1) 235compile_cc = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 236 echo " CC $(subst $(build_dir)/,,$(1))"; \ 237 $(CC) $(CFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1) 238compile_as_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 239 echo " AS-DEP $(subst $(build_dir)/,,$(1))"; \ 240 printf %s `dirname $(1)`/ > $(1) && \ 241 $(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) \ 242 -MM $(2) >> $(1) || rm -f $(1) 243compile_as = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 244 echo " AS $(subst $(build_dir)/,,$(1))"; \ 245 $(AS) $(ASFLAGS) $(call dynamic_flags,$(1),$(2)) -c $(2) -o $(1) 246compile_elf = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 247 echo " ELF $(subst $(build_dir)/,,$(1))"; \ 248 $(CC) $(CFLAGS) $(3) $(ELFFLAGS) -Wl,-T$(2) -o $(1) 249compile_ar = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 250 echo " AR $(subst $(build_dir)/,,$(1))"; \ 251 $(AR) $(ARFLAGS) $(1) $(2) 252compile_objcopy = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 253 echo " OBJCOPY $(subst $(build_dir)/,,$(1))"; \ 254 $(OBJCOPY) -S -O binary $(2) $(1) 255compile_dts = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \ 256 echo " DTC $(subst $(build_dir)/,,$(1))"; \ 257 $(DTC) $(DTCFLAGS) -o $(1) $(2) 258 259targets-y = $(build_dir)/lib/libsbi.a 260targets-y += $(build_dir)/lib/libsbiutils.a 261ifdef PLATFORM 262targets-y += $(platform_build_dir)/lib/libplatsbi.a 263targets-y += $(platform-dtb-path-y) 264endif 265targets-y += $(firmware-bins-path-y) 266 267# Default rule "make" should always be first rule 268.PHONY: all 269all: $(targets-y) 270 271# Preserve all intermediate files 272.SECONDARY: 273 274$(build_dir)/%.bin: $(build_dir)/%.elf 275 $(call compile_objcopy,$@,$<) 276 277$(build_dir)/%.elf: $(build_dir)/%.o $(build_dir)/%.elf.ld $(platform_build_dir)/lib/libplatsbi.a 278 $(call compile_elf,$@,$@.ld,$< $(platform_build_dir)/lib/libplatsbi.a) 279 280$(platform_build_dir)/%.ld: $(src_dir)/%.ldS 281 $(call compile_cpp,$@,$<) 282 283$(build_dir)/lib/libsbi.a: $(libsbi-objs-path-y) 284 $(call compile_ar,$@,$^) 285 286$(build_dir)/lib/libsbiutils.a: $(libsbi-objs-path-y) $(libsbiutils-objs-path-y) 287 $(call compile_ar,$@,$^) 288 289$(platform_build_dir)/lib/libplatsbi.a: $(libsbi-objs-path-y) $(libsbiutils-objs-path-y) $(platform-objs-path-y) 290 $(call compile_ar,$@,$^) 291 292$(build_dir)/%.dep: $(src_dir)/%.c 293 $(call compile_cc_dep,$@,$<) 294 295$(build_dir)/%.o: $(src_dir)/%.c 296 $(call compile_cc,$@,$<) 297 298$(build_dir)/%.dep: $(src_dir)/%.S 299 $(call compile_as_dep,$@,$<) 300 301$(build_dir)/%.o: $(src_dir)/%.S 302 $(call compile_as,$@,$<) 303 304$(platform_build_dir)/%.dep: $(platform_src_dir)/%.c 305 $(call compile_cc_dep,$@,$<) 306 307$(platform_build_dir)/%.o: $(platform_src_dir)/%.c 308 $(call compile_cc,$@,$<) 309 310$(platform_build_dir)/%.dep: $(platform_src_dir)/%.S 311 $(call compile_as_dep,$@,$<) 312 313$(platform_build_dir)/%.o: $(platform_src_dir)/%.S 314 $(call compile_as,$@,$<) 315 316$(platform_build_dir)/%.dep: $(src_dir)/%.c 317 $(call compile_cc_dep,$@,$<) 318 319$(platform_build_dir)/%.o: $(src_dir)/%.c 320 $(call compile_cc,$@,$<) 321 322$(platform_build_dir)/%.dep: $(src_dir)/%.S 323 $(call compile_as_dep,$@,$<) 324 325$(platform_build_dir)/%.o: $(src_dir)/%.S 326 $(call compile_as,$@,$<) 327 328$(build_dir)/%.dtb: $(src_dir)/%.dts 329 $(call compile_dts,$@,$<) 330 331# Rule for "make docs" 332$(build_dir)/docs/latex/refman.pdf: $(build_dir)/docs/latex/refman.tex 333 $(CMD_PREFIX)mkdir -p $(build_dir)/docs 334 $(CMD_PREFIX)$(MAKE) -C $(build_dir)/docs/latex 335$(build_dir)/docs/latex/refman.tex: $(build_dir)/docs/doxygen.cfg 336 $(CMD_PREFIX)mkdir -p $(build_dir)/docs 337 $(CMD_PREFIX)doxygen $(build_dir)/docs/doxygen.cfg 338$(build_dir)/docs/doxygen.cfg: $(src_dir)/docs/doxygen.cfg 339 $(CMD_PREFIX)mkdir -p $(build_dir)/docs 340 $(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 341.PHONY: docs 342docs: $(build_dir)/docs/latex/refman.pdf 343 344# Dependency files should only be included after default Makefile rules 345# They should not be included for any "xxxconfig" or "xxxclean" rule 346all-deps-1 = $(if $(findstring config,$(MAKECMDGOALS)),,$(deps-y)) 347all-deps-2 = $(if $(findstring clean,$(MAKECMDGOALS)),,$(all-deps-1)) 348-include $(all-deps-2) 349 350# Include external dependency of firmwares after default Makefile rules 351include $(src_dir)/firmware/external_deps.mk 352 353# Convenient "make run" command for emulated platforms 354.PHONY: run 355run: all 356ifneq ($(platform-runcmd),) 357 $(platform-runcmd) $(RUN_ARGS) 358else 359ifdef PLATFORM 360 @echo "Platform $(PLATFORM) doesn't specify a run command" 361 @false 362else 363 @echo Run command only available when targeting a platform 364 @false 365endif 366endif 367 368install_targets-y = install_libsbi 369install_targets-y += install_libsbiutils 370ifdef PLATFORM 371install_targets-y += install_libplatsbi 372install_targets-y += install_firmwares 373endif 374 375# Rule for "make install" 376.PHONY: install 377install: $(install_targets-y) 378 379.PHONY: install_libsbi 380install_libsbi: $(build_dir)/lib/libsbi.a 381 $(call inst_header_dir,$(install_dir)/include,$(include_dir)/sbi) 382 $(call inst_file,$(install_dir)/lib/libsbi.a,$(build_dir)/lib/libsbi.a) 383 384.PHONY: install_libsbiutils 385install_libsbiutils: $(build_dir)/lib/libsbiutils.a 386 $(call inst_header_dir,$(install_dir)/include,$(include_dir)/sbi_utils) 387 $(call inst_file,$(install_dir)/lib/libsbiutils.a,$(build_dir)/lib/libsbiutils.a) 388 389.PHONY: install_libplatsbi 390install_libplatsbi: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(build_dir)/lib/libsbiutils.a 391 $(call inst_file,$(install_dir)/platform/$(platform_subdir)/lib/libplatsbi.a,$(platform_build_dir)/lib/libplatsbi.a) 392 393.PHONY: install_firmwares 394install_firmwares: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(build_dir)/lib/libsbiutils.a $(firmware-bins-path-y) 395 $(call inst_file_list,$(install_dir),$(build_dir),platform/$(platform_subdir)/firmware,$(firmware-elfs-path-y)) 396 $(call inst_file_list,$(install_dir),$(build_dir),platform/$(platform_subdir)/firmware,$(firmware-bins-path-y)) 397 398.PHONY: install_docs 399install_docs: $(build_dir)/docs/latex/refman.pdf 400 $(call inst_file,$(install_dir)/docs/refman.pdf,$(build_dir)/docs/latex/refman.pdf) 401 402# Rule for "make clean" 403.PHONY: clean 404clean: 405 $(CMD_PREFIX)mkdir -p $(build_dir) 406 $(if $(V), @echo " RM $(build_dir)/*.o") 407 $(CMD_PREFIX)find $(build_dir) -type f -name "*.o" -exec rm -rf {} + 408 $(if $(V), @echo " RM $(build_dir)/*.a") 409 $(CMD_PREFIX)find $(build_dir) -type f -name "*.a" -exec rm -rf {} + 410 $(if $(V), @echo " RM $(build_dir)/*.elf") 411 $(CMD_PREFIX)find $(build_dir) -type f -name "*.elf" -exec rm -rf {} + 412 $(if $(V), @echo " RM $(build_dir)/*.bin") 413 $(CMD_PREFIX)find $(build_dir) -type f -name "*.bin" -exec rm -rf {} + 414 415# Rule for "make distclean" 416.PHONY: distclean 417distclean: clean 418 $(CMD_PREFIX)mkdir -p $(build_dir) 419 $(if $(V), @echo " RM $(build_dir)/*.dep") 420 $(CMD_PREFIX)find $(build_dir) -type f -name "*.dep" -exec rm -rf {} + 421ifeq ($(build_dir),$(CURDIR)/build) 422 $(if $(V), @echo " RM $(build_dir)") 423 $(CMD_PREFIX)rm -rf $(build_dir) 424endif 425ifeq ($(install_dir),$(CURDIR)/install) 426 $(if $(V), @echo " RM $(install_dir)") 427 $(CMD_PREFIX)rm -rf $(install_dir) 428endif 429