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				\