test: exercise secure espi interrupt handling
Hafnium/SPMC added support for enabling interrupts in the extended SPI
range. With the help of an SiP SMC call that can pend an interrupt,
this patch adds a test to trigger an espi interrupt when cactus is
running and ensure it is handled.
Additionally, a dummy device region node representing a fake
peripheral has been added to the Cactus SP manifest. It is used to
specify properties of the interrupt in the extended SPI range used
for the above test scenario.
Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ief932c40e3abd33d619f2b144e61cae449147b27
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c
index efe2260..6a1092b 100644
--- a/spm/cactus/cactus_tests/cactus_test_interrupts.c
+++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c
@@ -12,11 +12,13 @@
#include "cactus_message_loop.h"
#include "cactus_test_cmds.h"
+#include <mmio.h>
#include <platform.h>
/* Secure virtual interrupt that was last handled by Cactus SP. */
extern uint32_t last_serviced_interrupt[PLATFORM_CORE_COUNT];
static int flag_set;
+static volatile bool test_espi_handled;
static void handle_sec_wdog_interrupt(void)
{
@@ -227,3 +229,43 @@
ffa_dir_msg_source(*args),
last_serviced_interrupt[core_pos]);
}
+
+static void sec_interrupt_test_espi_handled(void)
+{
+ expect(test_espi_handled, false);
+ test_espi_handled = true;
+ NOTICE("Interrupt handler for test espi interrupt called\n");
+
+ /* Perform secure interrupt de-activation. */
+ spm_interrupt_deactivate(IRQ_ESPI_TEST_INTID);
+}
+
+CACTUS_CMD_HANDLER(trigger_espi_cmd, CACTUS_TRIGGER_ESPI_CMD)
+{
+ uint32_t espi_id = cactus_get_espi_id(*args);
+
+ /*
+ * The SiP function ID 0x82000100 must have been added to the SMC
+ * whitelist of the Cactus SP that invokes it.
+ */
+ smc_args plat_sip_call = {
+ .fid = 0x82000100,
+ .arg1 = espi_id,
+ };
+ smc_ret_values ret;
+
+ sp_register_interrupt_handler(sec_interrupt_test_espi_handled,
+ espi_id);
+ ret = tftf_smc(&plat_sip_call);
+
+ if (ret.ret0 == SMC_UNKNOWN) {
+ ERROR("SiP SMC call not supported\n");
+ return cactus_error_resp(ffa_dir_msg_dest(*args),
+ ffa_dir_msg_source(*args),
+ CACTUS_ERROR_TEST);
+ }
+
+ return cactus_response(ffa_dir_msg_dest(*args),
+ ffa_dir_msg_source(*args),
+ test_espi_handled ? 1 : 0);
+}