#===========================================================================
#  Copyright (c) 2011-2016, 2017 QUALCOMM Technologies Incorporated.
#  All Rights Reserved.
#  Qualcomm Confidential and Proprietary
#===========================================================================
#
#
# GENERAL DESCRIPTION
#    build script
#                      EDIT HISTORY FOR FILE
#
#  This section contains comments describing changes made to the module.
#  Notice that changes are listed in reverse chronological order.
#
# when       who     what, where, why
# --------   ---     ---------------------------------------------------------
#
#===============================================================================

import os
Import('env')

env = env.Clone()

project_name = 'wsm' 

#------------------------------------------------------------------------------
# WSM SConscript functions
#------------------------------------------------------------------------------
def WSM_LOGD(str):
    print("[WSM_DBG] " + str)

# get SAFE env variable and print it
def local_get_env(env_variable):
    ret_env_variable = os.getenv(env_variable, 'environment variable not available')
    WSM_LOGD(env_variable + ' : ' + ret_env_variable)
    return ret_env_variable

CHIPSET = env['CHIPSET']
TARGET_BUILD_VARIANT = os.environ['TARGET_BUILD_VARIANT']

# WSM custom config. It can be set as 32 or 64 to use for other configuration below.
TA_TARGET_ARCH = "32"
if CHIPSET in ['waipio']:
    TA_TARGET_ARCH = "64"

WSM_LOGD("CHIPSET : " + CHIPSET)

if os.path.exists(env['BUILD_ROOT'] + '/ssg'):
    QSEE_APP_DIR = env['BUILD_ROOT'] + "/ssg"
else:
    QSEE_APP_DIR = env['BUILD_ROOT'] + "/core"

if not hasattr(env, 'IMAGE_ALIASES'):
    WSM_LOGD("Not Image_aliases")
    aliases = []
    aliases = ['wsm',]
    env.Replace(OUT_DIR = QSEE_APP_DIR + "/bsp/trustzone/qsapps/wsm/build")
    env.Replace(LIB_OUT_DIR = QSEE_APP_DIR + "/bsp/trustzone/qsapps/wsm/build/" + "${SHORT_BUILDPATH}")

env.Append(LINKFLAGS=' -no-threads ')

#------------------------------------------------------------------------------
# WSM Defines
#------------------------------------------------------------------------------
if env['PROC'] == 'scorpion':
    env.Append(CCFLAGS = " -mfpu=neon ")

env.Append(CFLAGS = ' -fstack-protector-all -DSWD -DWSM_QSEE -DTA_BUILD -DUSE_SCRYPTO -DENABLE_QSEE_LOGGING -DQSEE ')
env.Append(CCFLAGS = ' -Wno-error -Wno-unused-value -Wno-address-of-packed-member -O0 ')
env.Append(CFLAGS = ' -Dqsee_' + CHIPSET + ' ') # this define is mandatory, inside sources can be found defines like 'qsee_msm8976'

if TARGET_BUILD_VARIANT in ['eng', 'userdebug']:
    WSM_LOGD("MODE : dbg")
    env.Append(CFLAGS = ' -DENABLE_DEBUGGING -D__FILENAME__=__FILE__ -g -DDEBUG ')
else:
    WSM_LOGD("MODE : usr")
    env.Append(CFLAGS = ' -DRELEASE -D__FILENAME__=\"\" ')

#------------------------------------------------------------------------------
# WSM Source PATH
#------------------------------------------------------------------------------
WSM_ROOT_PATH = QSEE_APP_DIR + "/securemsm/trustzone/qsapps/wsm/"

#------------------------------------------------------------------------------
# WSM Version and patch
#------------------------------------------------------------------------------
with open(WSM_ROOT_PATH + "version_ta", 'r') as reader:
    lines = reader.readlines()
CONFIG_BASELINE_CL = lines[1].rstrip()
CONFIG_WSM_VERSION = lines[0].rstrip()

CONFIG_WSM_VERSION_MAJOR, CONFIG_WSM_VERSION_MINOR, CONFIG_WSM_VERSION_PATCH = CONFIG_WSM_VERSION.split('.')

