#!/usr/bin/make -f

# Note this is a GNUmakefile

#############################################################
# Copyright(c) 2013 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#############################################################

#############################################################
## USAGE:
##
## file-add_me_fvheader_and_sign-->FVWRAP-->\
##                                           --->SIGN
## file-only_sign_me----------------------->/
#############################################################

#############################################################
## GLOBAL DEFINITIONS (EDIT HERE)
#############################################################

# WARNING: this MUST match the name in generator/src/SpiFlashImage.h
# It should also match the default argument of platform-data-patch.py
FLASH_NO_PDAT := Flash-missingPDAT.bin

FLASH_CAPSULE := Flash-missingPDAT.cap


# For more details about these flags see the UEFI PI specification and
# the UEFI firmware writer's guide
# - This flag changes EFI behaviour when the OS requests EFI to do the
#   reset
CAPSULE_FLAGS_PERSIST_ACROSS_RESET  := 0x10000
# - The "No return" flag
CAPSULE_FLAGS_INITIATE_RESET        := 0x40000
# - Resets and updates
CAPSULE_FLAGS_PERSIST_THEN_INITIATE := 0x50000

CAPSULE_FLAGS ?= ${CAPSULE_FLAGS_PERSIST_ACROSS_RESET}


# WARNING: this should match the default output name of platform-data-patch.py
FLASH_WITH_PDAT := Flash+PlatformData.bin

# Besides the flash images, these are all the final outputs useful to users
OTHER_GENERATOR_PRODUCTS := image_info.txt CapsuleComponents.ini mfh.bin

# Only GNU make 3.81 and above support .DEFAULT_GOAL : make this the first one.
all: ${FLASH_NO_PDAT} 

capsule: ${FLASH_CAPSULE}

MYSELF := $(lastword ${MAKEFILE_LIST})
MYABSELF := $(abspath ${MYSELF})
MYDIR  := $(dir ${MYSELF})


       ######      Recursive, "sysimages" targets    #######

# Search for layout.conf files in subdirectories
_subdirs := $(wildcard sysimage*/layout.conf)
IMAGE_SUBDIRS := $(dir ${_subdirs})


ifeq (,${MAKECMDGOALS})
NO_TARGET_ON_CLI := non_empty_placeholder
endif

# From the list of targets on the command line, extract the
# list of non-recursive targets
CURDIR_TARGETS := $(filter-out sysimage.% sysimages%         \
                               ramfs%     initramfs%   zip,  \
                    ${MAKECMDGOALS})


ifneq (,${CURDIR_TARGETS}${NO_TARGET_ON_CLI})
#    => No recursive target was passed on the command line

include layout.mk

else
#    => Some recursive target(s) was passed on the command line

$(info |       ---------------------- )
$(info | List of sub-directories with a layout.conf file: ${IMAGE_SUBDIRS})
$(info |       ---------------------- )

endif



# TOOL PATHS ------------------------------------------------
# Can be overriden on the command line, see BaseTools/README.txt
BASETOOLS           ?= ${MYDIR}BaseTools/x86_64/C/bin

ifneq (,${CSSTOOLS})
$(warning warning: CSSTOOLS variable now ignored: asset \
	signing tool has been embedded into SPI flash tools )
endif
SIGNTOOL           := ${MYDIR}asset-signing-tool

KEYFILE             ?= ./config/key.pem
GENERATORTOOL       ?= ${MYDIR}generator

# TOOLS -----------------------------------------------------
#SPIFLASHGENERATOR   := ${GENERATORTOOL}/SpiFlashGenerator
SPIFLASHGENERATOR   := ${MYDIR}/generator/generator.py
DD                  := dd

GENFW               := ${BASETOOLS}/GenFw
GENSEC              := ${BASETOOLS}/GenSec
GENFFS              := ${BASETOOLS}/GenFfs
GENFV               := ${BASETOOLS}/GenFv


CSSINPUT            := $(SIGNTOOL)/exports/lastbuilt/bin/cssinput
CODESIGNEMULATOR    := $(SIGNTOOL)/exports/lastbuilt/bin/codesignemulator

