Merge "docs/Makefile: use conditional assignment on sphinx variables"
diff --git a/Makefile b/Makefile
index a614238..b09e749 100644
--- a/Makefile
+++ b/Makefile
@@ -526,34 +526,35 @@
 	${Q}cscope -b -q -k
 
 .PHONY: help
+.SILENT: help
 help:
-	@echo "usage: ${MAKE} PLAT=<${PLATFORMS}> \
+	echo "usage: ${MAKE} PLAT=<${PLATFORMS}> \
 <all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|quark|el3_payload|distclean|clean|checkcodebase|checkpatch|help_tests>"
-	@echo ""
-	@echo "PLAT is used to specify which platform you wish to build."
-	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
-	@echo ""
-	@echo "Supported Targets:"
-	@echo "  all            Build all supported binaries for this platform"
-	@echo "                 (i.e. TFTF and FWU images)"
-	@echo "  tftf           Build the TFTF image"
-	@echo "  ns_bl1u        Build the NS_BL1U image"
-	@echo "  ns_bl2u        Build the NS_BL2U image"
-	@echo "  cactus         Build the Cactus image (Test S-EL0 payload) and resource description."
-	@echo "  cactus_mm      Build the Cactus-MM image (Test S-EL0 payload)."
-	@echo "  ivy            Build the Ivy image (Test S-EL0 payload) and resource description."
-	@echo "  quark          Build the Quark image (Test S-EL0 payload) and resource description."
-	@echo "  el3_payload    Build the EL3 test payload"
-	@echo "  checkcodebase  Check the coding style of the entire source tree"
-	@echo "  checkpatch     Check the coding style on changes in the current"
-	@echo "                 branch against BASE_COMMIT (default origin/master)"
-	@echo "  doc            Build html based documentation using Sphinx tool"
-	@echo "  clean          Clean the build for the selected platform"
-	@echo "  cscope         Generate cscope index"
-	@echo "  distclean      Remove all build artifacts for all platforms"
-	@echo "  help_tests     List all possible sets of tests"
-	@echo ""
-	@echo "note: most build targets require PLAT to be set to a specific platform."
-	@echo ""
-	@echo "example: build all targets for the FVP platform:"
-	@echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
+	echo ""
+	echo "PLAT is used to specify which platform you wish to build."
+	echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
+	echo ""
+	echo "Supported Targets:"
+	echo "  all            Build all supported binaries for this platform"
+	echo "                 (i.e. TFTF and FWU images)"
+	echo "  tftf           Build the TFTF image"
+	echo "  ns_bl1u        Build the NS_BL1U image"
+	echo "  ns_bl2u        Build the NS_BL2U image"
+	echo "  cactus         Build the Cactus image (Test S-EL0 payload) and resource description."
+	echo "  cactus_mm      Build the Cactus-MM image (Test S-EL0 payload)."
+	echo "  ivy            Build the Ivy image (Test S-EL0 payload) and resource description."
+	echo "  quark          Build the Quark image (Test S-EL0 payload) and resource description."
+	echo "  el3_payload    Build the EL3 test payload"
+	echo "  checkcodebase  Check the coding style of the entire source tree"
+	echo "  checkpatch     Check the coding style on changes in the current"
+	echo "                 branch against BASE_COMMIT (default origin/master)"
+	echo "  doc            Build html based documentation using Sphinx tool"
+	echo "  clean          Clean the build for the selected platform"
+	echo "  cscope         Generate cscope index"
+	echo "  distclean      Remove all build artifacts for all platforms"
+	echo "  help_tests     List all possible sets of tests"
+	echo ""
+	echo "note: most build targets require PLAT to be set to a specific platform."
+	echo ""
+	echo "example: build all targets for the FVP platform:"
+	echo "  CROSS_COMPILE=aarch64-none-elf- make PLAT=fvp all"
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 197879e..2cc2c46 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -23,6 +23,7 @@
 typedef unsigned short ffa_vm_id_t;
 typedef unsigned short ffa_vm_count_t;
 typedef unsigned short ffa_vcpu_count_t;
+typedef uint32_t ffa_int_id_t;
 
 #ifndef __ASSEMBLY__
 
diff --git a/spm/cactus/aarch64/cactus_entrypoint.S b/spm/cactus/aarch64/cactus_entrypoint.S
index 4fe17e3..383c319 100644
--- a/spm/cactus/aarch64/cactus_entrypoint.S
+++ b/spm/cactus/aarch64/cactus_entrypoint.S
@@ -35,6 +35,12 @@
 	add	x1, x1, x0
 	bl	fixup_gdt_reloc
 
