Merge "n1sdp: remote chip SPI numbering for multichip GIC routing" into integration
diff --git a/Makefile b/Makefile
index 61593c1..af829f2 100644
--- a/Makefile
+++ b/Makefile
@@ -1209,7 +1209,7 @@
 
 .PHONY: ${CRTTOOL}
 ${CRTTOOL}:
-	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${CRTTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} USE_TBBR_DEFS=${USE_TBBR_DEFS} COT=${COT} OPENSSL_DIR=${OPENSSL_DIR} CRTTOOL=${CRTTOOL} --no-print-directory -C ${CRTTOOLPATH}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -1252,12 +1252,12 @@
 
 .PHONY: ${FIPTOOL}
 ${FIPTOOL}:
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${FIPTOOLPATH}
+	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" FIPTOOL=${FIPTOOL} --no-print-directory -C ${FIPTOOLPATH}
 
 sptool: ${SPTOOL}
 .PHONY: ${SPTOOL}
 ${SPTOOL}:
-	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${SPTOOLPATH}
+	${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" SPTOOL=${SPTOOL} --no-print-directory -C ${SPTOOLPATH}
 
 .PHONY: libraries
 romlib.bin: libraries
@@ -1275,7 +1275,7 @@
 
 .PHONY: ${ENCTOOL}
 ${ENCTOOL}:
-	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} --no-print-directory -C ${ENCTOOLPATH}
+	${Q}${MAKE} PLAT=${PLAT} BUILD_INFO=0 OPENSSL_DIR=${OPENSSL_DIR} ENCTOOL=${ENCTOOL} --no-print-directory -C ${ENCTOOLPATH}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 808c7f8..da663be 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -78,6 +78,10 @@
 	mov	x1, #CPU_PWR_DWN_OPS
 	add	x1, x1, x2, lsl #3
 	ldr	x1, [x0, x1]
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif
 	br	x1
 endfunc prepare_cpu_pwr_dwn
 
@@ -171,6 +175,10 @@
 
 	/* Subtract the increment and offset to get the cpu-ops pointer */
 	sub	x0, x4, #(CPU_OPS_SIZE + CPU_MIDR)
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 error_exit:
 	ret
 endfunc get_cpu_ops_ptr
@@ -276,7 +284,15 @@
 	 * turn.
 	 */
 	mrs	x0, tpidr_el3
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x1, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x1, #CPU_ERRATA_FUNC]
 	cbz	x0, .Lnoprint
 
@@ -326,6 +342,10 @@
 	ASM_ASSERT(ne)
 #endif
 	ldr	x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x0, #CPU_EXTRA1_FUNC]
 	/*
 	 * If the reserved function pointer is NULL, this CPU
@@ -359,6 +379,10 @@
 	ASM_ASSERT(ne)
 #endif
 	ldr	x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
 	ldr	x0, [x0, #CPU_EXTRA2_FUNC]
 	ret
 endfunc wa_cve_2018_3639_get_disable_ptr
diff --git a/lib/libc/snprintf.c b/lib/libc/snprintf.c
index 38ad1c7..2686327 100644
--- a/lib/libc/snprintf.c
+++ b/lib/libc/snprintf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,27 +24,55 @@
 	}
 }
 
-static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
-			       unsigned int unum)
+static void unsigned_num_print(char **s, size_t n, size_t *chars_printed,
+			      unsigned long long int unum,
+			      unsigned int radix, char padc, int padn,
+			      bool capitalise)
 {
-	/* Enough for a 32-bit unsigned decimal integer (4294967295). */
-	char num_buf[10];
+	/* Just need enough space to store 64 bit decimal integer */
+	char num_buf[20];
 	int i = 0;
+	int width;
 	unsigned int rem;
+	char ascii_a = capitalise ? 'A' : 'a';
 
 	do {
-		rem = unum % 10U;
-		num_buf[i++] = '0' + rem;
-		unum /= 10U;
+		rem = unum % radix;
+		if (rem < 10U) {
+			num_buf[i] = '0' + rem;
+		} else {
+			num_buf[i] = ascii_a + (rem - 10U);
+		}
+		i++;
+		unum /= radix;
 	} while (unum > 0U);
 
