feat: introduce SError exception handler

Introduce SError exception handler along with support to register a
custom handler. The default behaviour is same as before if no handler
is registered.
This patch will allow tests to do a graceful exit after handling an
SError.

Signed-off-by: Manish Pandey <manish.pandey2@arm.com>
Change-Id: Idbe37d3690e3a8e08fa3b0dff496d18d3022a8fc
diff --git a/include/lib/aarch64/serror.h b/include/lib/aarch64/serror.h
new file mode 100644
index 0000000..ac25f87
--- /dev/null
+++ b/include/lib/aarch64/serror.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SERROR_H__
+#define  __SERROR_H__
+
+typedef bool (*exception_handler_t)(void);
+void register_custom_serror_handler(exception_handler_t handler);
+void unregister_custom_serror_handler(void);
+
+#endif /* __SERROR_H__ */
diff --git a/lib/exceptions/aarch64/serror.c b/lib/exceptions/aarch64/serror.c
new file mode 100644
index 0000000..9c35712
--- /dev/null
+++ b/lib/exceptions/aarch64/serror.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <serror.h>
+
+static exception_handler_t custom_serror_handler;
+
+void register_custom_serror_handler(exception_handler_t handler)
+{
+	custom_serror_handler = handler;
+}
+
+void unregister_custom_serror_handler(void)
+{
+	custom_serror_handler = NULL;
+}
+
+bool tftf_serror_handler(void)
+{
+	if (custom_serror_handler == NULL) {
+		return false;
+	}
+
+	return custom_serror_handler();
+}
diff --git a/tftf/framework/aarch64/exceptions.S b/tftf/framework/aarch64/exceptions.S
index 3dedb92..471bef7 100644
--- a/tftf/framework/aarch64/exceptions.S
+++ b/tftf/framework/aarch64/exceptions.S
@@ -40,7 +40,9 @@
 end_vector_entry irq_sp_elx
 
 unhandled_exception fiq_sp_elx
-unhandled_exception serror_sp_elx
+vector_entry serror_sp_elx
+	b	serror_vector_entry
+end_vector_entry serror_sp_elx
 
 	/*
 	 * Lower EL using AArch64 : 0x400 - 0x600.
@@ -122,6 +124,21 @@
 	eret
 endfunc irq_vector_entry
 
+func serror_vector_entry
+	sub	sp, sp, #0x100
+	save_gp_regs
+	bl	tftf_serror_handler
+	cbnz	x0, 1f
+	mov	x0, x19
+	/* Save original stack pointer value on the stack */
+	add	x1, x0, #0x100
+	str	x1, [x0, #0xf8]
+	b	print_exception
+1:	restore_gp_regs
+	add	sp, sp, #0x100
+	eret
+endfunc serror_vector_entry
+
 func crash_dump
 	/* Save general-purpose registers on the stack. */
 	sub	sp, sp, #0x100
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index ddae823..ef59502 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -82,6 +82,7 @@
 # ARMv8.3 Pointer Authentication support files
 FRAMEWORK_SOURCES	+=						\
 	lib/exceptions/aarch64/sync.c					\
+	lib/exceptions/aarch64/serror.c					\
 	lib/extensions/pauth/aarch64/pauth.c				\
 	lib/extensions/pauth/aarch64/pauth_helpers.S			\
 	lib/extensions/sme/aarch64/sme.c				\