feat(tftf): introduce handler for synchronous exceptions
Introduce a handler for synchronous exceptions (for aarch64) which
currently is treated as unhandled exception.
Also, added the capability to allow registering a custom handler by tftf
framework to allow graceful exit while doing negative tests.
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Change-Id: I4d8d1f5af9951edfe8f068ce85f7d434b2ec070f
diff --git a/include/lib/aarch64/sync.h b/include/lib/aarch64/sync.h
new file mode 100644
index 0000000..5058980
--- /dev/null
+++ b/include/lib/aarch64/sync.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SYNC_H__
+#define __SYNC_H__
+
+typedef bool (*exception_handler_t)(void);
+void register_custom_sync_exception_handler(exception_handler_t handler);
+void unregister_custom_sync_exception_handler(void);
+
+#endif /* __SYNC_H__ */
diff --git a/lib/exceptions/aarch64/sync.c b/lib/exceptions/aarch64/sync.c
new file mode 100644
index 0000000..49b6bd8
--- /dev/null
+++ b/lib/exceptions/aarch64/sync.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <sync.h>
+
+static exception_handler_t custom_sync_exception_handler;
+
+void register_custom_sync_exception_handler(exception_handler_t handler)
+{
+ custom_sync_exception_handler = handler;
+}
+
+void unregister_custom_sync_exception_handler(void)
+{
+ custom_sync_exception_handler = NULL;
+}
+
+bool tftf_sync_exception_handler(void)
+{
+ uint64_t elr_elx = IS_IN_EL2() ? read_elr_el2() : read_elr_el1();
+ bool resume = false;
+
+ if (custom_sync_exception_handler == NULL) {
+ return false;
+ }
+
+ resume = custom_sync_exception_handler();
+
+ if (resume) {
+ /* Move ELR to next instruction to allow tftf to continue */
+ if (IS_IN_EL2()) {
+ write_elr_el2(elr_elx + 4U);
+ } else {
+ write_elr_el1(elr_elx + 4U);
+ }
+ }
+
+ return resume;
+}
diff --git a/lib/irq/irq.c b/lib/exceptions/irq.c
similarity index 100%
rename from lib/irq/irq.c
rename to lib/exceptions/irq.c
diff --git a/tftf/framework/aarch64/exceptions.S b/tftf/framework/aarch64/exceptions.S
index 218cca3..3dedb92 100644
--- a/tftf/framework/aarch64/exceptions.S
+++ b/tftf/framework/aarch64/exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,7 +31,9 @@
/*
* Current EL with SPx : 0x200 - 0x400.
*/
-unhandled_exception sync_exception_sp_elx
+vector_entry sync_spx
+ b sync_exception_vector_entry
+end_vector_entry sync_spx
vector_entry irq_sp_elx
b irq_vector_entry
@@ -95,6 +97,22 @@
ldp x0, x1, [sp, #0x0]
.endm
+func sync_exception_vector_entry
+ sub sp, sp, #0x100
+ save_gp_regs
+ mov x19, sp
+ bl tftf_sync_exception_handler
+ cbnz x0, 0f
+ mov x0, x19
+ /* Save original stack pointer value on the stack */
+ add x1, x0, #0x100
+ str x1, [x0, #0xf8]
+ b print_exception
+0: restore_gp_regs
+ add sp, sp, #0x100
+ eret
+endfunc sync_exception_vector_entry
+
func irq_vector_entry
sub sp, sp, #0x100
save_gp_regs
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index 2965926..11026f2 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -53,7 +53,7 @@
lib/events/events.c \
lib/extensions/amu/${ARCH}/amu.c \
lib/extensions/amu/${ARCH}/amu_helpers.S \
- lib/irq/irq.c \
+ lib/exceptions/irq.c \
lib/locks/${ARCH}/spinlock.S \
lib/power_management/hotplug/hotplug.c \
lib/power_management/suspend/${ARCH}/asm_tftf_suspend.S \
@@ -79,6 +79,7 @@
ifeq (${ARCH},aarch64)
# ARMv8.3 Pointer Authentication support files
FRAMEWORK_SOURCES += \
+ lib/exceptions/aarch64/sync.c \
lib/extensions/pauth/aarch64/pauth.c \
lib/extensions/pauth/aarch64/pauth_helpers.S \
lib/extensions/sme/aarch64/sme.c \