# CONFIGURATION FILE ----------------------------------------
LAYOUTFILE          ?= ./layout.conf

INSTALL_DIR         ?= install
INSTALLS            ?= installs

#############################################################
# SOURCES - TO BE WRAPPED WITH FV HEADER (EDIT HERE) --------
# PATTERN: --------------------------------------------------
# SRCS_FVWRAP        := firstfile.efi secondfile
# firstfile.efi.GUID := B43BD3E1-64D1-4744-9394-D0E1C4DE8C87
# secondfile.GUID    := C13BF1A9-34B1-1024-7122-E0E3CFDA8089
# SRCS_FVWRAP variable comes from layout.mk file
#############################################################

OBJS_FVWRAP     := ${SRCS_FVWRAP:=.fv}
OBJS_FW         := ${SRCS_FVWRAP:=.fw}
OBJS_PE32       := ${SRCS_FVWRAP:=.fw.pe32}

#############################################################
# SOURCES - TO BE SIGNED (EDIT HERE) ------------------------
# PATTERN: --------------------------------------------------
# SRCS_SIGN     := firstfile.efi.fv secondfile
# SRCS_SIGN variable comes from layout.mk file
#############################################################

OBJS_SIGN       := ${SRCS_SIGN:=.signed}
OBJS_CSBH       := ${SRCS_SIGN:=.csbh}
OBJS_ALIGN      := ${SRCS_SIGN:=.aligned}
OBJS_CSSINPUT   := ${SRCS_SIGN:=.cssinput}

#############################################################
## TARGETS (DON'T EDIT!)
#############################################################

.DELETE_ON_ERROR:


sysimages: ${IMAGE_SUBDIRS}

.PHONY: sysimages sysimagesclean ${IMAGE_SUBDIRS} sysimages-install

${IMAGE_SUBDIRS}:
	$(MAKE) -C $@ -f ${MYABSELF} capsule

# This is just for CLI convenience: do NOT start using this variable anywhere else
_IMAGE_SUBDIRS_SLASH := ${IMAGE_SUBDIRS:%=%/}
.PHONY: ${_IMAGE_SUBDIRS_SLASH}
${_IMAGE_SUBDIRS_SLASH}: %/: %

sysimages-clean:
	${RM} -r ${INSTALLS}
	for i in ${IMAGE_SUBDIRS}; do $(MAKE) -C "$$i" -f  ${MYABSELF} clean || true; done

sysimages-install:
	mkdir -p ${INSTALLS}
	for i in ${IMAGE_SUBDIRS}; do \
	$(MAKE) -C "$$i" -f  ${MYABSELF} capsule install INSTALL_DIR=../${INSTALLS}/"$$i"; done


.PHONY: all fvwrap sign zip clean generatorclean capsule

# -----------------------------------------------------------
${SYMLINKS}:
	ln -s '$^' '$@'

# -----------------------------------------------------------
fvwrap: $(OBJS_FVWRAP)

$(OBJS_FVWRAP): %.fv : %
	$(RM) image.ffs
	$(GENFW) $* -o $*.fw -e UEFI_APPLICATION || { cat ${MYDIR}BaseTools/README.txt; exit 1; }
	$(GENSEC) -s EFI_SECTION_PE32 $*.fw -o $*.fw.pe32
	$(GENFFS) -o image.ffs -t EFI_FV_FILETYPE_APPLICATION -g $($*.GUID) -i $*.fw.pe32
	$(GENFV)  -i inf/$(notdir $*.inf) -o $*.fv

# -----------------------------------------------------------
sign: $(OBJS_SIGN)

$(OBJS_CSSINPUT): %.cssinput : %     ${CSSINPUT}
	$(CSSINPUT) -input $< -bodyoffset 0x400 -svn 0 -svnindex $($*.SVNINDEX) -output $@ >/dev/null