+	/* Set up exceptions vector table */
+	adrp	x0, tftf_vector
+	add	x0, x0, :lo12:tftf_vector
+	msr	vbar_el1, x0
+	isb
+
 	/* And jump to the C entrypoint. */
 	b	cactus_main
 
diff --git a/spm/cactus/cactus-secondary.dts b/spm/cactus/cactus-secondary.dts
index 71a56f4..661684b 100644
--- a/spm/cactus/cactus-secondary.dts
+++ b/spm/cactus/cactus-secondary.dts
@@ -20,7 +20,7 @@
 	id = <2>;
 	auxiliary-id = <0xae>;
 	stream-endpoint-ids = <0 1 2 3>;
-	execution-ctx-count = <1>;
+	execution-ctx-count = <8>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7100000>;
diff --git a/spm/cactus/cactus-tertiary.dts b/spm/cactus/cactus-tertiary.dts
index d823ef3..ea7d5d6 100644
--- a/spm/cactus/cactus-tertiary.dts
+++ b/spm/cactus/cactus-tertiary.dts
@@ -20,7 +20,7 @@
 	id = <3>;
 	auxiliary-id = <0xae>;
 	stream-endpoint-ids = <0 1 2 3>;
-	execution-ctx-count = <1>;
+	execution-ctx-count = <8>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7200000>;
diff --git a/spm/cactus/cactus.dts b/spm/cactus/cactus.dts
index 919a5d5..e64d3a8 100644
--- a/spm/cactus/cactus.dts
+++ b/spm/cactus/cactus.dts
@@ -20,7 +20,7 @@
 	id = <1>;
 	auxiliary-id = <0xae>;
 	stream-endpoint-ids = <0 1 2 3>;
-	execution-ctx-count = <1>;
+	execution-ctx-count = <8>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7000000>;
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 60f6974..e6577c3 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -18,9 +18,10 @@
 	-Iinclude/lib/${ARCH}				\
 	-Iinclude/lib/utils				\
 	-Iinclude/lib/xlat_tables			\
+	-Iinclude/plat/common				\
 	-Iinclude/runtime_services			\
 	-Ispm/cactus					\