env.Append(CFLAGS = ' -DBASELINE_CL=\\"' + CONFIG_BASELINE_CL + '\\"')
env.Append(CFLAGS = ' -DVERSION_NUMBER=\\"' + CONFIG_WSM_VERSION + '\\"')
env.Append(CFLAGS = ' -DVERSION_NUMBER_MAJOR=' + CONFIG_WSM_VERSION_MAJOR)
env.Append(CFLAGS = ' -DVERSION_NUMBER_MINOR=' + CONFIG_WSM_VERSION_MINOR)
env.Append(CFLAGS = ' -DVERSION_NUMBER_PATCH=' + CONFIG_WSM_VERSION_PATCH)

WSM_LOGD("WSM_CONFIG_VERSION:" + CONFIG_WSM_VERSION_MAJOR + "." + CONFIG_WSM_VERSION_MINOR + "." + CONFIG_WSM_VERSION_PATCH + "." + CONFIG_BASELINE_CL)

#------------------------------------------------------------------------------
# WSM includes
#------------------------------------------------------------------------------
incl_common = [
    "${INC_ROOT}/core/api/services",
    "${INC_ROOT}/core/kernel/smmu/ACv3.0/common/inc",
    QSEE_APP_DIR +"/api/securemsm/trustzone/qsee",
    QSEE_APP_DIR + "/securemsm/accesscontrol/api",
    WSM_ROOT_PATH + "src",
    WSM_ROOT_PATH + "src/common/include",
    WSM_ROOT_PATH + "src/common/log/inc",
    WSM_ROOT_PATH + "src/common/list/inc",
    WSM_ROOT_PATH + "include",
    WSM_ROOT_PATH + "src/common/random",
    WSM_ROOT_PATH + "src/common/malloc_wrapper/inc",
    WSM_ROOT_PATH + "src/common/utilities/inc",
    WSM_ROOT_PATH + "src/crypto/src_v2/inc",
    WSM_ROOT_PATH + "src/crypto/src/crypto_impl", 
    WSM_ROOT_PATH + "src/crypto/src/ta_cmd",
    WSM_ROOT_PATH + "src/crypto/src/openssl_impl",  
    WSM_ROOT_PATH + "src/common/performance/inc", 
    WSM_ROOT_PATH + "src/authentication/inc/private", 
    WSM_ROOT_PATH + "src/daemon/inc", 
    WSM_ROOT_PATH + "src/common/version", 
    WSM_ROOT_PATH + "src/key_manager/inc/ta_cmd", 
    WSM_ROOT_PATH + "src/key_manager/inc/private", 
    WSM_ROOT_PATH + "src/key_manager/inc", 
    WSM_ROOT_PATH + "src/common/pbkdf/ta_cmd", 
    WSM_ROOT_PATH + "src/common/pbkdf/inc", 
    WSM_ROOT_PATH + "src/authentication/inc", 
    WSM_ROOT_PATH + "src/common/crc32", 
    WSM_ROOT_PATH + "src/key_storage/inc", 
    WSM_ROOT_PATH + "src/crypto/inc", 
    WSM_ROOT_PATH + "src/crypto/inc/private", 
    WSM_ROOT_PATH + "swd/common/libc_functions/inc",
    WSM_ROOT_PATH + "swd/common",
    local_get_env('TZ_SCRYPTO_HEADER_PATH'),
    local_get_env('TZ_PROCA_HEADER_PATH'),
]

