fix: ignore errors on optional General service queries

Ignore SMC_UNKNOWN errors on optional 'General service queries' defined
in SMCCC Section 6.2.

Change-Id: Iaf3d0b2f1750c83b104e2fd3e8640318493da062
Signed-off-by: Imre Kis <imre.kis@arm.com>
diff --git a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
index 0b3b6e3..50d918a 100644
--- a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
+++ b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
@@ -47,6 +47,10 @@
 	ven_el3_svc_args.fid = VEN_EL3_SVC_UID;
 	ret = tftf_smc(&ven_el3_svc_args);
 
+	/* These functions are optional, skip test when not supported. */
+	if (ret.ret0 == SMC_UNKNOWN)
+		return TEST_RESULT_SKIPPED;
+
 	make_uuid_from_4words(&ven_el3_svc_uuid,
 			ret.ret0, ret.ret1, ret.ret2, ret.ret3);
 	if (!uuid_equal(&ven_el3_svc_uuid, &armtf_ven_el3_svc_uuid)) {
diff --git a/tftf/tests/runtime_services/generic/generic_smc.c b/tftf/tests/runtime_services/generic/generic_smc.c
index 6d057a6..676e803 100644
--- a/tftf/tests/runtime_services/generic/generic_smc.c
+++ b/tftf/tests/runtime_services/generic/generic_smc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,6 +46,26 @@
 	} while (0)
 
 /*
+ * Check that the values it returns match the expected ones. If not, write an
+ * error message in the test report.
+ */
+static bool smc_check_eq_common(const smc_ret_values *ret,
+				const smc_ret_values *expect)
+{
+	if (memcmp(ret, expect, sizeof(smc_ret_values)) == 0)
+		return true;
+
+	tftf_testcase_printf(
+		"Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
+		expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
+		ret->ret0, ret->ret1, ret->ret2, ret->ret3,
+		ret->ret4, ret->ret5, ret->ret6, ret->ret7,
+		expect->ret0, expect->ret1, expect->ret2, expect->ret3,
+		expect->ret4, expect->ret5, expect->ret6, expect->ret7);
+	return false;
+}
+
+/*
  * Send an SMC with the specified arguments.
  * Check that the values it returns match the expected ones. If not, write an
  * error message in the test report.
@@ -54,18 +74,27 @@
 {
 	smc_ret_values ret = tftf_smc(args);
 
-	if (memcmp(&ret, expect, sizeof(smc_ret_values)) == 0) {
-		return true;
-	} else {
-		tftf_testcase_printf(
-			"Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
-			expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
-			ret.ret0, ret.ret1, ret.ret2, ret.ret3,
-			ret.ret4, ret.ret5, ret.ret6, ret.ret7,
-			expect->ret0, expect->ret1, expect->ret2, expect->ret3,
-			expect->ret4, expect->ret5, expect->ret6, expect->ret7);
-		return false;
-	}
+	return smc_check_eq_common(&ret, expect);
+}
+
+/*
+ * Send an optional SMC with the specified arguments. Treat it as skipped if the
+ * firmware does not support the call and skip further checks.
+ * Otherwise, check that the values it returns match the expected ones. If not,
+ * return a test fail result.
+ */
+static test_result_t smc_check_eq_optional(const smc_args *args, const smc_ret_values *expect)
+{
+	smc_ret_values ret = tftf_smc(args);
+
+	if (ret.ret0 == SMC_UNKNOWN)
+		return TEST_RESULT_SKIPPED;
+
+	if (smc_check_eq_common(&ret, expect))
+		return TEST_RESULT_SUCCESS;
+	else
+		return TEST_RESULT_FAIL;
+
 }
 
 /*
@@ -153,9 +182,14 @@
 /* Exercise SMC32 calling convention with fast SMC calls. */
 test_result_t smc32_fast(void)
 {
+	test_result_t result;
+
 	/* Valid Fast SMC32 using all 4 return values. */
 	const smc_args args1 = { .fid = SMC_STD_SVC_UID };
-	FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+	result = smc_check_eq_optional(&args1, &std_svc_uuid);
+	if (result != TEST_RESULT_SUCCESS) {
+		return result;
+	}
 
 	/* Invalid Fast SMC32. */
 	const smc_args args2 = {
@@ -182,9 +216,14 @@
 /* Exercise SMC64 calling convention with yielding SMC calls. */
 test_result_t smc64_yielding(void)
 {
+	test_result_t result;
+
 	/* Valid Fast SMC32 using all 4 return values. */
 	const smc_args args1 = { .fid = SMC_STD_SVC_UID };
-	FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+	result = smc_check_eq_optional(&args1, &std_svc_uuid);
+	if (result != TEST_RESULT_SUCCESS) {
+		return result;
+	}
 
 	/* Invalid function number, SMC64 Yielding. */
 	const smc_args args2 = {
@@ -239,9 +278,14 @@
 #ifndef __aarch64__
 static test_result_t smc64_fast_caller32(void)
 {
+	test_result_t result;
+
 	/* Valid Fast SMC32 using all 4 return values. */
 	smc_args args1 = { .fid = SMC_STD_SVC_UID };
-	FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+	result = smc_check_eq_optional(&args1, &std_svc_uuid);
+	if (result != TEST_RESULT_SUCCESS) {
+		return result;
+	}
 
 	/* Invalid SMC function number, Fast SMC64. */
 	const smc_args args2 = {
@@ -270,9 +314,14 @@
 #else
 static test_result_t smc64_fast_caller64(void)
 {
+	test_result_t result;
+
 	/* Valid Fast SMC32 using all 4 return values. */
 	smc_args args1 = { .fid = SMC_STD_SVC_UID };
-	FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+	result = smc_check_eq_optional(&args1, &std_svc_uuid);
+	if (result != TEST_RESULT_SUCCESS) {
+		return result;
+	}
 
 	/* Invalid function number, Fast SMC64. */
 	const smc_args args2 = {
@@ -310,9 +359,14 @@
 /* Exercise SMC32 calling convention with yielding SMC calls. */
 test_result_t smc32_yielding(void)
 {
+	test_result_t result;
+
 	/* Valid Fast SMC32 using all 4 return values. */
 	const smc_args args1 = { .fid = SMC_STD_SVC_UID };
-	FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+	result = smc_check_eq_optional(&args1, &std_svc_uuid);
+	if (result != TEST_RESULT_SUCCESS) {
+		return result;
+	}
 
 	/* Invalid function number, SMC32 Yielding. */
 	const smc_args args2 = {
diff --git a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
index 43685e4..259ed1d 100644
--- a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
+++ b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
@@ -75,10 +75,11 @@
 	args.fid = PMF_SMC_GET_VERSION;
 	ret = tftf_smc(&args);
 
+	if (ret.ret0 == SMC_UNKNOWN)
+		return TEST_RESULT_SKIPPED;
+
 	if (ret.ret1 != PMF_SMC_VERSION)
-	{
 		return TEST_RESULT_FAIL;
-	}
 
 	return TEST_RESULT_SUCCESS;
 }
diff --git a/tftf/tests/runtime_services/standard_service/query_std_svc.c b/tftf/tests/runtime_services/standard_service/query_std_svc.c
index c8ce6e9..6debe63 100644
--- a/tftf/tests/runtime_services/standard_service/query_std_svc.c
+++ b/tftf/tests/runtime_services/standard_service/query_std_svc.c
@@ -47,6 +47,10 @@
 	std_svc_args.fid = SMC_STD_SVC_UID;
 	ret = tftf_smc(&std_svc_args);
 
+	/* These functions are optional, skip test when not supported. */
+	if (ret.ret0 == SMC_UNKNOWN)
+		return TEST_RESULT_SKIPPED;
+
 	make_uuid_from_4words(&std_svc_uuid,
 			ret.ret0, ret.ret1, ret.ret2, ret.ret3);
 	if (!uuid_equal(&std_svc_uuid, &armtf_std_svc_uuid)) {