#!/usr/bin/make -f

SHELL=/bin/bash

include /usr/share/dpkg/default.mk
include /usr/share/dpkg/buildopts.mk

# Set to DEBUG for debug builds
BUILD_TYPE ?= RELEASE
EDK2_TOOLCHAIN = GCC5
export $(EDK2_TOOLCHAIN)_AARCH64_PREFIX=aarch64-linux-gnu-
export $(EDK2_TOOLCHAIN)_ARM_PREFIX=arm-linux-gnueabi-
export $(EDK2_TOOLCHAIN)_RISCV64_PREFIX=riscv64-linux-gnu-
export $(EDK2_TOOLCHAIN)_LOONGARCH64_PREFIX=loongarch64-linux-gnu-

export PYTHON3_ENABLE=TRUE

ifeq ($(DEB_BUILD_ARCH),amd64)
	EDK2_BUILD_ARCH=X64
endif
ifeq ($(DEB_BUILD_ARCH),i386)
	EDK2_BUILD_ARCH=IA32
endif
ifeq ($(DEB_BUILD_ARCH),arm64)
	EDK2_BUILD_ARCH=AARCH64
endif

# LP: #2078252
unexport ELF_PACKAGE_METADATA

PCD_RELEASE_DATE = $(shell date -d@$(SOURCE_DATE_EPOCH) "+%m/%d/%Y")
PCD_FLAGS  = --pcd PcdFirmwareVendor=L"$(shell lsb_release -is) distribution of EDK II\\0"
PCD_FLAGS += --pcd PcdFirmwareVersionString=L"$(DEB_VERSION)\\0"
PCD_FLAGS += --pcd PcdFirmwareReleaseDateString=L"$(PCD_RELEASE_DATE)\\0"
COMMON_FLAGS  = -DCC_MEASUREMENT_ENABLE=TRUE
COMMON_FLAGS += -DNETWORK_HTTP_BOOT_ENABLE=TRUE
COMMON_FLAGS += -DNETWORK_IP6_ENABLE=TRUE
COMMON_FLAGS += -DNETWORK_TLS_ENABLE
COMMON_FLAGS += $(PCD_FLAGS)

NO_STRICTNX_COMMON_FLAGS = --pcd PcdUninstallMemAttrProtocol=TRUE