-	-Ispm/common					\
+	-Ispm/common
 
 CACTUS_SOURCES	:=					\
 	$(addprefix spm/cactus/,			\
@@ -38,7 +39,9 @@
 CACTUS_SOURCES	+=					\
 	tftf/framework/debug.c				\
 	tftf/framework/${ARCH}/asm_debug.S		\
-	tftf/tests/runtime_services/secure_service/ffa_helpers.c
+	tftf/tests/runtime_services/secure_service/ffa_helpers.c \
+	tftf/framework/${ARCH}/exceptions.S		\
+	tftf/framework/${ARCH}/exception_report.c
 
 CACTUS_SOURCES	+= 	drivers/arm/pl011/${ARCH}/pl011_console.S	\
 			lib/${ARCH}/cache_helpers.S			\
diff --git a/spm/cactus/cactus_def.h b/spm/cactus/cactus_def.h
index 5a4a5dd..be6f06a 100644
--- a/spm/cactus/cactus_def.h
+++ b/spm/cactus/cactus_def.h
@@ -31,10 +31,10 @@
 /*
  * RX/TX buffer helpers.
  */
-#define get_sp_rx_start(sp_id) (CACTUS_RX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE))
-#define get_sp_rx_end(sp_id) (CACTUS_RX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
-#define get_sp_tx_start(sp_id) (CACTUS_TX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE))
-#define get_sp_tx_end(sp_id) (CACTUS_TX_BASE + ((sp_id - 1) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
+#define get_sp_rx_start(sp_id) (CACTUS_RX_BASE + (((sp_id & 0x7FFFU) - 1U) * CACTUS_RX_TX_SIZE))
+#define get_sp_rx_end(sp_id) (CACTUS_RX_BASE + (((sp_id & 0x7FFFU) - 1U) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
+#define get_sp_tx_start(sp_id) (CACTUS_TX_BASE + (((sp_id & 0x7FFFU) - 1U) * CACTUS_RX_TX_SIZE))
+#define get_sp_tx_end(sp_id) (CACTUS_TX_BASE + (((sp_id & 0x7FFFU) - 1U) * CACTUS_RX_TX_SIZE) + PAGE_SIZE)
 
 /*
  * UUID of secure partition as defined in the respective manifests.
diff --git a/spm/cactus/cactus_ffa_tests.c b/spm/cactus/cactus_ffa_tests.c
index 085923a..a242e41 100644
--- a/spm/cactus/cactus_ffa_tests.c
+++ b/spm/cactus/cactus_ffa_tests.c
@@ -121,9 +121,9 @@
 	const char *test_all = "Get all partitions info";
 
 	const struct ffa_partition_info expected_info[] = {
-		{.id = SPM_VM_ID_FIRST, .exec_context = 8, .properties = 0}, /* Primary partition info */
-		{.id = SPM_VM_ID_SECOND, .exec_context = 2, .properties = 0}, /* Secondary partition info */
-		{.id = SPM_VM_ID_THIRD, .exec_context = 2, .properties = 0} /* Tertiary partition info */
+		{.id = SPM_VM_ID_FIRST, .exec_context = 8U, .properties = 0U}, /* Primary partition info */
+		{.id = SPM_VM_ID_FIRST + 1U, .exec_context = 8U, .properties = 0U}, /* Secondary partition info */
+		{.id = SPM_VM_ID_FIRST + 2U, .exec_context = 8U, .properties = 0U} /* Tertiary partition info */
 	};
 
 	announce_test_section_start(test_partition_info);
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index e833310..0809716 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -50,18 +50,21 @@
 	for (;;) {
 
 		if (ffa_ret.ret0 != FFA_MSG_SEND_DIRECT_REQ_SMC32) {
-			ffa_ret = ffa_error(-1);
-			continue;
+			ERROR("%s(%u) unknown func id 0x%lx\n",
+				__func__, vm_id, ffa_ret.ret0);
+			break;
 		}
 
-		if (ffa_ret.ret1 != SP_ID(vm_id)) {
-			ffa_ret = ffa_error(-2);
-			continue;
+		if (ffa_ret.ret1 != vm_id) {
+			ERROR("%s(%u) invalid vm id 0x%lx\n",
+				__func__, vm_id, ffa_ret.ret1);
+			break;
 		}
 
 		if (ffa_ret.ret2 != HYP_ID) {
-			ffa_ret = ffa_error(-3);
-			continue;
+			ERROR("%s(%u) invalid hyp id 0x%lx\n",
+				__func__, vm_id, ffa_ret.ret2);
+			break;
 		}
 
 		/*
@@ -74,9 +77,10 @@
 		 * Send a response through direct messaging then block
 		 * until receiving a new message request.
 		 */
-		ffa_ret = ffa_msg_send_direct_resp(SP_ID(vm_id),
-						     HYP_ID, sp_response);
+		ffa_ret = ffa_msg_send_direct_resp(vm_id, HYP_ID, sp_response);
 	}
+
+	panic();
 }
 
 static const mmap_region_t cactus_mmap[] __attribute__((used)) = {
@@ -143,6 +147,13 @@
 	init_xlat_tables();
 }
 