#----------------------------------------------------------------------------
# App core Objects
#----------------------------------------------------------------------------
sour_common = [
    WSM_ROOT_PATH + "swd/qsee/qseeAgentMain.c",
    WSM_ROOT_PATH + "swd/common/libc_functions/src/libc_functions.c",
    WSM_ROOT_PATH + "swd/common/libc_functions/src/memmgrs.c",
    WSM_ROOT_PATH + "swd/common/custom_so.c",
    WSM_ROOT_PATH + "swd/common/deleg_wrap_unwrap.c",
    WSM_ROOT_PATH + "swd/common/tl_handler.c",
    WSM_ROOT_PATH + "swd/common/tz_proca_handler.c",

    WSM_ROOT_PATH + "src/common/crc32/crc32.c",
    WSM_ROOT_PATH + "src/common/list/src/wsm_list.c",
    WSM_ROOT_PATH + "src/common/list/src/wsm_protected_list.c",
    WSM_ROOT_PATH + "src/common/log/src/wsm_log.c",
    WSM_ROOT_PATH + "src/common/malloc_wrapper/src/malloc_wrapper.c",
    WSM_ROOT_PATH + "src/common/pbkdf/src/pbkdf_hmac_sha256.c",
    WSM_ROOT_PATH + "src/common/random/wsm_rand.c",
    WSM_ROOT_PATH + "src/common/utilities/src/memory_utilities.c",
    WSM_ROOT_PATH + "src/common/utilities/src/string_utilities.c",
    WSM_ROOT_PATH + "src/common/utilities/src/utilities.c",
    WSM_ROOT_PATH + "src/common/version/version_info.c",

    WSM_ROOT_PATH + "src/authentication/src/esap_v1/esap_v1.c",
    WSM_ROOT_PATH + "src/authentication/src/esap_v1/ta_esap_v1_cmd.c",
    WSM_ROOT_PATH + "src/authentication/src/esap_v1/wsm_v1_auth_utilities.c",
    WSM_ROOT_PATH + "src/authentication/src/protocol_v2/protocol_v2.c",
    WSM_ROOT_PATH + "src/authentication/src/protocol_v2/ta_protocol_v2_cmd.c",
    WSM_ROOT_PATH + "src/authentication/src/protocol_v2/wsm_v2_auth_utilities.c",
    WSM_ROOT_PATH + "src/authentication/src/auth_utilities.c",

    WSM_ROOT_PATH + "src/crypto/src/crypto_impl/wsm_crypto_common.c",
    WSM_ROOT_PATH + "src/crypto/src/crypto_impl/wsm_v1_crypto.c",
    WSM_ROOT_PATH + "src/crypto/src/crypto_impl/wsm_v2_crypto.c",
    WSM_ROOT_PATH + "src/crypto/src/crypto_impl/wsm_v3_crypto.c",
    WSM_ROOT_PATH + "src/crypto/src/openssl_impl/openssl_aes_core.c",
    WSM_ROOT_PATH + "src/crypto/src/openssl_impl/wsm_openssl_util.c",
    WSM_ROOT_PATH + "src/crypto/src/ta_cmd/cm_ta_cmd.c",
    WSM_ROOT_PATH + "src/crypto/src_v2/src/psk.c",
    WSM_ROOT_PATH + "src/crypto/src_v2/src/wsm_v1.c",
    WSM_ROOT_PATH + "src/crypto/src_v2/src/wsm_v2.c",

    WSM_ROOT_PATH + "src/key_manager/src/ta_cmd/km_ta_cmd.c",
    WSM_ROOT_PATH + "src/key_manager/src/appskey_type_aes.c",
    WSM_ROOT_PATH + "src/key_manager/src/km_impl.c",
    WSM_ROOT_PATH + "src/key_storage/src/key_storage.c",
    WSM_ROOT_PATH + "src/key_storage/src/key_storage_impl.c",
    WSM_ROOT_PATH + "src/key_storage/src/key_storage_wrapper.c",
    WSM_ROOT_PATH + "src/key_storage/src/key_storage_eeal.c",
    WSM_ROOT_PATH + "src/key_storage/src/key_storage_stub_eeal.c",
]

#------------------------------------------------------------------------------
# Library
#------------------------------------------------------------------------------
privileges = ['default',
              'System',
              'I2C',
              'OEMUnwrapKeys',
              'CertValidate',
              'SPI',
              'TLMM',
              'SecureDisplay',
              'IntMask',
              'OEMBuf',
             ]

arm_libs = [
    File(env.SubstRealPath('${LLVMLIB}/libclang_rt.builtins-arm.a'))
]
if env["PROC"] == "scorpion":
    arm_libs.append(File(env.SubstRealPath('${MUSL32PATH}/lib/libc.a')))
