fix(interrupts): check support for ESPI before testing it

It is possible for extended range interrupts to be enabled by software
but the underlying hardware (GIC) may not support it. In such,
scenarios check if the support exists before exercising the
ESPI functionality.

Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ibdf18be8403539c0ae9204309adc8a81dd0382d3
diff --git a/drivers/arm/gic/arm_gic_v2.c b/drivers/arm/gic/arm_gic_v2.c
index 8266626..a781703 100644
--- a/drivers/arm/gic/arm_gic_v2.c
+++ b/drivers/arm/gic/arm_gic_v2.c
@@ -9,6 +9,7 @@
 #include <assert.h>
 #include <debug.h>
 #include <drivers/arm/gic_v2.h>
+#include <stdbool.h>
 
 void arm_gic_enable_interrupts_local(void)
 {
@@ -119,3 +120,8 @@
 	INFO("ARM GIC v2 driver initialized\n");
 }
 
+bool arm_gic_is_espi_supported(void)
+{
+	/* ESPI not supported by GICv2. */
+	return false;
+}
diff --git a/drivers/arm/gic/arm_gic_v2v3.c b/drivers/arm/gic/arm_gic_v2v3.c
index a3f84d0..9c7692e 100644
--- a/drivers/arm/gic/arm_gic_v2v3.c
+++ b/drivers/arm/gic/arm_gic_v2v3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/gic_v2.h>
 #include <drivers/arm/gic_v3.h>
+#include <stdbool.h>
 
 /* Record whether a GICv3 was detected on the system */
 static unsigned int gicv3_detected;
@@ -194,3 +195,19 @@
 	INFO("%s mode detected\n", (gicv3_detected) ?
 			"GICv3" : "GICv2");
 }
+
+bool arm_gic_is_espi_supported(void)
+{
+	unsigned int typer_reg = gicv3_get_gicd_typer();
+
+	if (!gicv3_detected) {
+		return false;
+	}
+
+	/* Check if extended SPI range is implemented. */
+	if ((typer_reg & TYPER_ESPI) != 0U) {
+		return true;
+	}
+
+	return false;
+}
diff --git a/drivers/arm/gic/gic_v3.c b/drivers/arm/gic/gic_v3.c
index 56049e3..93c707a 100644
--- a/drivers/arm/gic/gic_v3.c
+++ b/drivers/arm/gic/gic_v3.c
@@ -505,3 +505,8 @@
 	gicr_base_addr = gicr_base;
 	gicd_base_addr = gicd_base;
 }
+
+unsigned int gicv3_get_gicd_typer(void)
+{
+	return gicd_read_typer(gicd_base_addr);
+}
diff --git a/include/drivers/arm/arm_gic.h b/include/drivers/arm/arm_gic.h
index 0f27dc1..528ec6e 100644
--- a/include/drivers/arm/arm_gic.h
+++ b/include/drivers/arm/arm_gic.h
@@ -7,6 +7,7 @@
 #ifndef __ARM_GIC_H__
 #define __ARM_GIC_H__
 
+#include <stdbool.h>
 #include <stdint.h>
 
 /***************************************************************************
@@ -150,4 +151,9 @@
  *****************************************************************************/
 void arm_gic_restore_context_global(void);
 
+/******************************************************************************
+ * Check if extended SPI range is implemented by GIC.
+ *****************************************************************************/
+bool arm_gic_is_espi_supported(void);
+
 #endif /* __ARM_GIC_H__ */
diff --git a/include/drivers/arm/gic_v3.h b/include/drivers/arm/gic_v3.h
index e164103..2f4b52d 100644
--- a/include/drivers/arm/gic_v3.h
+++ b/include/drivers/arm/gic_v3.h
@@ -34,6 +34,13 @@
 #define IROUTER_IRM_SHIFT	31
 #define IROUTER_IRM_MASK	0x1
 
+/* GICD_TYPER shifts and masks */
+#define	TYPER_ESPI		U(1 << 8)
+#define	TYPER_DVIS		U(1 << 18)
+#define	TYPER_ESPI_RANGE_MASK	U(0x1f)
+#define	TYPER_ESPI_RANGE_SHIFT	U(27)
+#define	TYPER_ESPI_RANGE	U(TYPER_ESPI_MASK << TYPER_ESPI_SHIFT)
+
 /*******************************************************************************
  * GICv3 Re-distributor interface registers & constants
  ******************************************************************************/
@@ -229,6 +236,10 @@
  */
 void gicv3_enable_cpuif(void);
 
+/*
+ * Return the value of GICD_TYPER.
+ */
+unsigned int gicv3_get_gicd_typer(void);
 
 #endif /*__ASSEMBLY__*/
 #endif /* __GIC_V3_H__ */
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
index 3f746f4..40e52c9 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_secure_interrupts.c
@@ -13,6 +13,8 @@
 #include <test_helpers.h>
 #include <timer.h>
 
+#include <drivers/arm/arm_gic.h>
+
 #define SENDER		HYP_ID
 #define RECEIVER	SP_ID(1)
 #define RECEIVER_2	SP_ID(2)
@@ -448,6 +450,11 @@
 {
 	struct ffa_value ret_values;
 
+	/* Check if extended SPI range is implemented by GIC. */
+	if (!arm_gic_is_espi_supported()) {
+		return TEST_RESULT_SKIPPED;
+	}
+
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
 	/* Enable ESPI. */