#
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2021-2022 , Chunguang Yang <yangchg@chinatelecom.cn>
#
bits = 64
ldarch = elf64-littleaarch64

arch_LDFLAGS = -pie -n
arch_LDFLAGS += -z notext
CFLAGS += -mstrict-align

mno_outline_atomics := $(call cc-option, -mno-outline-atomics, "")
CFLAGS += $(mno_outline_atomics)
CFLAGS += -DCONFIG_RELOC
CFLAGS += -std=gnu99
CFLAGS += -ffreestanding
CFLAGS += -O2
CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/libfdt -I lib

define arch_elf_check =
	$(if $(shell ! $(READELF) -rW $(1) >&/dev/null && echo "nok"),
		$(error $(shell $(READELF) -rW $(1) 2>&1)))
	$(if $(shell $(READELF) -rW $(1) | grep R_ | grep -v R_AARCH64_RELATIVE),
		$(error $(1) has unsupported reloc types))
endef

cstart.o = $(TEST_DIR)/cstart64.o
cflatobjs += lib/arm64/stack.o lib/arm64/processor.o
cflatobjs += lib/arm64/spinlock.o lib/alloc_phys.o
cflatobjs += lib/arm64/gic-v3-its.o lib/arm64/gic-v3-its-cmd.o
cflatobjs += lib/util.o lib/getchar.o
cflatobjs += lib/alloc_page.o lib/vmalloc.o lib/alloc.o
cflatobjs += lib/devicetree.o lib/migrate.o
cflatobjs += lib/pci.o lib/pci-testdev.o lib/pci-host-generic.o
cflatobjs += lib/virtio.o lib/virtio-mmio.o
cflatobjs += lib/chr-testdev.o lib/arm/setup.o lib/arm/mmu.o
cflatobjs += lib/arm/io.o lib/arm/bitops.o lib/arm/smp.o
cflatobjs += lib/arm/psci.o lib/arm/delay.o lib/arm/timer.o
cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
OBJDIRS += lib/arm
OBJDIRS += lib/arm64

exe = flat

# arm64 specific tests
tests = $(TEST_DIR)/dummy.$(exe)
tests += $(TEST_DIR)/timer.$(exe)
tests += $(TEST_DIR)/gic.$(exe)
tests += $(TEST_DIR)/reg.$(exe)

tests-all = $(tests)
all: directories $(tests-all)

$(TEST_DIR)/sieve.elf: AUXFLAGS = 0x1

AUXFLAGS ?= 0x0

# stack.o relies on frame pointers.
KEEP_FRAME_POINTER := y

# We want to keep intermediate files
.PRECIOUS: %.elf %.o

asm-offsets = lib/$(ARCH)/asm-offsets.h
include $(SRCDIR)/arm/asm-offsets.mak

libeabi = lib/arm/libeabi.a
eabiobjs = lib/arm/eabi_compat.o

FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi)

%.elf: LDFLAGS += $(arch_LDFLAGS)
%.elf: %.o $(FLATLIBS) $(SRCDIR)/arm/flat.lds $(cstart.o)
	$(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \
		-DPROGNAME=\"$(@:.elf=.flat)\" -DAUXFLAGS=$(AUXFLAGS)
	$(LD) $(LDFLAGS) -o $@ -T $(SRCDIR)/arm/flat.lds \
		$(filter %.o, $^) $(FLATLIBS) $(@:.elf=.aux.o)
	$(RM) $(@:.elf=.aux.o)
	@chmod a-x $@

%.flat: %.elf
	$(call arch_elf_check, $^)
	$(OBJCOPY) -O binary $^ $@
	@chmod a-x $@

$(libeabi): $(eabiobjs)
	$(AR) rcs $@ $^

arm_clean: asm_offsets_clean
	$(RM) $(TEST_DIR)/*.{o,flat,elf,so,efi,debug} $(libeabi) $(eabiobjs) \
	      $(TEST_DIR)/.*.d $(TEST_DIR)/efi/.*.d lib/arm/.*.d

generated-files = $(asm-offsets)
$(tests-all:.$(exe)=.o) $(cstart.o) $(cflatobjs): $(generated-files)