OVMF_COMMON_FLAGS  = $(COMMON_FLAGS)
OVMF_COMMON_FLAGS += -DTPM2_ENABLE=TRUE
# Uncomment for in-band debug messages
# OVMF_COMMON_FLAGS += "-DDEBUG_ON_SERIAL_PORT=TRUE"
OVMF_4M_COMMON_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB
OVMF_4M_NO_SECBOOT_FLAGS = $(OVMF_COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS)
OVMF_4M_SECBOOT_FLAGS = $(OVMF_4M_COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE -DSMM_REQUIRE=TRUE
OVMF_4M_SECBOOT_STRICTNX_FLAGS = $(OVMF_4M_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE -DSMM_REQUIRE=TRUE
OVMF32_4M_COMMON_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB
OVMF32_4M_NO_SECBOOT_FLAGS = $(OVMF32_4M_COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS)
OVMF32_4M_SECBOOT_FLAGS = $(OVMF32_4M_COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE -DSMM_REQUIRE=TRUE
OVMF32_4M_SECBOOT_STRICTNX_FLAGS = $(OVMF32_4M_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE -DSMM_REQUIRE=TRUE

AAVMF_COMMON_FLAGS  = $(COMMON_FLAGS)
AAVMF_COMMON_FLAGS += -DTPM2_ENABLE=TRUE
AAVMF_COMMON_FLAGS += -DTPM2_CONFIG_ENABLE=TRUE
AAVMF_COMMON_FLAGS += -DCAVIUM_ERRATUM_27456=TRUE
AAVMF_NO_SECBOOT_FLAGS = $(COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS)
AAVMF_SECBOOT_FLAGS = $(AAVMF_COMMON_FLAGS) $(NO_STRICTNX_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE
AAVMF_SECBOOT_STRICTNX_FLAGS = $(AAVMF_COMMON_FLAGS) -DBUILD_SHELL=FALSE -DSECURE_BOOT_ENABLE=TRUE

RISCV64_FLAGS = $(COMMON_FLAGS)
LOONGARCH64_FLAGS = $(COMMON_FLAGS)

# Clear variables used internally by the edk2 build system
undefine WORKSPACE
undefine ECP_SOURCE
undefine EDK_SOURCE
undefine EFI_SOURCE
undefine EDK_TOOLS_PATH
undefine CONF_PATH

DESTDIR ?= $(CURDIR)/debian/tmp

%:
	dh $@

override_dh_auto_install:
	$(MAKE) -f debian/rules -j$(DEB_BUILD_OPTION_PARALLEL) install-all

override_dh_auto_build:
	$(MAKE) -f debian/rules -j$(DEB_BUILD_OPTION_PARALLEL) build-all

override_dh_auto_test: override_dh_auto_install
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
	$(MAKE) -f debian/rules -j$(DEB_BUILD_OPTION_PARALLEL) test-all
endif

OVMF_INSTALL_DIR = $(DESTDIR)/usr/share/OVMF
OVMF_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-x64
OVMF64_BUILD_ROOT = Build/OvmfX64
OVMF64_BUILD_DIR = $(OVMF64_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)
AMDSEV_BUILD_ROOT = Build/AmdSev
AMDSEV_BUILD_DIR = $(AMDSEV_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

OVMF32_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-ia32
OVMF32_BUILD_ROOT = Build/OvmfIa32
OVMF32_BUILD_DIR = $(OVMF32_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

AAVMF_INSTALL_DIR = $(DESTDIR)/usr/share/AAVMF
AAVMF_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-aa64
AAVMF_BUILD_ROOT = Build/ArmVirtQemu-AARCH64
AAVMF_BUILD_DIR = $(AAVMF_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

AAVMF32_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-arm
AAVMF32_BUILD_ROOT = Build/ArmVirtQemu-ARM
AAVMF32_BUILD_DIR = $(AAVMF32_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

RISCV64_INSTALL_DIR = $(DESTDIR)/usr/share/qemu-efi-riscv64
RISCV64_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-riscv64
RISCV64_BUILD_ROOT = Build/RiscVVirtQemu
RISCV64_BUILD_DIR = $(RISCV64_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

LOONGARCH64_INSTALL_DIR = $(DESTDIR)/usr/share/qemu-efi-loongarch64
LOONGARCH64_SHELL_INSTALL_DIR = $(DESTDIR)/usr/share/efi-shell-loongarch64
LOONGARCH64_BUILD_ROOT = Build/LoongArchVirtQemu
LOONGARCH64_BUILD_DIR = $(LOONGARCH64_BUILD_ROOT)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN)

# -j options in MAKEFLAGS cause the edk2 build system to fall over.
MAKEFLAGS_NO_PARALLEL := $(filter-out -j%,$(MAKEFLAGS))
# If a parallel build was requested, we'll build multiple images in parallel.
# Tell each image build to just use one thread to avoid overload.
ifneq ($(MAKEFLAGS),$(MAKEFLAGS_NO_PARALLEL))
	MAX_CONCURRENT_THREAD_NUMBER ?= 1
	# This var doesn't seem to be respected, so we explicitly
        # pass "-n" instead.
	#export MAX_CONCURRENT_THREAD_NUMBER
	MAX_THREADS_ARG = -n $(MAX_CONCURRENT_THREAD_NUMBER)
endif

define edksetup
	rm $(2)/Conf/BuildEnv.sh
	sed "s|$(1)|$(2)|g" < $(1)/Conf/BuildEnv.sh > $(2)/Conf/BuildEnv.sh
endef

define do_build
	rm -rf build/$(1)/$(2)
	mkdir -p build/$(1)/$(2)
	rsync -aH --link-dest=$(CURDIR) \
		--exclude=/.git/ --exclude=/build/ --exclude=/debian/ \
		./ build/$(1)/$(2)/
	$(call edksetup,$(CURDIR),$(CURDIR)/build/$(1)/$(2))
	cd build/$(1)/$(2) && . edksetup.sh; \
		export MAKEFLAGS=$(MAKEFLAGS_NO_PARALLEL); \
		build -a $(3) -t $(EDK2_TOOLCHAIN) \
		-p $(4) $(5) -b $(BUILD_TYPE) $(MAX_THREADS_ARG)
endef

SHELL_ARCHS = aa64 arm ia32 loongarch64 riscv64 x64

.PHONY: install-all build-all test-all
install-all: install-qemu-efi-aarch64 install-qemu-efi-arm install-ovmf install-ovmf32 install-qemu-efi-riscv64 install-qemu-efi-loongarch64 $(addprefix install-efi-shell-,$(SHELL_ARCHS)) $(AAVMF_PREENROLLED_VARS) $(OVMF64_PREENROLLED_VARS)
build-all: build-qemu-efi-aarch64 build-qemu-efi-arm build-ovmf build-ovmf32 build-qemu-efi-riscv64 build-qemu-efi-loongarch64 $(addprefix build-efi-shell-,$(SHELL_ARCHS))
test-all: export PYTHONPATH=$(CURDIR)/debian/python
test-all: export DEB_EDK2_ROOT=$(DESTDIR)
test-all:
	./debian/tests/shell.py

debian/setup-build-stamp:
	set -e; . ./edksetup.sh; \
	make -C BaseTools ARCH=$(EDK2_BUILD_ARCH)
	touch $@

## OVMF32
.PHONY: install-ovmf32 build-ovmf32
install-ovmf32: install-ovmf32-no-secboot install-ovmf32-secboot install-ovmf32-secboot-strictnx
build-ovmf32: build-ovmf32-no-secboot build-ovmf32-secboot build-ovmf32-secboot-strictnx

# OVMF32 NO-SECBOOT AND SHELL
OVMF32_NO_SECBOOT_BUILD_DIR = build/ovmf32/no-secboot/$(OVMF32_BUILD_DIR)
.PHONY: install-ovmf32-no-secboot install-efi-shell-ia32 build-ovmf32-no-secboot build-efi-shell-ia32
install-ovmf32-no-secboot: build-ovmf32-no-secboot
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF32_CODE_4M.fd
	cp $(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_VARS.fd \
		$(OVMF_INSTALL_DIR)/OVMF32_VARS_4M.fd

install-efi-shell-ia32:	build-efi-shell-ia32
	mkdir -p $(OVMF32_SHELL_INSTALL_DIR)
	cp $(OVMF32_NO_SECBOOT_BUILD_DIR)/IA32/Shell.efi \
		$(OVMF32_SHELL_INSTALL_DIR)/shellia32.efi

build-ovmf32-no-secboot: $(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd $(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_VARS.fd
build-efi-shell-ia32: $(OVMF32_NO_SECBOOT_BUILD_DIR)/IA32/Shell.efi
$(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd $(OVMF32_NO_SECBOOT_BUILD_DIR)/FV/OVMF_VARS.fd $(OVMF32_NO_SECBOOT_BUILD_DIR)/IA32/Shell.efi &: debian/setup-build-stamp
	$(call do_build,ovmf32,no-secboot,IA32,OvmfPkg/OvmfPkgIa32.dsc,$(OVMF32_4M_NO_SECBOOT_FLAGS))

## OVMF32 SECBOOT
OVMF32_SECBOOT_BUILD_DIR = build/ovmf32/secboot/$(OVMF32_BUILD_DIR)
.PHONY: install-ovmf32-secboot build-ovmf32-secboot
install-ovmf32-secboot: build-ovmf32-secboot
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF32_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF32_CODE_4M.secboot.fd

build-ovmf32-secboot: $(OVMF32_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd
$(OVMF32_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd: debian/setup-build-stamp
	$(call do_build,ovmf32,secboot,IA32,OvmfPkg/OvmfPkgIa32.dsc,$(OVMF32_4M_SECBOOT_FLAGS))

# OVMF32 SECBOOT-STRICTNX
OVMF32_SECBOOT_STRICTNX_BUILD_DIR = build/ovmf32/secboot-strictnx/$(OVMF32_BUILD_DIR)
.PHONY: install-ovmf32-secboot-strictnx build-ovmf32-secboot-strictnx
install-ovmf32-secboot-strictnx: build-ovmf32-secboot-strictnx
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF32_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF32_CODE_4M.secboot.strictnx.fd

build-ovmf32-secboot-strictnx: $(OVMF32_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd
$(OVMF32_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd: debian/setup-build-stamp
	$(call do_build,ovmf32,secboot-strictnx,IA32,OvmfPkg/OvmfPkgIa32.dsc,$(OVMF32_4M_SECBOOT_STRICTNX_FLAGS))

## OVMF ##
.PHONY: install-ovmf build-ovmf
install-ovmf: install-ovmf-no-secboot install-ovmf-secboot install-ovmf-secboot-strictnx
build-ovmf: build-ovmf-no-secboot build-ovmf-secboot build-ovmf-secboot-strictnx

# OVMF NO-SECBOOT AND SHELL
OVMF64_NO_SECBOOT_BUILD_DIR = build/ovmf/no-secboot/$(OVMF64_BUILD_DIR)
.PHONY: install-ovmf-no-secboot install-efi-shell-x64 build-ovmf-no-secboot build-efi-shell-x64
install-ovmf-no-secboot: build-ovmf-no-secboot
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF64_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF_CODE_4M.fd
	cp $(OVMF64_NO_SECBOOT_BUILD_DIR)/FV/OVMF_VARS.fd \
		$(OVMF_INSTALL_DIR)/OVMF_VARS_4M.fd

install-efi-shell-x64: build-efi-shell-x64
	mkdir -p $(OVMF_SHELL_INSTALL_DIR)
	cp $(OVMF64_NO_SECBOOT_BUILD_DIR)/X64/Shell.efi \
		$(OVMF_SHELL_INSTALL_DIR)/shellx64.efi

build-ovmf-no-secboot: $(OVMF64_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd
build-efi-shell-x64: $(OVMF64_NO_SECBOOT_BUILD_DIR)/X64/Shell.efi
$(OVMF64_NO_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd $(OVMF64_NO_SECBOOT_BUILD_DIR)/X64/Shell.efi &: debian/setup-build-stamp
	$(call do_build,ovmf,no-secboot,X64,OvmfPkg/OvmfPkgX64.dsc,$(OVMF_4M_NO_SECBOOT_FLAGS))

# OVMF SECBOOT
OVMF64_SECBOOT_BUILD_DIR = build/ovmf/secboot/$(OVMF64_BUILD_DIR)
OVMF64_PREENROLLED_VARS = $(addprefix $(OVMF64_SECBOOT_BUILD_DIR)/FV/,OVMF_VARS_4M.ms.fd OVMF_VARS_4M.snakeoil.fd)
.PHONY: install-ovmf-secboot build-ovmf-secboot
install-ovmf-secboot: build-ovmf-secboot
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF64_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF_CODE_4M.secboot.fd
	ln -sf OVMF_CODE_4M.secboot.fd $(OVMF_INSTALL_DIR)/OVMF_CODE_4M.ms.fd
	ln -sf OVMF_CODE_4M.secboot.fd $(OVMF_INSTALL_DIR)/OVMF_CODE_4M.snakeoil.fd
	cp -a $(OVMF64_PREENROLLED_VARS) $(OVMF_INSTALL_DIR)
	mkdir -p $(DESTDIR)/usr/share/ovmf
	cp -a debian/PkKek-1-snakeoil.* $(DESTDIR)/usr/share/ovmf

build-ovmf-secboot: $(OVMF64_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd $(OVMF64_PREENROLLED_VARS)
$(OVMF64_SECBOOT_BUILD_DIR)/FV/OVMF_CODE.fd $(OVMF64_SECBOOT_BUILD_DIR)/FV/OVMF_VARS.fd &: debian/setup-build-stamp
	$(call do_build,ovmf,secboot,X64,OvmfPkg/OvmfPkgX64.dsc,$(OVMF_4M_SECBOOT_FLAGS))

%/OVMF_VARS_4M.ms.fd: %/OVMF_VARS.fd debian/PkKek-1-vendor.pem
	$(call enroll_vendor,$<,$@,amd64)

%/OVMF_VARS_4M.snakeoil.fd: %/OVMF_VARS.fd debian/PkKek-1-snakeoil.pem
	$(call enroll_snakeoil,$<,$@)

# OVMF SECBOOT-STRICTNX
OVMF64_SECBOOT_STRICTNX_BUILD_DIR = build/ovmf/secboot-strictnx/$(OVMF64_BUILD_DIR)
.PHONY: install-ovmf-secboot-strictnx build-ovmf-secboot-strictnx
install-ovmf-secboot-strictnx: build-ovmf-secboot-strictnx
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF64_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd \
		$(OVMF_INSTALL_DIR)/OVMF_CODE_4M.secboot.strictnx.fd

build-ovmf-secboot-strictnx: $(OVMF64_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd
$(OVMF64_SECBOOT_STRICTNX_BUILD_DIR)/FV/OVMF_CODE.fd: debian/setup-build-stamp
	$(call do_build,ovmf,secboot-strictnx,X64,OvmfPkg/OvmfPkgX64.dsc,$(OVMF_4M_SECBOOT_STRICTNX_FLAGS))

# AMDSEV
OVMF64_AMDSEV_BUILD_DIR = build/ovmf/amdsev/$(AMDSEV_BUILD_DIR)
.PHONY: install-ovmf-amdsev build-ovmf-amdsev
install-ovmf-amdsev: build-ovmf-amdsev
	mkdir -p $(OVMF_INSTALL_DIR)
	cp $(OVMF64_AMDSEV_BUILD_DIR)/FV/OVMF.fd \
		$(OVMF_INSTALL_DIR)/OVMF.amdsev.fd

build-ovmf-amdsev: $(OVMF64_AMDSEV_BUILD_DIR)/FV/OVMF.fd
$(OVMF64_AMDSEV_BUILD_DIR)/FV/OVMF.fd: debian/setup-build-stamp
	$(call do_build,ovmf,amdsev,X64,OvmfPkg/AmdSev/AmdSevX64.dsc,$(OVMF_COMMON_FLAGS))

## QEMU-EFI-AARCH64 ##
.PHONY: install-qemu-efi-aarch64 build-qemu-efi-aarch64
install-qemu-efi-aarch64: install-qemu-efi-aarch64-no-secboot install-qemu-efi-aarch64-secboot install-qemu-efi-aarch64-secboot-strictnx
build-qemu-efi-aarch64: build-qemu-efi-aarch64-no-secboot build-qemu-efi-aarch64-secboot build-qemu-efi-aarch64-secboot-strictnx

# QEMU-EFI-AARCH64 NO-SECBOOT AND SHELL
AAVMF_NO_SECBOOT_BUILD_DIR = build/qemu-efi-aarch64/no-secboot/$(AAVMF_BUILD_DIR)
.PHONY: install-qemu-efi-aarch64-no-secboot install-efi-shell-aa64 build-qemu-efi-aarch64-no-secboot build-efi-shell-aa64
install-qemu-efi-aarch64-no-secboot: build-qemu-efi-aarch64-no-secboot
	mkdir -p $(AAVMF_INSTALL_DIR)
	cp $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF_CODE.no-secboot.fd
	cp $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_VARS.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF_VARS.fd
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF_CODE.no-secboot.fd
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF_VARS.fd
	mkdir -p $(DESTDIR)/usr/share/qemu-efi-aarch64
	cp $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(DESTDIR)/usr/share/qemu-efi-aarch64

install-efi-shell-aa64: build-efi-shell-aa64
	mkdir -p $(AAVMF_SHELL_INSTALL_DIR)
	cp $(AAVMF_NO_SECBOOT_BUILD_DIR)/AARCH64/Shell.efi \
		$(AAVMF_SHELL_INSTALL_DIR)/shellaa64.efi

build-qemu-efi-aarch64-no-secboot: $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_VARS.fd

build-efi-shell-aa64: $(AAVMF_NO_SECBOOT_BUILD_DIR)/AARCH64/Shell.efi
$(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF_NO_SECBOOT_BUILD_DIR)/FV/QEMU_VARS.fd $(AAVMF_NO_SECBOOT_BUILD_DIR)/AARCH64/Shell.efi &: debian/setup-build-stamp BaseTools/Bin/GccLto/liblto-aarch64.a
	$(call do_build,qemu-efi-aarch64,no-secboot,AARCH64,ArmVirtPkg/ArmVirtQemu.dsc,$(AAVMF_NO_SECBOOT_FLAGS))

# QEMU-EFI-AARCH64 SECBOOT
AAVMF_SECBOOT_BUILD_DIR = build/qemu-efi-aarch64/secboot/$(AAVMF_BUILD_DIR)
AAVMF_PREENROLLED_VARS = $(addprefix $(AAVMF_SECBOOT_BUILD_DIR)/FV/,AAVMF_VARS.ms.fd AAVMF_VARS.snakeoil.fd)
.PHONY: install-qemu-efi-aarch64-secboot build-qemu-efi-aarch64-secboot
install-qemu-efi-aarch64-secboot: build-qemu-efi-aarch64-secboot
	mkdir -p $(AAVMF_INSTALL_DIR)
	cp $(AAVMF_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF_CODE.secboot.fd
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF_CODE.secboot.fd
	ln -sf AAVMF_CODE.secboot.fd $(AAVMF_INSTALL_DIR)/AAVMF_CODE.ms.fd
	ln -sf AAVMF_CODE.secboot.fd $(AAVMF_INSTALL_DIR)/AAVMF_CODE.snakeoil.fd
	cp -a $(AAVMF_PREENROLLED_VARS) $(AAVMF_INSTALL_DIR)
	mkdir -p $(DESTDIR)/usr/share/qemu-efi-aarch64
	cp -a debian/PkKek-1-snakeoil.* $(DESTDIR)/usr/share/qemu-efi-aarch64

build-qemu-efi-aarch64-secboot: $(AAVMF_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF_PREENROLLED_VARS)
$(AAVMF_SECBOOT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF_SECBOOT_BUILD_DIR)/FV/QEMU_VARS.fd &: debian/setup-build-stamp BaseTools/Bin/GccLto/liblto-aarch64.a
	$(call do_build,qemu-efi-aarch64,secboot,AARCH64,ArmVirtPkg/ArmVirtQemu.dsc,$(AAVMF_SECBOOT_FLAGS))

%/AAVMF_VARS.ms.fd: %/QEMU_VARS.fd debian/PkKek-1-vendor.pem
	$(call enroll_vendor,$<,$@,arm64)
	truncate -s 64M $@

%/AAVMF_VARS.snakeoil.fd: %/QEMU_VARS.fd debian/PkKek-1-vendor.pem
	$(call enroll_snakeoil,$<,$@)
	truncate -s 64M $@


# QEMU_EFI_AARCH64 SECBOOT-STRICTNX
AAVMF_SECBOOT_STRICTNX_BUILD_DIR = build/qemu-efi-aarch64/secboot-strictnx/$(AAVMF_BUILD_DIR)
.PHONY: install-qemu-efi-aarch64-secboot-strictnx build-qemu-efi-aarch64-secboot-strictnx
install-qemu-efi-aarch64-secboot-strictnx: build-qemu-efi-aarch64-secboot-strictnx
	mkdir -p $(AAVMF_INSTALL_DIR)
	cp $(AAVMF_SECBOOT_STRICTNX_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF_CODE.secboot.strictnx.fd
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF_CODE.secboot.strictnx.fd

build-qemu-efi-aarch64-secboot-strictnx: $(AAVMF_SECBOOT_STRICTNX_BUILD_DIR)/FV/QEMU_EFI.fd
$(AAVMF_SECBOOT_STRICTNX_BUILD_DIR)/FV/QEMU_EFI.fd: debian/setup-build-stamp BaseTools/Bin/GccLto/liblto-aarch64.a
	$(call do_build,qemu-efi-aarch64,secboot-strictnx,AARCH64,ArmVirtPkg/ArmVirtQemu.dsc,$(AAVMF_SECBOOT_STRICTNX_FLAGS))

ifeq ($(call dpkg_vendor_derives_from_v1,ubuntu),yes)
debian/PkKek-1-vendor.pem: debian/PkKek-1-Ubuntu.pem
else
debian/PkKek-1-vendor.pem: debian/PkKek-1-Debian.pem
endif
	ln -sf `basename $<` $@

# Usage: $(call enroll_vendor,<var-template>,<output-file>,<uefi-arch>)
enroll_vendor   = virt-fw-vars --input $(1) --output $(2) \
                    --enroll-cert debian/PkKek-1-vendor.pem \
                    --set-dbx ./debian/DBXUpdate-*.$(3).bin
# Usage: $(call enroll_snakeoil,<var-template>,<output-file>)
enroll_snakeoil = virt-fw-vars --input $(1) --output $(2) \
                    --set-pk OvmfEnrollDefaultKeys \
                             debian/PkKek-1-snakeoil.pem \
                    --add-kek OvmfEnrollDefaultKeys \
                             debian/PkKek-1-snakeoil.pem \
                    --add-db OvmfEnrollDefaultKeys \
                             debian/PkKek-1-snakeoil.pem

BaseTools/Bin/GccLto/liblto-aarch64.a:	BaseTools/Bin/GccLto/liblto-aarch64.s
	$($(EDK2_TOOLCHAIN)_AARCH64_PREFIX)gcc -c -fpic $< -o $@

BaseTools/Bin/GccLto/liblto-arm.a: BaseTools/Bin/GccLto/liblto-arm.s
	$($(EDK2_TOOLCHAIN)_ARM_PREFIX)gcc -c -fpic $< -o $@

# QEMU-EFI-ARM AND SHELL
AAVMF32_DEFAULT_BUILD_DIR = build/qemu-efi-arm/default/$(AAVMF32_BUILD_DIR)
.PHONY: install-qemu-efi-arm install-efi-shell-arm build-qemu-efi-arm build-efi-shell-arm
install-qemu-efi-arm: build-qemu-efi-arm
	mkdir -p $(AAVMF_INSTALL_DIR)
	cp $(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF32_CODE.fd
	cp $(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd \
		$(AAVMF_INSTALL_DIR)/AAVMF32_VARS.fd
	# QEMU expects 64MiB CODE and VARS files on ARM/AARCH64 architectures
	# Truncate the firmware files to the expected size
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF32_CODE.fd
	truncate -s 64M $(AAVMF_INSTALL_DIR)/AAVMF32_VARS.fd

install-efi-shell-arm: build-efi-shell-arm
	mkdir -p $(AAVMF32_SHELL_INSTALL_DIR)
	cp $(AAVMF32_DEFAULT_BUILD_DIR)/ARM/Shell.efi \
		$(AAVMF32_SHELL_INSTALL_DIR)/shellarm.efi

build-qemu-efi-arm: $(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd
build-efi-shell-arm: $(AAVMF32_DEFAULT_BUILD_DIR)/ARM/Shell.efi

$(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd $(AAVMF32_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd $(AAVMF32_DEFAULT_BUILD_DIR)/ARM/Shell.efi &: debian/setup-build-stamp BaseTools/Bin/GccLto/liblto-arm.a
	$(call do_build,qemu-efi-arm,default,ARM,ArmVirtPkg/ArmVirtQemu.dsc,$(AAVMF32_FLAGS))

## QEMU-EFI-RISCV64
# QEMU-EFI-RISCV64 AND SHELL
RISCV64_DEFAULT_BUILD_DIR = build/qemu-efi-riscv64/default/$(RISCV64_BUILD_DIR)
.PHONY: install-qemu-efi-riscv64 install-efi-shell-riscv64 build-qemu-efi-riscv64 build-efi-shell-riscv64
install-qemu-efi-riscv64: build-qemu-efi-riscv64
	mkdir -p $(RISCV64_INSTALL_DIR)
	cp $(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_CODE.fd \
		$(RISCV64_INSTALL_DIR)/
	cp $(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_VARS.fd \
		$(RISCV64_INSTALL_DIR)/
	truncate -s 32M $(RISCV64_INSTALL_DIR)/RISCV_VIRT_CODE.fd
	truncate -s 32M $(RISCV64_INSTALL_DIR)/RISCV_VIRT_VARS.fd

install-efi-shell-riscv64: build-efi-shell-riscv64
	mkdir -p $(RISCV64_SHELL_INSTALL_DIR)
	cp $(RISCV64_DEFAULT_BUILD_DIR)/RISCV64/Shell.efi \
		$(RISCV64_SHELL_INSTALL_DIR)/shellriscv64.efi

build-qemu-efi-riscv64: $(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_CODE.fd $(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_VARS.fd
build-efi-shell-riscv64: $(RISCV64_DEFAULT_BUILD_DIR)/RISCV64/Shell.efi
$(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_CODE.fd $(RISCV64_DEFAULT_BUILD_DIR)/FV/RISCV_VIRT_VARS.fd $(RISCV64_DEFAULT_BUILD_DIR)/RISCV64/Shell.efi &: debian/setup-build-stamp
	$(call do_build,qemu-efi-riscv64,default,RISCV64,OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc,$(RISCV64_FLAGS))

## QEMU-EFI-LOONGARCH64
# QEMU-EFI-LOONGARCH64 AND SHELL
LOONGARCH64_DEFAULT_BUILD_DIR = build/qemu-efi-loongarch64/default/$(LOONGARCH64_BUILD_DIR)
.PHONY: install-qemu-efi-loongarch64 install-efi-shell-loongarch64 build-qemu-efi-loongarch64 build-efi-shell-loongarch64
install-qemu-efi-loongarch64: build-qemu-efi-loongarch64
	mkdir -p $(LOONGARCH64_INSTALL_DIR)
	cp $(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd \
		$(LOONGARCH64_INSTALL_DIR)/
	cp $(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd \
		$(LOONGARCH64_INSTALL_DIR)/
	truncate -s 16M $(LOONGARCH64_INSTALL_DIR)/QEMU_EFI.fd
	truncate -s 16M $(LOONGARCH64_INSTALL_DIR)/QEMU_VARS.fd

install-efi-shell-loongarch64: build-efi-shell-loongarch64
	mkdir -p $(LOONGARCH64_SHELL_INSTALL_DIR)
	cp $(LOONGARCH64_DEFAULT_BUILD_DIR)/LOONGARCH64/Shell.efi \
		$(LOONGARCH64_SHELL_INSTALL_DIR)/shellloongarch64.efi

build-qemu-efi-loongarch64: $(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd $(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd
build-efi-shell-loongarch64: $(LOONGARCH64_DEFAULT_BUILD_DIR)/LOONGARCH64/Shell.efi
$(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_EFI.fd $(LOONGARCH64_DEFAULT_BUILD_DIR)/FV/QEMU_VARS.fd $(LOONGARCH64_DEFAULT_BUILD_DIR)/LOONGARCH64/Shell.efi &: debian/setup-build-stamp
	$(call do_build,qemu-efi-loongarch64,default,LOONGARCH64,OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc,$(LOONGARCH64_FLAGS))

override_dh_auto_clean:
	rm -rf build
	rm -f BaseTools/Bin/GccLto/liblto-*.a
	rm -f debian/PkKek-1-vendor.pem

# Only embed code that is actually used; requested by the Ubuntu Security Team
EMBEDDED_SUBMODULES += CryptoPkg/Library/MbedTlsLib/mbedtls
EMBEDDED_SUBMODULES += CryptoPkg/Library/OpensslLib/openssl
EMBEDDED_SUBMODULES += MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
EMBEDDED_SUBMODULES += MdePkg/Library/BaseFdtLib/libfdt
EMBEDDED_SUBMODULES += MdePkg/Library/MipiSysTLib/mipisyst
EMBEDDED_SUBMODULES += SecurityPkg/DeviceSecurity/SpdmLib/libspdm
get-orig-source:
	# Should be executed on a checkout of the upstream master branch,
	# with the debian/ directory manually copied in.
	rm -rf edk2.tmp && git clone . edk2.tmp
	# Embed submodules. Don't recurse - openssl will bring in MBs of
	# stuff we don't need
	set -e; cd edk2.tmp; \
	for submodule in $(EMBEDDED_SUBMODULES); do \
		git submodule update --depth 1 --init $$submodule; \
	done
	rm -rf edk2-$(DEB_VERSION_UPSTREAM) && \
		mkdir edk2-$(DEB_VERSION_UPSTREAM)
	cd edk2.tmp && git archive HEAD | \
		tar xv -C ../edk2-$(DEB_VERSION_UPSTREAM)
	cd edk2.tmp && git submodule foreach \
		'git archive HEAD | tar xv -C $$toplevel/../edk2-$(DEB_VERSION_UPSTREAM)/$$sm_path'
	ln -s ../debian edk2-$(DEB_VERSION_UPSTREAM)
	# Remove known-binary files
	cd edk2-$(DEB_VERSION_UPSTREAM) && python3 ./debian/remove-binaries.py
	# Look for possible unknown binary files
	cd edk2-$(DEB_VERSION_UPSTREAM) && python3 ./debian/find-binaries.py
	rm edk2-$(DEB_VERSION_UPSTREAM)/debian
	tar Jcvf ../edk2_$(DEB_VERSION_UPSTREAM).orig.tar.xz \
		edk2-$(DEB_VERSION_UPSTREAM)
	rm -rf edk2.tmp edk2-$(DEB_VERSION_UPSTREAM)

update-dbx:
	rm -rf debian/DBXUpdate-*.bin
	set -ex; \
	tmpdir="$$(mktemp -d)"; \
	git clone https://github.com/microsoft/secureboot_objects $$tmpdir; \
	for arch in amd64 arm64; do \
	  bin=PostSignedObjects/DBX/$$arch/DBXUpdate.bin; \
	  date=$$(cd $$tmpdir && git log -1 --pretty=format:"%cs" $$bin); \
	  cp $$tmpdir/$$bin debian/DBXUpdate-$${date}.$${arch}.bin; \
	done; \
	rm -rf "$$tmpdir"
	ls debian/DBXUpdate-*.bin > debian/source/include-binaries
