#
#  Copyright (c) 2012-2018 Texas Instruments Incorporated - http://www.ti.com
#  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 Texas Instruments Incorporated 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.
#
%%{
    // used to 'escape' the percent and backtick chars throughout
    var PCT = '%';
    var BKTK = '`';

    var platform = this.arguments[0];
    var core = this.arguments[1];
    var suffix = this.arguments[2];
    var target = this.arguments[3];

    var lcCore = core.toLowerCase();
    var platInst = "";
    var cgtools = target;
    var csprefix = "";

    if (platform.match(/^DRA7XX_bios_elf$/)) {
        platInst = "ti.platforms.evmDRA7XX:" + lcCore;
    } else if (platform.match(/^AM572X_bios_elf$/)) {
        platInst = "ti.platforms.evmAM572X:" + lcCore;
    } else if (platform.match(/^AM571X_bios_elf$/)) {
        platInst = "ti.platforms.evmAM571X:" + lcCore;
    } else if (platform.match(/^TI814X_bios_elf$/)) {
        platInst = "ti.platforms.evmTI814X:" + lcCore;
    } else if (platform.match(/^C6A8149_bios_elf$/)) {
        platInst = "ti.platforms.evmC6A8149:" + lcCore;
    } else if (platform.match(/^TCI6636_bios_elf$/)) {
        platInst = "ti.platforms.evmTCI6636K2H:" + lcCore;
    } else if (platform.match(/^66AK2E_bios_elf$/)) {
        platInst = "ti.platforms.evmC66AK2E:" + lcCore;
    } else if (platform.match(/^TCI6630_bios_elf$/)) {
        platInst = "ti.platforms.evmTCI6630K2L:" + lcCore;
    } else if (platform.match(/^66AK2G_bios_elf$/)) {
        platInst = "ti.platforms.evmTCI66AK2G02:" + lcCore;
    } else if (platform.match(/^AM65XX_bios_elf$/)) {
        platInst = "ti.platforms.cortexA:AM65X";
        suffix = "a53fg";
    } else {
        throw new Error("unsupported platform: " + platform);
    }

    if (target.match(/^ti.targets.arm.elf.A8Fnv$/)) {
        cc = "bin/armcl";
        lnk = "bin/armcl -z";
        ldlibs = "$(CGTOOLS)/lib/libc.a"
    } else if (target.match(/^gnu.targets.arm.A15F$/)) {
	csprefix = "gnu.targets.arm.A15F";
        cc = "/bin/arm-none-eabi-gcc";
        lnk = "/bin/arm-none-eabi-gcc";
    } else if (target.match(/^gnu.targets.arm.A53F$/)) {
        /* gnu.targets.arm.A53F */
        csprefix = "gnu.targets.arm.A53F";
        cc = "/bin/aarch64-elf-gcc";
        lnk = "/bin/aarch64-elf-gcc";
    }
    else {
        throw new Error("unsupported target: " + target);
    }

%%}

#
#  ======== makefile ========
#

EXBASE = ..
include $(EXBASE)/products.mak

srcs = Main`core`.c Svr`core`.c App`core`.c
% if (platform.match(/^AM65XX_bios_elf$/)) {
srcs += InitMmu.c
% }
objs = $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.o`suffix`,$(srcs)))

libs =

CONFIG = bin/$(PROFILE)/configuro

-include $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.o`suffix`.dep,$(srcs)))

.PRECIOUS: %/compiler.opt %/linker.cmd

all:
	$(MAKE) PROFILE=debug PROCLIST="$(PROCLIST)" server_`lcCore`.x
	$(MAKE) PROFILE=release PROCLIST="$(PROCLIST)" server_`lcCore`.x

server_`lcCore`.x: bin/$(PROFILE)/server_`lcCore`.x`suffix`
% if (platform.match(/^AM65XX_bios_elf$/)) {
bin/$(PROFILE)/server_`lcCore`.x`suffix`: $(objs) $(libs) $(CONFIG)/linker.cmd A53FLink.cmd
% } else {
bin/$(PROFILE)/server_`lcCore`.x`suffix`: $(objs) $(libs) $(CONFIG)/linker.cmd
% }
	@$(ECHO) "#"
	@$(ECHO) "# Making $@ ..."
% if (cgtools.match(/^ti\./)) {
	$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
% } else if (cgtools.match(/^gnu\./)) {
% if (platform.match(/^AM65XX_bios_elf$/)) {
	$(LD) -o $@ $(LDFLAGS) $(objs) $(libs) -Wl,-T,A53FLink.cmd -Wl,-T,$(CONFIG)/linker.cmd \
		-lgcc -lc -lm -lrdimon $(LDLIBS)
% } else {
	$(LD) -o $@ $(LDFLAGS) $(objs) $(libs) -Wl,-T,$(CONFIG)/linker.cmd \
		-lgcc -lc -lm -lnosys $(LDLIBS)
% }
% } else {
%     throw ("Unrecognized cgtools: " + cgtools);
% }

bin/$(PROFILE)/obj/%.o`suffix`: %.c $(CONFIG)/compiler.opt
	@$(ECHO) "#"
	@$(ECHO) "# Making $@ ..."
% if (cgtools.match(/^ti\./)) {
	$(CC) $(CPPFLAGS) $(CFLAGS) --output_file=$@ -fc $<
% } else if (cgtools.match(/^gnu\./)) {
	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
% } else {
%     throw ("Unrecognized cgtools: " + cgtools);
% }

