summaryrefslogtreecommitdiff
path: root/spm
diff options
context:
space:
mode:
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>2022-01-28 17:01:35 -0600
committerMadhukar Pappireddy <madhukar.pappireddy@arm.com>2022-03-22 13:05:49 -0500
commit7caaa4a2098b67f73bf8a87a9ec550720f9dc428 (patch)
tree2d485bcb9e50d35a694e6d2ad052da906d32962c /spm
parent407befcf35d6e62303eceb7efc82610c940c3ef2 (diff)
feat(interrupts): support for registering custom handler
This patch provides support for registering and unregistering handler that is invoked by SP at the tail end of the virtual interrupt processing. Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com> Change-Id: Ia12686361063bb680ff32b4f4bf90e0af2521c36
Diffstat (limited to 'spm')
-rw-r--r--spm/cactus/cactus_interrupt.c11
-rw-r--r--spm/cactus/cactus_main.c3
-rw-r--r--spm/common/sp_helpers.c38
-rw-r--r--spm/common/sp_helpers.h18
4 files changed, 67 insertions, 3 deletions
diff --git a/spm/cactus/cactus_interrupt.c b/spm/cactus/cactus_interrupt.c
index ef3d5cc..f0d916f 100644
--- a/spm/cactus/cactus_interrupt.c
+++ b/spm/cactus/cactus_interrupt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,6 +22,8 @@ extern void notification_pending_interrupt_handler(void);
extern ffa_id_t g_ffa_id;
+extern spinlock_t sp_handler_lock[NUM_VINT_ID];
+
void cactus_interrupt_handler(void)
{
uint32_t intid = spm_interrupt_get();
@@ -59,4 +61,11 @@ void cactus_interrupt_handler(void)
intid);
panic();
}
+
+ /* Invoke the tail end handler registered by the SP. */
+ spin_lock(&sp_handler_lock[intid]);
+ if (sp_interrupt_tail_end_handler[intid]) {
+ sp_interrupt_tail_end_handler[intid]();
+ }
+ spin_unlock(&sp_handler_lock[intid]);
}
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 58186d1..dd15d97 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -206,6 +206,9 @@ void __dead2 cactus_main(bool primary_cold_boot)
/* Configure and enable Stage-1 MMU, enable D-Cache */
cactus_plat_configure_mmu(ffa_id);
+
+ /* Initialize locks for tail end interrupt handler */
+ sp_handler_spin_lock_init();
}
/*
diff --git a/spm/common/sp_helpers.c b/spm/common/sp_helpers.c
index 77031f8..448084f 100644
--- a/spm/common/sp_helpers.c
+++ b/spm/common/sp_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,10 @@
#include "sp_helpers.h"
+spinlock_t sp_handler_lock[NUM_VINT_ID];
+
+void (*sp_interrupt_tail_end_handler[NUM_VINT_ID])(void);
+
uintptr_t bound_rand(uintptr_t min, uintptr_t max)
{
/*
@@ -80,3 +84,35 @@ void sp_sleep(uint32_t ms)
{
(void)sp_sleep_elapsed_time(ms);
}
+
+void sp_handler_spin_lock_init(void)
+{
+ for (uint32_t i = 0; i < NUM_VINT_ID; i++) {
+ init_spinlock(&sp_handler_lock[i]);
+ }
+}
+
+void sp_register_interrupt_tail_end_handler(void (*handler)(void),
+ uint32_t interrupt_id)
+{
+ if (interrupt_id >= NUM_VINT_ID) {
+ ERROR("Cannot register handler for interrupt %u\n", interrupt_id);
+ panic();
+ }
+
+ spin_lock(&sp_handler_lock[interrupt_id]);
+ sp_interrupt_tail_end_handler[interrupt_id] = handler;
+ spin_unlock(&sp_handler_lock[interrupt_id]);
+}
+
+void sp_unregister_interrupt_tail_end_handler(uint32_t interrupt_id)
+{
+ if (interrupt_id >= NUM_VINT_ID) {
+ ERROR("Cannot unregister handler for interrupt %u\n", interrupt_id);
+ panic();
+ }
+
+ spin_lock(&sp_handler_lock[interrupt_id]);
+ sp_interrupt_tail_end_handler[interrupt_id] = NULL;
+ spin_unlock(&sp_handler_lock[interrupt_id]);
+}
diff --git a/spm/common/sp_helpers.h b/spm/common/sp_helpers.h
index 6fe8ec0..ef60221 100644
--- a/spm/common/sp_helpers.h
+++ b/spm/common/sp_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,10 @@
#include <stdint.h>
#include <tftf_lib.h>
#include <spm_common.h>
+#include <spinlock.h>
+
+/* Currently, Hafnium/SPM supports only 64 virtual interrupt IDs. */
+#define NUM_VINT_ID 64
typedef struct {
u_register_t fid;
@@ -62,4 +66,16 @@ uint64_t sp_sleep_elapsed_time(uint32_t ms);
/* Sleep for at least 'ms' milliseconds. */
void sp_sleep(uint32_t ms);
+void sp_handler_spin_lock_init(void);
+
+/* Handler invoked at the tail end of interrupt processing by SP. */
+extern void (*sp_interrupt_tail_end_handler[NUM_VINT_ID])(void);
+
+/* Register the handler. */
+void sp_register_interrupt_tail_end_handler(void (*handler)(void),
+ uint32_t interrupt_id);
+
+/* Un-register the handler. */
+void sp_unregister_interrupt_tail_end_handler(uint32_t interrupt_id);
+
#endif /* SP_HELPERS_H */