Merge "Allowing zeroes in trusted OS SMC return values"
diff --git a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
index a090874..cf36e4f 100644
--- a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
+++ b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,7 +15,12 @@
 #include <tftf_lib.h>
 
 #ifdef AARCH64
-#define CORTEX_A76_MIDR 0x410fd0b0
+#define NOT_REQUIRED_DONOT_INVOKE	-2
+#define NOT_SUPPORTED			-1
+#define IS_REQUIRED			 0
+#define NOT_REQUIRED			 1
+
+#define CORTEX_A76_MIDR	0x410fd0b0
 
 static int cortex_a76_test(void);
 
@@ -37,7 +42,6 @@
 	smc_ret_values ret;
 	int32_t expected_ver;
 	unsigned int my_midr, midr_mask;
-	int wa_required;
 	size_t i;
 
 	/* Check if SMCCC version is at least v1.1 */
@@ -56,16 +60,43 @@
 	args.fid = SMCCC_ARCH_FEATURES;
 	args.arg1 = SMCCC_ARCH_WORKAROUND_2;
 	ret = tftf_smc(&args);
-	if ((int)ret.ret0 == -1) {
-		tftf_testcase_printf("SMCCC_ARCH_WORKAROUND_2 is not implemented\n");
-		return TEST_RESULT_SKIPPED;
-	}
 
-	/* If the call returns 0, it means the workaround is required */
-	if ((int)ret.ret0 == 0)
-		wa_required = 1;
-	else
-		wa_required = 0;
+	switch ((int)ret.ret0) {
+
+	case NOT_REQUIRED_DONOT_INVOKE:
+		/*
+		 * This workaround is not required and must not be invoked on
+		 * any PE in this system
+		 */
+		tftf_testcase_printf("SMCCC_ARCH_WORKAROUND_2 is not required\n");
+		return TEST_RESULT_SKIPPED;
+
+	case NOT_SUPPORTED:
+		/*
+		 * This workaround is not supported and must not be invoked on
+		 * any PE in this system
+		 */
+		tftf_testcase_printf("SMCCC_ARCH_WORKAROUND_2 is not supported\n");
+		return TEST_RESULT_SKIPPED;
+
+	case IS_REQUIRED:
+		/* This workaround is required. Proceed with the test */
+		break;
+
+	case NOT_REQUIRED:
+		/*
+		 * This PE does not require dynamic firmware mitigation using
+		 * SMCCC_ARCH_WORKAROUND_2
+		 */
+		tftf_testcase_printf("SMCCC_ARCH_WORKAROUND_2 is not required\n");
+		return TEST_RESULT_SKIPPED;
+
+	default:
+		tftf_testcase_printf("Illegal value %d returned by "
+				"SMCCC_ARCH_WORKAROUND_2 function\n", (int)ret.ret0);
+		return TEST_RESULT_FAIL;
+
+	}
 
 	/* Check if the SMC return value matches our expectations */
 	my_midr = (unsigned int)read_midr_el1();
@@ -75,12 +106,12 @@
 		struct ent *entp = &entries[i];
 
 		if ((my_midr & midr_mask) == (entp->midr & midr_mask)) {
-			if (entp->wa_required() != wa_required)
+			if (entp->wa_required() != 1)
 				return TEST_RESULT_FAIL;
 			break;
 		}
 	}
-	if (i == ARRAY_SIZE(entries) && wa_required) {
+	if (i == ARRAY_SIZE(entries)) {
 		tftf_testcase_printf("TFTF workaround table out of sync with TF\n");
 		return TEST_RESULT_FAIL;
 	}
@@ -128,4 +159,4 @@
 	INFO("%s skipped on AArch32\n", __func__);
 	return TEST_RESULT_SKIPPED;
 }
-#endif
+#endif /* AARCH64 */