test(notifications): retrieve interrupt IDs

FFA_FEATURES can be used to query about certain features, namely to
retrieve interrupt ID of:
- Notification Pending Interrupt.
- Scheduler Receiver Interrupt.
- Managed Exit Interrupt.
As those are all needed in the scope of the notifications feature,
added test to validate they can be retrieved and have expected values.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I808170780118cff0dc89008e135897af7009ab37
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 1774848..6d9c61d 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -30,6 +30,21 @@
 #include <cassert.h>
 #include <stdint.h>
 
+/**
+ * FF-A Feature ID, to be used with interface FFA_FEATURES.
+ * As defined in the FF-A v1.1 Beta specification, table 13.10, in section
+ * 13.2.
+ */
+
+/** Query interrupt ID of Notification Pending Interrupt. */
+#define FFA_FEATURE_NPI 0x1U
+
+/** Query interrupt ID of Schedule Receiver Interrupt. */
+#define FFA_FEATURE_SRI 0x2U
+
+/** Query interrupt ID of the Managed Exit Interrupt. */
+#define FFA_FEATURE_MEI 0x3U
+
 /** Partition property: partition supports receipt of direct requests. */
 #define FFA_PARTITION_DIRECT_REQ_RECV 0x1
 
@@ -62,6 +77,11 @@
 	return (ffa_id_t) val.ret2 & 0xffff;
 }
 
+static inline uint32_t ffa_feature_intid(smc_ret_values val)
+{
+	return (uint32_t)val.ret2;
+}
+
 typedef uint64_t ffa_notification_bitmap_t;
 
 #define FFA_NOTIFICATION(ID)		(UINT64_C(1) << ID)
diff --git a/include/runtime_services/spm_common.h b/include/runtime_services/spm_common.h
index 91a3b8c..58569d5 100644
--- a/include/runtime_services/spm_common.h
+++ b/include/runtime_services/spm_common.h
@@ -25,6 +25,9 @@
 /* INTID for the managed exit virtual interrupt. */
 #define MANAGED_EXIT_INTERRUPT_ID	U(4)
 
+/* INTID for the notification pending interrupt. */
+#define NOTIFICATION_PENDING_INTERRUPT_INTID 5
+
 /** IRQ/FIQ pin used for signaling a virtual interrupt. */
 enum interrupt_pin {
 	INTERRUPT_TYPE_IRQ,
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index cb1ccd4..dde8d58 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -33,9 +33,6 @@
 uint32_t per_vcpu_flags_get;
 static event_t per_vcpu_finished[PLATFORM_CORE_COUNT];
 
-/* TODO: replace use for this ID with respective call to ffa_features. */
-#define NOTIFICATION_PENDING_INTERRUPT_INTID 5
-
 static const struct ffa_uuid expected_sp_uuids[] = {
 		{PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
 };
@@ -47,6 +44,59 @@
 						   FFA_NOTIFICATION(63);
 
 /**
+ * Use FFA_FEATURES to retrieve the ID of:
+ * - Schedule Receiver Interrupt
+ * - Notification Pending Interrupt
+ * - Managed Exit Interrupt
+ * Validate the call works as expected, and they match the used int ID in the
+ * remainder of the tests.
+ */
+test_result_t test_notifications_retrieve_int_ids(void)
+{
+	smc_ret_values ret;
+
+	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1, 1);
+
+	/* Check if SPMC is OP-TEE at S-EL1 */
+	if (check_spmc_execution_level()) {
+		/* FFA_FEATURES is not yet supported in OP-TEE */
+		return TEST_RESULT_SUCCESS;
+	}
+
+	ret = ffa_features(FFA_FEATURE_NPI);
+	if (is_ffa_call_error(ret) ||
+	    ffa_feature_intid(ret) != NOTIFICATION_PENDING_INTERRUPT_INTID) {
+		ERROR("Failed to retrieved NPI (exp: %u, got: %u)\n",
+		      NOTIFICATION_PENDING_INTERRUPT_INTID,
+		      ffa_feature_intid(ret));
+
+		return TEST_RESULT_FAIL;
+	}
+
+	ret = ffa_features(FFA_FEATURE_SRI);
+	if (is_ffa_call_error(ret) ||
+	    ffa_feature_intid(ret) != FFA_SCHEDULE_RECEIVER_INTERRUPT_ID) {
+		ERROR("Failed to retrieved SRI (exp: %u, got: %u)\n",
+		      FFA_SCHEDULE_RECEIVER_INTERRUPT_ID,
+		      ffa_feature_intid(ret));
+
+		return TEST_RESULT_FAIL;
+	}
+
+	ret = ffa_features(FFA_FEATURE_MEI);
+	if (is_ffa_call_error(ret) ||
+	    ffa_feature_intid(ret) != MANAGED_EXIT_INTERRUPT_ID) {
+		ERROR("Failed to retrieved MEI (exp: %u, got: %u)\n",
+		      MANAGED_EXIT_INTERRUPT_ID,
+		      ffa_feature_intid(ret));
+
+		return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/**
  * Helper to create bitmap for NWd VMs.
  */
 static bool notifications_bitmap_create(ffa_id_t vm_id,
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index e8bbb5d..9603b9a 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -110,6 +110,8 @@
 
   <testsuite name="FF-A Notifications"
              description="Test Notifications functionality" >
+     <testcase name="Notifications interrupts ID retrieval with FFA_FEATURES"
+                function= "test_notifications_retrieve_int_ids" />
      <testcase name="Notifications bitmap create and destroy"
                function="test_ffa_notifications_bitmap_create_destroy" />
      <testcase name="Notifications bitmap destroy not created"