$(OBJS_SIGN) : %.signed : %.cssinput ${KEYFILE} ${CODESIGNEMULATOR}
	${RM} $@
	>/dev/null $(CODESIGNEMULATOR) -input $< -output $@ -keyfile "${KEYFILE}"
# because codesignemulator does not report (all) errors in its exit status
	test -e $@
	dd if=$@ of=$*.csbh bs=1024 count=1


${CSSINPUT} ${CODESIGNEMULATOR}:
	${MAKE} -C ${SIGNTOOL}

# -----------------------------------------------------------
# Old C version - deprecated. Now generator.py, see RTC #38537
#$(SPIFLASHGENERATOR):
#	${MAKE} -C $(GENERATORTOOL)

# -----------------------------------------------------------
${FLASH_NO_PDAT}: $(SYMLINKS) $(SPIFLASHGENERATOR) $(LAYOUTFILE) $(OBJS_SIGN) $(OBJS_FVWRAP) $(SRCS_UNMODIFIED)
	$(SPIFLASHGENERATOR) $(LAYOUTFILE)
	${GENERATORTOOL}/dediprog-checksum.py $@
	${GENERATORTOOL}/scan-padding.py $@

${FLASH_CAPSULE}: ${FLASH_NO_PDAT}
	${BOOT_INDEX_ZERO_DIR}/FV/Tools/CapsuleCreate CapsuleComponents.ini  ./  _$@.noheader ${CAPSULE_FLAGS}
	# Insert a dummy 1K signature header
	{ dd if=/dev/zero bs=1024 count=1; cat _$@.noheader; } > $@
	rm _$@.noheader

${FLASH_WITH_PDAT}: ${FLASH_NO_PDAT} ./platform-data.ini
	${MYDIR}/platform-data/platform-data-patch.py --undefined-order
	${GENERATORTOOL}/dediprog-checksum.py $@


# -----------------------------------------------------------
layout.mk: $(SPIFLASHGENERATOR) $(LAYOUTFILE)
	$(SPIFLASHGENERATOR) $(LAYOUTFILE) -M
	# When building on NFS with high precision timestamps you
	# might see a harmless "clock skew" warning. If that bothers
	# you then enable the next line:
	# usleep 100000 || sleep 1

ifneq (install,${INSTALL_DIR})
install: ${INSTALL_DIR}
endif
.PHONY: ${INSTALL_DIR}

# If this become too big we could dump this list to a temporary
# "files2install.rsync" file and then use:
#    rsync --files-from=files2install.rsync .
FILES2INSTALL := ${FLASH_NO_PDAT} ${LAYOUTFILE} ${OTHER_GENERATOR_PRODUCTS}

${INSTALL_DIR}: ${FLASH_NO_PDAT}
	${RM} -r "${INSTALL_DIR}/"
	rsync -ar --delete  ${FILES2INSTALL} "${INSTALL_DIR}/"
	if test -e ${FLASH_CAPSULE}; then rsync -a ${FLASH_CAPSULE} "${INSTALL_DIR}/"; fi

# -----------------------------------------------------------
zip:
	${MAKE} -C ${GENERATORTOOL} $@

# -----------------------------------------------------------
clean: ramfs-clean
	$(RM) ${OBJS_FVWRAP}.txt ${OBJS_FVWRAP}.map \
	${OBJS_FVWRAP} ${OBJS_FW} ${OBJS_PE32} image.ffs \
	${OBJS_SIGN} ${OBJS_CSSINPUT} $(OBJS_CSBH) $(SYMLINKS) \
	layout.mk ${FLASH_NO_PDAT} ${FLASH_WITH_PDAT} ${OTHER_GENERATOR_PRODUCTS} ${FLASH_CAPSULE}
	${RM} -r ${INSTALL_DIR}

generatorclean: clean
	${MAKE} -C ${GENERATORTOOL} clean
	${MAKE} -C ${SIGNTOOL} clean


#############################################################
#   Optional feature to insert/overwrite kernel modules
#   (or more) into an existing cpio initramfs
#############################################################
-include ${MYDIR}/ramfs.mk