`PCT`/compiler.opt: `PCT`/linker.cmd ;
% if (platform.match(/^AM65XX_bios_elf$/)) {
`PCT`/linker.cmd: `core`.cfg
% } else {
`PCT`/linker.cmd: `core`.cfg ../shared/config.bld
% }
	@$(ECHO) "#"
	@$(ECHO) "# Making $@ ..."
	$(XDC_INSTALL_DIR)/xs --xdcpath="$(subst +,;,$(PKGPATH))" \
            xdc.tools.configuro -o $(CONFIG) \
            -t `target` \
            -c $(`cgtools`) \
            -p `platInst` \
% if (platform.match(/^AM65XX_bios_elf$/)) {
            -r release \
% } else {
            -b ../shared/config.bld -r release \
% }
            --cfgArgs "{ \
                procList: \"$(PROCLIST)\", \
                profile: \"$(PROFILE)\" \
            }" `core`.cfg

install:
	@$(ECHO) "#"
	@$(ECHO) "# Making $@ ..."
	@$(MKDIR) $(EXEC_DIR)/debug
	$(CP) bin/debug/server_`lcCore`.x`suffix` $(EXEC_DIR)/debug
	@$(MKDIR) $(EXEC_DIR)/release
	$(CP) bin/release/server_`lcCore`.x`suffix` $(EXEC_DIR)/release

install_rov:
	@$(ECHO) "#"
	@$(ECHO) "# Making $@ ..."
	@$(MKDIR) $(EXEC_DIR)/debug
	$(CP) bin/debug/configuro/package/cfg/`core`_p`suffix`.rov.xs $(EXEC_DIR)/debug
	@$(MKDIR) $(EXEC_DIR)/release
	$(CP) bin/release/configuro/package/cfg/`core`_p`suffix`.rov.xs $(EXEC_DIR)/release

help:
	@$(ECHO) "make                   # build executable"
	@$(ECHO) "make clean             # clean everything"

clean::
	$(RMDIR) bin

PKGPATH := $(BIOS_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$(IPC_INSTALL_DIR)/packages
PKGPATH := $(PKGPATH)+$(XDC_INSTALL_DIR)/packages
ifneq ($(PDK_INSTALL_DIR),)
PKGPATH := $(PKGPATH)+$(PDK_INSTALL_DIR)/packages
endif

#  ======== install validation ========
ifeq (install,$(MAKECMDGOALS))
ifeq (,$(EXEC_DIR))
$(error must specify EXEC_DIR)
endif
endif

#  ======== toolchain macros ========
% if (cgtools.match(/^ti\./)) {
CGTOOLS = $(`cgtools`)

CC = $(CGTOOLS)/`cc` -c
%// unused
%// AR = $(CGTOOLS)/`ar`
LD = $(CGTOOLS)/`lnk`
%// unused
%// ST = $(CGTOOLS)/`strip`

CPPFLAGS =
CFLAGS = -qq -pdsw225 -ppd=$@.dep -ppa $(CCPROFILE_$(PROFILE)) -@$(CONFIG)/compiler.opt -I.

LDFLAGS = -w -q -c -m $(@D)/obj/$(@F).map
LDLIBS = -l `ldlibs`

CCPROFILE_debug = -D_DEBUG_=1 --symdebug:dwarf
CCPROFILE_release = -O2
% } else if (cgtools.match(/^gnu\./)) {
CC = $(`csprefix`)`cc` -c -MD -MF $@.dep
%// unused
%// AR = $(CS_A15_PREFIX)ar cr
LD = $(`csprefix`)`cc`

CPPFLAGS = -Dfar= -D__DYNAMIC_REENT__
CFLAGS = -Wall -Wunused -Wunknown-pragmas -ffunction-sections -fdata-sections $(CCPROFILE_$(PROFILE)) @$(CONFIG)/compiler.opt -I.
% if (platform.match(/^AM65XX_bios_elf$/)) {
LDFLAGS = $(LDPROFILE_$(PROFILE)) -nostartfiles -Wl,-static -Wl,--gc-sections -Wl,-Map=$(@D)/obj/$(@F).map
LDLIBS = -L$(BIOS_INSTALL_DIR)/packages/gnu/targets/arm/libs/install-native/arm-none-eabi/lib/fpu
% } else {
LDFLAGS = $(LDPROFILE_$(PROFILE)) -mfloat-abi=hard -nostartfiles -Wl,-static -Wl,--gc-sections -Wl,-Map=$(@D)/obj/$(@F).map
LDLIBS = -L$(BIOS_INSTALL_DIR)/packages/gnu/targets/arm/libs/install-native/arm-none-eabi/lib/hard --specs=nano.specs
% }
CCPROFILE_debug = -g -ggdb -D_DEBUG_=1
CCPROFILE_release = -O2

LDPROFILE_debug = -g -ggdb
LDPROFILE_release =
% }

#  ======== standard macros ========
ifneq (,$(wildcard $(XDC_INSTALL_DIR)/bin/echo.exe))
    # use these on Windows
    CP      = $(XDC_INSTALL_DIR)/bin/cp
    ECHO    = $(XDC_INSTALL_DIR)/bin/echo
    MKDIR   = $(XDC_INSTALL_DIR)/bin/mkdir -p
    RM      = $(XDC_INSTALL_DIR)/bin/rm -f
    RMDIR   = $(XDC_INSTALL_DIR)/bin/rm -rf
else
    # use these on Linux
    CP      = cp
    ECHO    = echo
    MKDIR   = mkdir -p
    RM      = rm -f
    RMDIR   = rm -rf
endif

#  ======== create output directories ========
ifneq (clean,$(MAKECMDGOALS))
ifneq (,$(PROFILE))
ifeq (,$(wildcard bin/$(PROFILE)/obj))
    $(shell $(MKDIR) -p bin/$(PROFILE)/obj)
endif
endif
endif