else:
    arm_libs.append(File(env.SubstRealPath('${MUSLPATH}/lib/libc.a')))

# Scrypto / PROCA
SCRYPTO_VERSION      = local_get_env('TZ_SCRYPTO_VERSION')
SCRYPTO_LIB_NAME     = local_get_env('TZ_SCRYPTO_LIB'+TA_TARGET_ARCH)
SCRYPTO_IMPRINT      = local_get_env('TZ_SCRYPTO_TOOLS_IMPRINT')
PROCA_ENABLE         = local_get_env('PROCA_ENABLE')
TARGET_SOC           = local_get_env('TARGET_SOC')
SUPPORT_NEW_TA_BUILD = local_get_env('SUPPORT_NEW_TA_BUILD') # declared inside see_single_ta_sign.sh

#Scrypto
arm_libs.append(File(env.SubstRealPath(SCRYPTO_LIB_NAME)))
env.Append(CPPDEFINES=[('CRYPTO_VERSION', '\\"${SCRYPTO_VERSION}\\"')])

#PROCA
if PROCA_ENABLE == 'TRUE':
    WSM_LOGD("PROCA : PROCA library included to WSM TA build")
    env.Append(CFLAGS = ' -DPROCA_FEATURE_ENABLED ')
    PROCA_LIB = local_get_env('TZ_PROCA_LIB'+TA_TARGET_ARCH)
    arm_libs.append(env.File(PROCA_LIB.split()))
    privileges.append('ProcessAuthenticator')

#USE_ALT_ROT_NAME
if SUPPORT_NEW_TA_BUILD == "true":
    WSM_LOGD("USE_ALT_ROT_NAME used")
    env.Append(CFLAGS = ' -DUSE_ALT_ROT_NAME ')

target_name = project_name
app_name = project_name

#------------------------------------------------------------------------------
# Add command to Imprint HMAC
#------------------------------------------------------------------------------
WSM_ELF_PATH = env.subst('${OUT_DIR}/' + '${SHORT_BUILDPATH}/' + project_name + ".elf")
if CHIPSET in ['bitra', 'sm7250', 'saipan']:
    WSM_ELF_PATH = env.subst('${OUT_DIR}/' + '${SHORT_BUILDPATH}/scorpion/' + project_name + ".elf")
if CHIPSET in ['sm6115', 'divar', 'lahaina', 'kodiak', 'waipio']:
    WSM_ELF_PATH = env.subst('${OUT_DIR}/' + project_name + ".elf")

WSM_LOGD("WSM_ELF_PATH : " + WSM_ELF_PATH)

WSM_RUN_FIPS_TOOLS_COMMAND = SCRYPTO_IMPRINT + " " + WSM_ELF_PATH

env.Append(LINKCOM = " && ")
env.Append(LINKCOM = WSM_RUN_FIPS_TOOLS_COMMAND)
env.Replace(WSM_RUN_FIPS_TOOLS_COMMAND = SCRYPTO_IMPRINT + " " + WSM_ELF_PATH)

#-------------------------------------------------------------------------------
# Add metadata to image
#-------------------------------------------------------------------------------
md = {
    'appName': app_name,
    'privileges': privileges,
}

if not CHIPSET in ['sdm855', 'sm8250', 'lahaina']:
    if env['PROC'] == 'scorpion':
        md['memoryType'] = 'Unprotected'

try:
    wsm_units = env.SecureAppBuilder(
        sources = [ sour_common ],
        includes = incl_common,
        metadata = md,
        image = target_name,
        user_libs = arm_libs,
        heap_size = '0x10000',
    )
except:
    md['heapSize'] = 0x13000
    wsm_units = env.SecureAppBuilder(
        sources = [ sour_common ],
        includes = incl_common,
        metadata = md,
        image = target_name,
        user_libs = arm_libs,
    )

if hasattr(env, 'IMAGE_ALIASES'):
    for image in env['IMAGE_ALIASES']:
        env.Alias(image, wsm_units)
else:
    env.Alias(aliases, wsm_units)