-	while (--i >= 0) {
-		if (*chars_printed < n) {
-			*(*s) = num_buf[i];
-			(*s)++;
+	width = i;
+	if (padn > width) {
+		(*chars_printed) += (size_t)padn;
+	} else {
+		(*chars_printed) += (size_t)width;
+	}
+
+	if (*chars_printed < n) {
+
+		if (padn > 0) {
+			while (width < padn) {
+				*(*s)++ = padc;
+				padn--;
+			}
 		}
 
-		(*chars_printed)++;
+		while (--i >= 0) {
+			*(*s)++ = num_buf[i];
+		}
+
+		if (padn < 0) {
+			while (width < -padn) {
+				*(*s)++ = padc;
+				padn++;
+			}
+		}
 	}
 }
 
@@ -52,9 +80,16 @@
  * Reduced snprintf to be used for Trusted firmware.
  * The following type specifiers are supported:
  *
+ * %x (or %X) - hexadecimal format
  * %d or %i - signed decimal format
  * %s - string format
  * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number or string with spaces (NN is a decimal number)
+ * %-NN - Right-pad the number or string with spaces (NN is a decimal number)
  *
  * The function panics on all other formats specifiers.
  *
@@ -66,8 +101,12 @@
 {
 	va_list args;
 	int num;
-	unsigned int unum;
+	unsigned long long int unum;
 	char *str;
+	char padc;		/* Padding character */
+	int padn;		/* Number of characters to pad */
+	bool left;
+	bool capitalise;
 	size_t chars_printed = 0U;
 
 	if (n == 0U) {
@@ -83,11 +122,39 @@
 
 	va_start(args, fmt);
 	while (*fmt != '\0') {
+		left = false;
+		padc ='\0';
+		padn = 0;
+		capitalise = false;
 
 		if (*fmt == '%') {
 			fmt++;
 			/* Check the format specifier. */
+loop:
 			switch (*fmt) {
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				padc = (*fmt == '0') ? '0' : ' ';
+				for (padn = 0; *fmt >= '0' && *fmt <= '9'; fmt++) {
+					padn = (padn * 10) + (*fmt - '0');
+				}
+				if (left) {
+					padn = -padn;
+				}
+				goto loop;
+			case '-':
+				left = true;
+				fmt++;
+				goto loop;
+
 			case 'i':
 			case 'd':
 				num = va_arg(args, int);
@@ -104,7 +171,8 @@
 					unum = (unsigned int)num;
 				}
 
-				unsigned_dec_print(&s, n, &chars_printed, unum);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
 				break;
 			case 's':
 				str = va_arg(args, char *);
@@ -112,8 +180,27 @@
 				break;
 			case 'u':
 				unum = va_arg(args, unsigned int);
-				unsigned_dec_print(&s, n, &chars_printed, unum);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
 				break;
+			case 'p':
+				unum = (uintptr_t)va_arg(args, void *);
+				if (unum > 0U) {
+					string_print(&s, n, &chars_printed, "0x");
+					padn -= 2;
+				}
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn, false);
+				break;
+			case 'X':
+				capitalise = true;
+			case 'x':
+				unum = va_arg(args, unsigned int);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn,
+						   capitalise);
+				break;
+
 			default:
 				/* Panic on any other format specifier. */
 				ERROR("snprintf: specifier with ASCII code '%d' not supported.",
diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c
index e65980b..8f4018c 100644
--- a/plat/common/plat_spmd_manifest.c
+++ b/plat/common/plat_spmd_manifest.c
@@ -9,6 +9,7 @@
 #include <string.h>
 #include <libfdt.h>
 
+#include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/fdt_wrappers.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 5f01416..bd2bebb 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -167,23 +167,6 @@
 endfunc plat_get_my_entrypoint
 
 	/* -----------------------------------------------------
-	 * int platform_get_core_pos(int mpidr);
-	 *
-	 * result: CorePos = (ClusterId * cpus per cluster) +
-	 *                   CoreId
-	 * -----------------------------------------------------
-	 */
-func platform_get_core_pos
-	and	x1, x0, #MPIDR_CPU_MASK
-	and	x0, x0, #MPIDR_CLUSTER_MASK
-	lsr	x0, x0, #MPIDR_AFFINITY_BITS
-	mov	x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
-	mul	x0, x0, x2
-	add	x0, x1, x0
-	ret
-endfunc platform_get_core_pos
-
-	/* -----------------------------------------------------
 	 * void plat_secondary_cold_boot_setup (void);
 	 *
 	 * This function performs any platform specific actions
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index e56909d..d5297ee 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -28,6 +28,7 @@
 
 #include <memctrl.h>
 #include <profiler.h>
+#include <smmu.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -180,21 +181,6 @@
 	plat_early_platform_setup();
 
 	/*
-	 * Do initial security configuration to allow DRAM/device access.
-	 */
-	tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
-			(uint32_t)plat_bl31_params_from_bl2.tzdram_size);
-
-#if RELOCATE_BL32_IMAGE
-	/*
-	 * The previous bootloader might not have placed the BL32 image
-	 * inside the TZDRAM. Platform handler to allow relocation of BL32
-	 * image to TZDRAM memory. This behavior might change per platform.
-	 */
-	plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
-#endif
-
-	/*
 	 * Add timestamp for platform early setup exit.
 	 */
 	boot_profiler_add_record("[TF] early setup exit");
@@ -287,6 +273,13 @@
 	 */
 	tegra_memctrl_disable_ahb_redirection();
 
+#if defined(TEGRA_SMMU0_BASE)
+	/*
+	 * Verify the integrity of the previously configured SMMU(s) settings
+	 */
+	tegra_smmu_verify();
+#endif
+
 	/*
 	 * Add final timestamp before exiting BL31.
 	 */
diff --git a/plat/nvidia/tegra/drivers/smmu/smmu.c b/plat/nvidia/tegra/drivers/smmu/smmu.c
index a4a4354..4189b00 100644
--- a/plat/nvidia/tegra/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/drivers/smmu/smmu.c
@@ -14,6 +14,7 @@
 #include <common/debug.h>
 
 #include <smmu.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
@@ -21,15 +22,17 @@
 #define SMMU_NUM_CONTEXTS		64U
 #define SMMU_CONTEXT_BANK_MAX_IDX	64U
 
+#define MISMATCH_DETECTED		0x55AA55AAU
+
 /*
  * Init SMMU during boot or "System Suspend" exit
  */
 void tegra_smmu_init(void)
 {
 	uint32_t val, cb_idx, smmu_id, ctx_base;
-	uint32_t smmu_counter = plat_get_num_smmu_devices();
+	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
 
-	for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) {
+	for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
 		/* Program the SMMU pagesize and reset CACHE_LOCK bit */
 		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
 		val |= SMMU_GSR0_PGSIZE_64K;
@@ -44,7 +47,7 @@
 		/* disable TCU prefetch for all contexts */
 		ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS)
 				+ SMMU_CBn_ACTLR;
-		for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+		for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
 			val = tegra_smmu_read_32(smmu_id,
 				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
 			val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
@@ -63,3 +66,56 @@
 		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
 	}
 }
+
+/*
+ * Verify SMMU settings have not been altered during boot
+ */
+void tegra_smmu_verify(void)
+{
+	uint32_t cb_idx, ctx_base, smmu_id, val;
+	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
+	uint32_t mismatch = 0U;
+
+	for (smmu_id = 0U; smmu_id < num_smmu_devices; smmu_id++) {
+		/* check PGSIZE_64K bit inr S Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
+		if (0U == (val & SMMU_GSR0_PGSIZE_64K)) {
+			ERROR("%s: PGSIZE_64K Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* check CACHE LOCK bit in S Aux. Config. Register */
+		if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+			ERROR("%s: CACHE_LOCK Mismatch - smmu_id=%d, GSR0_SECURE_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* check CACHE LOCK bit in NS Aux. Config. Register */
+		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
+		if (0U == (val & SMMU_ACR_CACHE_LOCK_ENABLE_BIT)) {
+			ERROR("%s: Mismatch - smmu_id=%d, GNSR_ACR=%x\n",
+				__func__, smmu_id, val);
+			mismatch = MISMATCH_DETECTED;
+		}
+
+		/* verify TCU prefetch for all contexts is disabled */
+		ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) +
+			SMMU_CBn_ACTLR;
+		for (cb_idx = 0U; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
+			val = tegra_smmu_read_32(smmu_id,
+				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
+			if (0U != (val & SMMU_CBn_ACTLR_CPRE_BIT)) {
+				ERROR("%s: Mismatch - smmu_id=%d, cb_idx=%d, GSR0_PGSIZE_64K=%x\n",
+					__func__, smmu_id, cb_idx, val);
+				mismatch = MISMATCH_DETECTED;
+			}
+		}
+	}
+
+	/* Treat configuration mismatch as fatal */
+	if ((mismatch == MISMATCH_DETECTED) && tegra_platform_is_silicon()) {
+		panic();
+	}
+}
diff --git a/plat/nvidia/tegra/drivers/spe/shared_console.S b/plat/nvidia/tegra/drivers/spe/shared_console.S
index 6df73ec..9196c1c 100644
--- a/plat/nvidia/tegra/drivers/spe/shared_console.S
+++ b/plat/nvidia/tegra/drivers/spe/shared_console.S
@@ -11,8 +11,7 @@
 #define CONSOLE_FLUSH_DATA_TO_PORT	(1 << 26)
 #define CONSOLE_RING_DOORBELL		(1 << 31)
 #define CONSOLE_IS_BUSY			(1 << 31)
-#define CONSOLE_TIMEOUT			0xC000		/* approx. 50 ms */
-#define CONSOLE_WRITE			(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+#define CONSOLE_TIMEOUT			0xC000		/* 50 ms */
 
 	/*
 	 * This file contains a driver implementation to make use of the
@@ -101,7 +100,7 @@
 	/* spe is ready */
 	mov	w2, #0xD		/* '\r' */
 	and	w2, w2, #0xFF
-	mov	w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+	mov	w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
 	orr	w2, w2, w3
 	str	w2, [x1]
 
@@ -111,7 +110,7 @@
 	/* spe is ready */
 	mov	w2, w0
 	and	w2, w2, #0xFF
-	mov	w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+	mov	w3, #(CONSOLE_RING_DOORBELL | (1 << CONSOLE_NUM_BYTES_SHIFT))
 	orr	w2, w2, w3
 	str	w2, [x1]
 
@@ -164,7 +163,7 @@
 	cbz	x0, flush_error
 
 	/* flush console */
-	mov	w1, #CONSOLE_WRITE
+	mov	w1, #(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
 	str	w1, [x0]
 	mov	w0, #0
 	ret
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 509fe32..e15762b 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -144,6 +144,7 @@
 	mmio_write_32(TEGRA_MC_BASE + off, val);
 }
 
+#if defined(TEGRA_MC_STREAMID_BASE)
 static inline uint32_t tegra_mc_streamid_read_32(uint32_t off)
 {
 	return mmio_read_32(TEGRA_MC_STREAMID_BASE + off);
@@ -153,6 +154,7 @@
 {
 	mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val);
 }
+#endif
 
 #define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
 	((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 601864f..1de9af6 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -86,6 +86,7 @@
 }
 
 void tegra_smmu_init(void);
+void tegra_smmu_verify(void);
 uint32_t plat_get_num_smmu_devices(void);
 
 #endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/plat_macros.S b/plat/nvidia/tegra/include/plat_macros.S
index 4f01e33..2dc3b41 100644
--- a/plat/nvidia/tegra/include/plat_macros.S
+++ b/plat/nvidia/tegra/include/plat_macros.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,6 +28,7 @@
  * ---------------------------------------------
  */
 .macro plat_crash_print_regs
+#ifdef TEGRA_GICC_BASE
 	mov_imm	x16, TEGRA_GICC_BASE
 
 	/* gicc base address is now in x16 */
@@ -37,7 +39,7 @@
 	ldr	w10, [x16, #GICC_CTLR]
 	/* Store to the crash buf and print to cosole */
 	bl	str_in_crash_buf_print
-
+#endif
 	/* Print the GICD_ISPENDR regs */
 	mov_imm	x16, TEGRA_GICD_BASE
 	add	x7, x16, #GICD_ISPENDR
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index a4724e6..abe94e4 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -55,27 +55,30 @@
 # Enable SDEI
 SDEI_SUPPORT			:= 1
 
+# modify BUILD_PLAT to point to SoC specific build directory
+BUILD_PLAT	:=	${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
 $(eval $(call add_define,ENABLE_TEGRA_WDT_LEGACY_FIQ_HANDLING))
 $(eval $(call add_define,RELOCATE_BL32_IMAGE))
 
-# modify BUILD_PLAT to point to SoC specific build directory
-BUILD_PLAT	:=	$(abspath ${BUILD_BASE})/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
-
 # platform cflags (enable signed comparisons, disable stdlib)
-TF_CFLAGS	+= -Wsign-compare -nostdlib
+TF_CFLAGS	+= -nostdlib
 
 # override with necessary libc files for the Tegra platform
 override LIBC_SRCS :=	$(addprefix lib/libc/,		\
 			aarch64/setjmp.S		\
 			assert.c			\
+			memchr.c			\
+			memcmp.c			\
 			memcpy.c			\
 			memmove.c			\
 			memset.c			\
 			printf.c			\
 			putchar.c			\
+			strrchr.c			\
 			strlen.c			\
 			snprintf.c)
 
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index 43acdd6..9f9abac 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -6,9 +6,11 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <common/bl_common.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
+#include <memctrl.h>
 #include <plat/common/platform.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
@@ -144,7 +146,16 @@
  ******************************************************************************/
 void plat_early_platform_setup(void)
 {
-	; /* do nothing */
+	plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+	/* Verify chip id is t132 */
+	assert(tegra_chipid_is_t132());
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index c216b5d..ab374a4 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -26,6 +26,7 @@
 #include <plat/common/platform.h>
 
 #include <mce.h>
+#include <memctrl.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -185,10 +186,20 @@
 {
 	uint64_t impl, val;
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+	const struct tegra_bl31_params *arg_from_bl2 = plat_get_bl31_params();
+
+	/* Verify chip id is t186 */
+	assert(tegra_chipid_is_t186());
 
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
+
 	impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
 
 	/*
@@ -202,6 +213,13 @@
 		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
 		write_l2ctlr_el1(val);
 	}
+
+	/*
+	 * The previous bootloader might not have placed the BL32 image
+	 * inside the TZDRAM. Platform handler to allow relocation of BL32
+	 * image to TZDRAM memory. This behavior might change per platform.
+	 */
+	plat_relocate_bl32_image(arg_from_bl2->bl32_image_info);
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 399aebb..c0f2fb0 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -205,6 +205,9 @@
 	uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step;
 	uint64_t actlr_elx;
 
+	/* Verify chip id is t194 */
+	assert(tegra_chipid_is_t194());
+
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
@@ -283,8 +286,6 @@
 	INTR_PROP_DESC(TEGRA_SDEI_SGI_PRIVATE, PLAT_SDEI_CRITICAL_PRI,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
 	INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
-			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
-	INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, PLAT_TEGRA_WDT_PRIO,
 			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
 };
 
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index 7573ed2..9705a7f 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -70,3 +70,13 @@
 				lib/extensions/ras/ras_common.c			\
 				${SOC_DIR}/plat_ras.c
 endif
+
+# SPM dispatcher
+ifeq (${SPD},spmd)
+# include device tree helper library
+include lib/libfdt/libfdt.mk
+# sources to support spmd
+BL31_SOURCES		+=	plat/common/plat_spmd_manifest.c	\
+				common/fdt_wrappers.c			\
+				${LIBFDT_SRCS}
+endif
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index f2b267b..20dde3b 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -165,6 +165,15 @@
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 	uint64_t val;
 
+	/* Verify chip id is t210 */
+	assert(tegra_chipid_is_t210());
+
+	/*
+	 * Do initial security configuration to allow DRAM/device access.
+	 */
+	tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
+			(uint32_t)plat_params->tzdram_size);
+
 	/* platform parameter passed by the previous bootloader */
 	if (plat_params->l2_ecc_parity_prot_dis != 1) {
 		/* Enable ECC Parity Protection for Cortex-A57 CPUs */
diff --git a/plat/qti/common/inc/qti_plat.h b/plat/qti/common/inc/qti_plat.h
index 0e867be..4d9d320 100644
--- a/plat/qti/common/inc/qti_plat.h
+++ b/plat/qti/common/inc/qti_plat.h
@@ -50,4 +50,7 @@
 
 void gic_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr);
 
+void qti_pmic_prepare_reset(void);
+void qti_pmic_prepare_shutdown(void);
+
 #endif /* QTI_PLAT_H */
diff --git a/plat/qti/common/inc/spmi_arb.h b/plat/qti/common/inc/spmi_arb.h
new file mode 100644
index 0000000..362f740
--- /dev/null
+++ b/plat/qti/common/inc/spmi_arb.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPMI_ARB_H
+#define SPMI_ARB_H
+
+#include <stdint.h>
+
+/*******************************************************************************
+ * WARNING: This driver does not arbitrate access with the kernel. These APIs
+ * must only be called when the kernel is known to be quiesced (such as before
+ * boot or while the system is shutting down).
+ ******************************************************************************/
+
+/* 32-bit addresses combine (U)SID, PID and register address. */
+
+int spmi_arb_read8(uint32_t addr);
+int spmi_arb_write8(uint32_t addr, uint8_t data);
+
+#endif /* SPMI_ARB_H */
diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c
new file mode 100644
index 0000000..b189a8b
--- /dev/null
+++ b/plat/qti/common/src/pm8998.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+
+#include <qti_plat.h>
+#include <spmi_arb.h>
+
+/*
+ * This driver implements PON support for PM8998-compatible PMICs. This can
+ * include other part numbers like PM6150.
+ */
+
+#define PON_PS_HOLD_RESET_CTL		0x85a
+#define RESET_TYPE_WARM_RESET		1
+#define RESET_TYPE_SHUTDOWN		4
+
+#define PON_PS_HOLD_RESET_CTL2		0x85b
+#define S2_RESET_EN			BIT(7)
+
+static void configure_ps_hold(uint32_t reset_type)
+{
+	/* QTI recommends disabling reset for 10 cycles before reconfiguring. */
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0);
+	mdelay(1);
+
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type);
+	spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN);
+	mdelay(1);
+}
+
+void qti_pmic_prepare_reset(void)
+{
+	configure_ps_hold(RESET_TYPE_WARM_RESET);
+}
+
+void qti_pmic_prepare_shutdown(void)
+{
+	configure_ps_hold(RESET_TYPE_SHUTDOWN);
+}
diff --git a/plat/qti/common/src/qti_pm.c b/plat/qti/common/src/qti_pm.c
index 4a5877c..5f1b7aa 100644
--- a/plat/qti/common/src/qti_pm.c
+++ b/plat/qti/common/src/qti_pm.c
@@ -9,6 +9,8 @@
 #include <arch_helpers.h>
 #include <bl31/bl31.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
 #include <lib/psci/psci.h>
 
 #include <platform.h>
@@ -204,14 +206,25 @@
 	/* We should never reach here */
 }
 
+static __dead2 void assert_ps_hold(void)
+{
+	mmio_write_32(QTI_PS_HOLD_REG, 0);
+	mdelay(1000);
+
+	/* Should be dead before reaching this. */
+	panic();
+}
+
 __dead2 void qti_system_off(void)
 {
-	qtiseclib_psci_system_off();
+	qti_pmic_prepare_shutdown();
+	assert_ps_hold();
 }
 
 __dead2 void qti_system_reset(void)
 {
-	qtiseclib_psci_system_reset();
+	qti_pmic_prepare_reset();
+	assert_ps_hold();
 }
 
 void qti_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/qti/common/src/spmi_arb.c b/plat/qti/common/src/spmi_arb.c
new file mode 100644
index 0000000..81cc577
--- /dev/null
+++ b/plat/qti/common/src/spmi_arb.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2020, Google LLC. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <spmi_arb.h>
+
+#define REG_APID_MAP(apid)	(0x0C440900 + 4 * i)
+#define NUM_APID		0x80
+
+#define PPID_MASK		(0xfff << 8)
+
+#define REG_ARB_CMD(apid)	(0x0C600000 + 0x10000 * apid)
+/* These are opcodes specific to this SPMI arbitrator, *not* SPMI commands. */
+#define OPC_EXT_WRITEL		0
+#define OPC_EXT_READL		1
+
+#define REG_ARB_STATUS(apid)	(0x0C600008 + 0x10000 * apid)
+#define ARB_STATUS_DONE		BIT(0)
+#define ARB_STATUS_FAILURE	BIT(1)
+#define ARB_STATUS_DENIED	BIT(2)
+#define ARB_STATUS_DROPPED	BIT(3)
+
+/* Fake status to report driver errors. */
+#define ARB_FAKE_STATUS_TIMEOUT	BIT(8)
+
+#define REG_ARB_RDATA0(apid)	(0x0C600018 + 0x10000 * apid)
+#define REG_ARB_WDATA0(apid)	(0x0C600010 + 0x10000 * apid)
+
+static int addr_to_apid(uint32_t addr)
+{
+	unsigned int i;
+
+	for (i = 0U; i < NUM_APID; i++) {
+		uint32_t reg = mmio_read_32(REG_APID_MAP(i));
+		if ((reg != 0U) && ((addr & PPID_MASK) == (reg & PPID_MASK))) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+static int wait_for_done(uint16_t apid)
+{
+	unsigned int timeout = 100;
+
+	while (timeout-- != 0U) {
+		uint32_t status = mmio_read_32(REG_ARB_STATUS(apid));
+		if ((status & ARB_STATUS_DONE) != 0U) {
+			if ((status & ARB_STATUS_FAILURE) != 0U ||
+			    (status & ARB_STATUS_DENIED) != 0U ||
+			    (status & ARB_STATUS_DROPPED) != 0U) {
+				return status & 0xff;
+			}
+			return 0;
+		}
+		mdelay(1);
+	}
+	ERROR("SPMI_ARB timeout!\n");
+	return ARB_FAKE_STATUS_TIMEOUT;
+}
+
+static void arb_command(uint16_t apid, uint8_t opcode, uint32_t addr,
+			uint8_t bytes)
+{
+	mmio_write_32(REG_ARB_CMD(apid), (uint32_t)opcode << 27 |
+					 (addr & 0xff) << 4 | (bytes - 1));
+}
+
+int spmi_arb_read8(uint32_t addr)
+{
+	int apid = addr_to_apid(addr);
+
+	if (apid < 0) {
+		return apid;
+	}
+
+	arb_command(apid, OPC_EXT_READL, addr, 1);
+
+	int ret = wait_for_done(apid);
+	if (ret != 0) {
+		ERROR("SPMI_ARB read error [0x%x]: 0x%x\n", addr, ret);
+		return ret;
+	}
+
+	return mmio_read_32(REG_ARB_RDATA0(apid)) & 0xff;
+}
+
+int spmi_arb_write8(uint32_t addr, uint8_t data)
+{
+	int apid = addr_to_apid(addr);
+
+	if (apid < 0) {
+		return apid;
+	}
+
+	mmio_write_32(REG_ARB_WDATA0(apid), data);
+	arb_command(apid, OPC_EXT_WRITEL, addr, 1);
+
+	int ret = wait_for_done(apid);
+	if (ret != 0) {
+		ERROR("SPMI_ARB write error [0x%x] = 0x%x: 0x%x\n",
+		      addr, data, ret);
+	}
+
+	return ret;
+}
diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
index 357bb6a..315bd6b 100644
--- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h
+++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h
@@ -78,10 +78,6 @@
 void qtiseclib_psci_node_power_off(const uint8_t *states);
 void qtiseclib_psci_node_suspend(const uint8_t *states);
 void qtiseclib_psci_node_suspend_finish(const uint8_t *states);
-__attribute__ ((noreturn))
-void qtiseclib_psci_system_off(void);
-__attribute__ ((noreturn))
-void qtiseclib_psci_system_reset(void);
 void qtiseclib_disable_cluster_coherency(uint8_t state);
 
 #endif /* QTISECLIB_INTERFACE_H */
diff --git a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
index 70485fe..9c93d51 100644
--- a/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
+++ b/plat/qti/qtiseclib/src/qtiseclib_interface_stub.c
@@ -108,18 +108,6 @@
 {
 }
 
-void qtiseclib_psci_system_off(void)
-{
-	while (1) {
-	};
-}
-
-void qtiseclib_psci_system_reset(void)
-{
-	while (1) {
-	};
-}
-
 void qtiseclib_disable_cluster_coherency(uint8_t state)
 {
 }
diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h
index d95b365..17e1310 100644
--- a/plat/qti/sc7180/inc/platform_def.h
+++ b/plat/qti/sc7180/inc/platform_def.h
@@ -173,4 +173,10 @@
  */
 #define BL31_LIMIT				(BL31_BASE + BL31_SIZE)
 
+/*----------------------------------------------------------------------------*/
+/* AOSS registers */
+/*----------------------------------------------------------------------------*/
+#define QTI_PS_HOLD_REG				0x0C264000
+/*----------------------------------------------------------------------------*/
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk
index e551355..ec560d0 100644
--- a/plat/qti/sc7180/platform.mk
+++ b/plat/qti/sc7180/platform.mk
@@ -51,6 +51,7 @@
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S	\
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S	\
 				$(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S	\
+				$(QTI_PLAT_PATH)/common/src/pm8998.c			\
 				$(QTI_PLAT_PATH)/common/src/qti_stack_protector.c	\
 				$(QTI_PLAT_PATH)/common/src/qti_common.c		\
 				$(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c		\
@@ -60,6 +61,7 @@
 				$(QTI_PLAT_PATH)/common/src/qti_topology.c		\
 				$(QTI_PLAT_PATH)/common/src/qti_pm.c			\
 				$(QTI_PLAT_PATH)/common/src/qti_rng.c			\
+				$(QTI_PLAT_PATH)/common/src/spmi_arb.c			\
 				$(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c	\
 
 
@@ -79,7 +81,7 @@
 PSCI_SOURCES		:=	plat/common/plat_psci_common.c				\
 
 # GIC-600 configuration
-GICV3_IMPL			:=	GIC600
+GICV3_SUPPORT_GIC600	:=	1
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
 
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 6ed2098..6f0d9b1 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -560,16 +560,22 @@
 	case FFA_RXTX_MAP_SMC32:
 	case FFA_RXTX_MAP_SMC64:
 	case FFA_RXTX_UNMAP:
+	case FFA_PARTITION_INFO_GET:
+		/*
+		 * Should not be allowed to forward FFA_PARTITION_INFO_GET
+		 * from Secure world to Normal world
+		 *
+		 * Fall through to forward the call to the other world
+		 */
 	case FFA_MSG_RUN:
 		/* This interface must be invoked only by the Normal world */
+
 		if (secure_origin) {
 			return spmd_ffa_error_return(handle,
-						      FFA_ERROR_NOT_SUPPORTED);
+						     FFA_ERROR_NOT_SUPPORTED);
 		}
 
 		/* Fall through to forward the call to the other world */
-
-	case FFA_PARTITION_INFO_GET:
 	case FFA_MSG_SEND:
 	case FFA_MSG_SEND_DIRECT_REQ_SMC64:
 	case FFA_MSG_SEND_DIRECT_RESP_SMC64:
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 19f736f..418e06c 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -4,11 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROJECT		:= cert_create
 PLAT		:= none
 V		?= 0
 DEBUG		:= 0
-BINARY		:= ${PROJECT}${BIN_EXT}
+BINARY		:= $(notdir ${CRTTOOL})
 OPENSSL_DIR	:= /usr
 COT		:= tbbr
 
diff --git a/tools/encrypt_fw/Makefile b/tools/encrypt_fw/Makefile
index cb81d0b..ebbc66a 100644
--- a/tools/encrypt_fw/Makefile
+++ b/tools/encrypt_fw/Makefile
@@ -1,14 +1,13 @@
 #
-# Copyright (c) 2019, Linaro Limited. All rights reserved.
+# Copyright (c) 2019-2020, Linaro Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROJECT		:= encrypt_fw
 V		?= 0
 BUILD_INFO	?= 1
 DEBUG		:= 0
-BINARY		:= ${PROJECT}${BIN_EXT}
+BINARY		:= $(notdir ${ENCTOOL})
 OPENSSL_DIR	:= /usr
 
 OBJECTS := src/encrypt.o \
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index ef35014..0ede6ce 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
-PROJECT := fiptool${BIN_EXT}
+PROJECT := $(notdir ${FIPTOOL})
 OBJECTS := fiptool.o tbbr_config.o
 V ?= 0
 
diff --git a/tools/sptool/Makefile b/tools/sptool/Makefile
index 9325207..f724c26 100644
--- a/tools/sptool/Makefile
+++ b/tools/sptool/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
 include ${MAKE_HELPERS_DIRECTORY}build_env.mk
 
-PROJECT := sptool${BIN_EXT}
+PROJECT := $(notdir ${SPTOOL})
 OBJECTS := sptool.o
 V ?= 0