Merge changes from topic "sb/smc-tests-tos"

* changes:
  Relax SMC tests when Trusted OS is present
  Make UUID buffer optional for is_trusted_os_present()
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c b/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c
new file mode 100644
index 0000000..44ee0f9
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spci_blocking_interrupt.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cactus_def.h>
+#include <debug.h>
+#include <smccc.h>
+#include <spci_helpers.h>
+#include <spci_svc.h>
+#include <string.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+static volatile int timer_irq_received;
+
+/*
+ * ISR for the timer interrupt. Update a global variable to check it has been
+ * called.
+ */
+static int timer_handler(void *data)
+{
+	assert(timer_irq_received == 0);
+	timer_irq_received = 1;
+	return 0;
+}
+
+/*
+ * @Test_Aim@ Test that non-secure interrupts do not interrupt blocking
+ * requests.
+ *
+ * 1. Register a handler for the non-secure timer interrupt. Program it to fire
+ *    in a certain time.
+ *
+ * 2. Send a blocking request to Cactus to sleep for more time than the timer.
+ *
+ * 3. While servicing the timer sleep request, the non-secure timer should
+ *    fire but not interrupt Cactus.
+ *
+ * 4. Once back in TFTF, check the response from Cactus, which shows whether the
+ *    secure service indeed ran to completion.
+ *
+ * 5. Also check whether the pending non-secure timer interrupt successfully got
+ *    handled in TFTF.
+ */
+test_result_t test_spci_blocking_interrupt_by_ns(void)
+{
+	int ret;
+	uint16_t handle_cactus;
+	test_result_t result = TEST_RESULT_SUCCESS;
+
+	SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 1);
+
+	/* Open handle */
+
+	ret = spci_service_handle_open(TFTF_SPCI_CLIENT_ID, &handle_cactus,
+				       CACTUS_SERVICE1_UUID);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to return a valid handle. Returned: %d\n",
+				     __LINE__, ret);
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Program timer */
+
+	timer_irq_received = 0;
+	tftf_timer_register_handler(timer_handler);
+
+	ret = tftf_program_timer(100);
+	if (ret < 0) {
+		tftf_testcase_printf("Failed to program timer (%d)\n", ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Send request to Cactus */
+
+	ret = spci_service_request_blocking(CACTUS_SLEEP_MS, 200U,
+					    0, 0, 0, 0,
+					    TFTF_SPCI_CLIENT_ID,
+					    handle_cactus,
+					    NULL, NULL, NULL);
+	if (ret != SPCI_SUCCESS) {
+		/*
+		 * If the interrupt is handled during the blocking call, there
+		 * will be a crash in EL3 because the function that invokes a
+		 * blocking call doesn't know how to handle it. The CPU won't
+		 * come back here (because it should never happen!).
+		 */
+		tftf_testcase_printf("%d: SPM should have returned SPCI_SUCCESS. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Check that the interrupt has been handled */
+
+	tftf_cancel_timer();
+	tftf_timer_unregister_handler();
+
+	if (timer_irq_received == 0) {
+		tftf_testcase_printf("%d: Timer interrupt hasn't actually been handled.\n",
+				     __LINE__);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Close handle */
+
+	ret = spci_service_handle_close(TFTF_SPCI_CLIENT_ID, handle_cactus);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to close the handle. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* All tests finished */
+
+	return result;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_blocking_while_busy.c b/tftf/tests/runtime_services/secure_service/test_spci_blocking_while_busy.c
new file mode 100644
index 0000000..dffd910
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spci_blocking_while_busy.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cactus_def.h>
+#include <debug.h>
+#include <smccc.h>
+#include <spci_helpers.h>
+#include <spci_svc.h>
+#include <string.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+static volatile int timer_irq_received;
+
+/*
+ * ISR for the timer interrupt. Update a global variable to check it has been
+ * called.
+ */
+static int timer_handler(void *data)
+{
+	assert(timer_irq_received == 0);
+	timer_irq_received = 1;
+	return 0;
+}
+
+/*
+ * @Test_Aim@ Test that blocking requests can only be done when there are no
+ * active non-blocking requests in a partition.
+ *
+ * 1. Register a handler for the non-secure timer interrupt. Program it to fire
+ *    in a certain time.
+ *
+ * 2. Send a non-blocking request to Cactus to sleep for more time than the
+ *    timer.
+ *
+ * 3. While servicing the timer sleep request, the non-secure timer should
+ *    fire and interrupt Cactus.
+ *
+ * 5. Check that the interrupt has been handled.
+ *
+ * 6. Make sure that the response isn't ready yet.
+ *
+ * 7. Try to send a blocking request. It should be denied because the partition
+ *    is busy.
+ *
+ * 8. Return to Cactus to finish the request.
+ */
+test_result_t test_spci_blocking_while_busy(void)
+{
+	int ret;
+	u_register_t rx1, rx2, rx3;
+	uint16_t handle_cactus;
+	uint32_t token_cactus;
+	test_result_t result = TEST_RESULT_SUCCESS;
+
+	SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 1);
+
+	/* Open handle. */
+
+	ret = spci_service_handle_open(TFTF_SPCI_CLIENT_ID, &handle_cactus,
+				       CACTUS_SERVICE1_UUID);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to return a valid handle. Returned: %d\n",
+				     __LINE__, ret);
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Program timer */
+
+	timer_irq_received = 0;
+	tftf_timer_register_handler(timer_handler);
+
+	ret = tftf_program_timer(100);
+	if (ret < 0) {
+		tftf_testcase_printf("Failed to program timer (%d)\n", ret);
+		result = TEST_RESULT_FAIL;
+		goto exit_close_handle;
+	}
+
+	enable_irq();
+
+	/* Send request to Cactus */
+
+	ret = spci_service_request_start(CACTUS_SLEEP_MS, 200U,
+					 0, 0, 0, 0,
+					 TFTF_SPCI_CLIENT_ID,
+					 handle_cactus,
+					 &token_cactus);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM should have returned SPCI_SUCCESS. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Check that the interrupt has been handled. */
+
+	if (timer_irq_received == 0) {
+		tftf_testcase_printf("%d: Didn't handle interrupt\n", __LINE__);
+		result = TEST_RESULT_FAIL;
+	}
+
+	tftf_cancel_timer();
+	tftf_timer_unregister_handler();
+
+	/* Make sure that the response is not ready yet. */
+
+	ret = spci_service_get_response(TFTF_SPCI_CLIENT_ID,
+					handle_cactus,
+					token_cactus,
+					NULL, NULL, NULL);
+
+	if (ret == SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: Cactus returned SPCI_SUCCESS\n",
+				     __LINE__);
+		result = TEST_RESULT_FAIL;
+		goto exit_close_handle;
+	}
+
+	/*
+	 * Try to send a blocking request. It should be denied because the
+	 * partition is busy.
+	 */
+
+	ret = spci_service_request_blocking(CACTUS_GET_MAGIC,
+					    0, 0, 0, 0, 0,
+					    TFTF_SPCI_CLIENT_ID,
+					    handle_cactus,
+					    &rx1, &rx2, &rx3);
+	if (ret != SPCI_BUSY) {
+		tftf_testcase_printf("%d: Cactus should have returned SPCI_BUSY. Returned %d 0x%lx 0x%lx 0x%lx\n",
+				     __LINE__, ret, rx1, rx2, rx3);
+		result = TEST_RESULT_FAIL;
+		goto exit_close_handle;
+	}
+
+	/* Re-enter Cactus to finish the request */
+
+	do {
+		ret = spci_service_request_resume(TFTF_SPCI_CLIENT_ID,
+						  handle_cactus,
+						  token_cactus,
+						  &rx1, NULL, NULL);
+	} while (ret == SPCI_QUEUED);
+
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: Cactus returned %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Close handle. */
+exit_close_handle:
+
+	ret = spci_service_handle_close(TFTF_SPCI_CLIENT_ID, handle_cactus);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to close the handle. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* All tests finished. */
+
+	return result;
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_non_blocking_interrupt.c b/tftf/tests/runtime_services/secure_service/test_spci_non_blocking_interrupt.c
new file mode 100644
index 0000000..cb5dd6b
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spci_non_blocking_interrupt.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cactus_def.h>
+#include <debug.h>
+#include <smccc.h>
+#include <spci_helpers.h>
+#include <spci_svc.h>
+#include <string.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+static volatile int timer_irq_received;
+
+/*
+ * ISR for the timer interrupt. Update a global variable to check it has been
+ * called.
+ */
+static int timer_handler(void *data)
+{
+	assert(timer_irq_received == 0);
+	timer_irq_received = 1;
+	return 0;
+}
+
+/*
+ * @Test_Aim@ Test that non-secure interrupts interrupt non-blocking requests.
+ *
+ * 1. Register a handler for the non-secure timer interrupt. Program it to fire
+ *    in a certain time.
+ *
+ * 2. Send a non-blocking request to Cactus to sleep for more time than the
+ *    timer.
+ *
+ * 3. While servicing the timer sleep request, the non-secure timer should
+ *    fire and interrupt Cactus.
+ *
+ * 4. Make sure that the response isn't ready yet.
+ *
+ * 5. In the TFTF, check that the interrupt has been handled.
+ *
+ * 6. Return to Cactus to finish the request.
+ */
+test_result_t test_spci_non_blocking_interrupt_by_ns(void)
+{
+	int ret;
+	u_register_t ret1;
+	uint16_t handle_cactus;
+	uint32_t token_cactus;
+	test_result_t result = TEST_RESULT_SUCCESS;
+
+	SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 1);
+
+	/* Open handle */
+
+	ret = spci_service_handle_open(TFTF_SPCI_CLIENT_ID, &handle_cactus,
+				       CACTUS_SERVICE1_UUID);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to return a valid handle. Returned: %d\n",
+				     __LINE__, ret);
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Program timer */
+
+	timer_irq_received = 0;
+	tftf_timer_register_handler(timer_handler);
+
+	ret = tftf_program_timer(100);
+	if (ret < 0) {
+		tftf_testcase_printf("Failed to program timer (%d)\n", ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Send request to Cactus */
+
+	ret = spci_service_request_start(CACTUS_SLEEP_MS, 200U,
+					 0, 0, 0, 0,
+					 TFTF_SPCI_CLIENT_ID,
+					 handle_cactus,
+					 &token_cactus);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM should have returned SPCI_SUCCESS. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Check that the interrupt has been handled */
+
+	tftf_cancel_timer();
+	tftf_timer_unregister_handler();
+
+	if (timer_irq_received == 0) {
+		tftf_testcase_printf("%d: Didn't handle interrupt\n", __LINE__);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Make sure that the response is not ready yet */
+
+	ret = spci_service_get_response(TFTF_SPCI_CLIENT_ID,
+					handle_cactus,
+					token_cactus,
+					NULL, NULL, NULL);
+
+	if (ret == SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: Cactus returned SPCI_SUCCESS\n",
+				__LINE__);
+		result = TEST_RESULT_FAIL;
+		goto exit_close_handle;
+	}
+
+	/* Re-enter Cactus to finish the request */
+
+	do {
+		ret = spci_service_request_resume(TFTF_SPCI_CLIENT_ID,
+						  handle_cactus,
+						  token_cactus,
+						  &ret1, NULL, NULL);
+	} while (ret == SPCI_QUEUED);
+
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: Cactus returned 0x%x\n",
+				__LINE__, (uint32_t)ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* Close handle */
+exit_close_handle:
+
+	ret = spci_service_handle_close(TFTF_SPCI_CLIENT_ID, handle_cactus);
+	if (ret != SPCI_SUCCESS) {
+		tftf_testcase_printf("%d: SPM failed to close the handle. Returned: %d\n",
+				     __LINE__, ret);
+		result = TEST_RESULT_FAIL;
+	}
+
+	/* All tests finished */
+
+	return result;
+}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 0dba413..c487687 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -10,4 +10,7 @@
 		test_spci_handle_open.c					\
 		test_spci_blocking_request.c				\
 		test_spci_non_blocking_request.c			\
+		test_spci_blocking_while_busy.c				\
+		test_spci_blocking_interrupt.c				\
+		test_spci_non_blocking_interrupt.c			\
 	)
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index bb6e5dd..9afc6af 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -22,6 +22,14 @@
      <testcase name="SPCI non-blocking requests multicore"
                function="test_spci_request_multicore" />
 
+     <testcase name="SPCI blocking request while busy"
+               function="test_spci_blocking_while_busy" />
+
+     <testcase name="SPCI blocking request fail to preempt"
+               function="test_spci_blocking_interrupt_by_ns" />
+     <testcase name="SPCI non-blocking request succeed to preempt"
+               function="test_spci_non_blocking_interrupt_by_ns" />
+
   </testsuite>
 
 </testsuites>