+int tftf_irq_handler_dispatcher(void)
+{
+	ERROR("%s\n", __func__);
+
+	return 0;
+}
+
 void __dead2 cactus_main(void)
 {
 	assert(IS_IN_EL1() != 0);
@@ -176,19 +187,13 @@
 
 		NOTICE("Booting Primary Cactus Secure Partition\n%s\n%s\n",
 			build_message, version_string);
-
-		/* Get number of VMs */
-		NOTICE("VM count: %u\n", spm_vm_get_count());
-
-		/* Get virtual CPU count for current VM */
-		NOTICE("vCPU count: %u\n", spm_vcpu_get_count(ffa_id));
 	} else {
 		set_putc_impl(HVC_CALL_AS_STDOUT);
 
 		NOTICE("Booting Secondary Cactus Secure Partition (ID: %u)\n%s\n%s\n",
 			ffa_id, build_message, version_string);
 
-		if (ffa_id == SPM_VM_ID_THIRD) {
+		if (ffa_id == (SPM_VM_ID_FIRST + 2)) {
 			NOTICE("Mapping RXTX Region\n");
 
 			/* Declare RX/TX buffers at virtual FF-A instance */
diff --git a/spm/common/sp_helpers.c b/spm/common/sp_helpers.c
index 7dc1648..1b650d3 100644
--- a/spm/common/sp_helpers.c
+++ b/spm/common/sp_helpers.c
@@ -75,22 +75,10 @@
  * Hypervisor Calls Wrappers
  ******************************************************************************/
 
-ffa_vcpu_count_t spm_vcpu_get_count(ffa_vm_id_t vm_id)
+ffa_int_id_t spm_interrupt_get(void)
 {
 	hvc_args args = {
-		.fid = SPM_VCPU_GET_COUNT,
-		.arg1 = vm_id
-	};
-
-	hvc_ret_values ret = tftf_hvc(&args);
-
-	return ret.ret0;
-}
-
-ffa_vm_count_t spm_vm_get_count(void)
-{
-	hvc_args args = {
-		.fid = SPM_VM_GET_COUNT
+		.fid = SPM_INTERRUPT_GET
 	};
 
 	hvc_ret_values ret = tftf_hvc(&args);
diff --git a/spm/common/sp_helpers.h b/spm/common/sp_helpers.h
index 7096daf..ec92227 100644
--- a/spm/common/sp_helpers.h
+++ b/spm/common/sp_helpers.h
@@ -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
  */
@@ -11,12 +11,10 @@
 #include <tftf_lib.h>
 #include <ffa_helpers.h>
 
-#define SPM_VM_ID_FIRST                 (1)
-#define SPM_VM_ID_SECOND                (2)
-#define SPM_VM_ID_THIRD                 (3)
+#define SPM_VM_ID_FIRST                 SP_ID(1)
 
-#define SPM_VM_GET_COUNT                (0xFF01)
-#define SPM_VCPU_GET_COUNT              (0xFF02)
+/* Should match with IDs defined in SPM/Hafnium */
+#define SPM_INTERRUPT_GET               (0xFF04)
 #define SPM_DEBUG_LOG                   (0xBD000000)
 
 typedef struct {
@@ -71,9 +69,7 @@
  * Hypervisor Calls Wrappers
  */
 
-ffa_vcpu_count_t spm_vcpu_get_count(ffa_vm_id_t vm_id);
-
-ffa_vm_count_t spm_vm_get_count(void);
+ffa_int_id_t spm_interrupt_get(void);
 
 void spm_debug_log(char c);
 
diff --git a/tftf/tests/runtime_services/secure_service/ffa_helpers.c b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
index 7ccf890..bda47c9 100644
--- a/tftf/tests/runtime_services/secure_service/ffa_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/ffa_helpers.c
@@ -134,7 +134,7 @@
 	 *
 	 */
 	ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
-					      OPTEE_FFA_GET_API_VERSION);
+						OPTEE_FFA_GET_API_VERSION);
 	if ((ret_values.ret3 == FFA_VERSION_MAJOR) &&
 	    (ret_values.ret4 == FFA_VERSION_MINOR)) {
 		is_optee_spmc_criteria++;
@@ -146,7 +146,7 @@
 	 *
 	 */
 	ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
-					      OPTEE_FFA_GET_OS_VERSION);
+						OPTEE_FFA_GET_OS_VERSION);
 	if ((ret_values.ret3 == OPTEE_FFA_GET_OS_VERSION_MAJOR) &&
 	    (ret_values.ret4 == OPTEE_FFA_GET_OS_VERSION_MINOR)) {
 		is_optee_spmc_criteria++;
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index 6008b78..d00793a 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -22,8 +22,7 @@
 	smc_ret_values ret_values;
 
 	/* Send a message to SP through direct messaging */
-	ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(sp_id),
-					      test_pattern);
+	ret_values = ffa_msg_send_direct_req(HYP_ID, sp_id, test_pattern);
 
 	/*
 	 * Return responses may be FFA_MSG_SEND_DIRECT_RESP or FFA_INTERRUPT,
@@ -70,7 +69,7 @@
 	/**********************************************************************
 	 * Send a message to SP1 through direct messaging
 	 **********************************************************************/
-	result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN1);
+	result = send_receive_direct_msg(SP_ID(1), DIRECT_MSG_TEST_PATTERN1);
 	if (result != TEST_RESULT_SUCCESS) {
 		return result;
 	}
@@ -78,7 +77,7 @@
 	/**********************************************************************
 	 * Send a message to SP2 through direct messaging
 	 **********************************************************************/
-	result = send_receive_direct_msg(2, DIRECT_MSG_TEST_PATTERN2);
+	result = send_receive_direct_msg(SP_ID(2), DIRECT_MSG_TEST_PATTERN2);
 	if (result != TEST_RESULT_SUCCESS) {
 		return result;
 	}
@@ -86,13 +85,7 @@
 	/**********************************************************************
 	 * Send a message to SP1 through direct messaging
 	 **********************************************************************/
-	result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN3);
-	if (result != TEST_RESULT_SUCCESS) {
-		return result;
-	}
+	result = send_receive_direct_msg(SP_ID(1), DIRECT_MSG_TEST_PATTERN3);
 
-	/**********************************************************************
-	 * All tests passed.
-	 **********************************************************************/
-	return TEST_RESULT_SUCCESS;
+	return result;
 }