Merge pull request #1810 from antonio-nino-diaz-arm/an/setjmp

Make setjmp/longjmp compliant with the C standard and move them to libc
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 89f5896..c9ba926 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -31,7 +31,6 @@
 				bl31/aarch64/runtime_exceptions.S		\
 				bl31/bl31_context_mgmt.c			\
 				common/runtime_svc.c				\
-				lib/aarch64/setjmp.S				\
 				lib/cpus/aarch64/dsu_helpers.S			\
 				plat/common/aarch64/platform_mp_stack.S		\
 				services/arm_arch_svc/arm_arch_svc_setup.c	\
diff --git a/include/arch/aarch64/setjmp.h b/include/arch/aarch64/setjmp.h
deleted file mode 100644
index bbfe1df..0000000
--- a/include/arch/aarch64/setjmp.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SETJMP_H
-#define SETJMP_H
-
-#define JMP_CTX_X19	0x0
-#define JMP_CTX_X21	0x10
-#define JMP_CTX_X23	0x20
-#define JMP_CTX_X25	0x30
-#define JMP_CTX_X27	0x40
-#define JMP_CTX_X29	0x50
-#define JMP_CTX_SP	0x60
-#define JMP_CTX_END	0x70
-
-#define JMP_SIZE	(JMP_CTX_END >> 3)
-
-#ifndef __ASSEMBLY__
-
-#include <stdint.h>
-
-/* Jump buffer hosting x18 - x30 and sp_el0 registers */
-struct jmpbuf {
-	uint64_t buf[JMP_SIZE];
-} __aligned(16);
-
-
-/*
- * Set a jump point, and populate the jump buffer with context information so
- * that longjmp() can jump later. The caller must adhere to the following
- * conditions:
- *
- *  - After calling this function, the stack must not be shrunk. The contents of
- *    the stack must not be changed either.
- *
- *  - If the caller were to 'return', the buffer must be considered invalid, and
- *    must not be used with longjmp().
- *
- * The caller will observe this function returning at two distinct
- * circumstances, each with different return values:
- *
- *  - Zero, when the buffer is setup;
- *
- *  - Non-zero, when a call to longjmp() is made (presumably by one of the
- *    callee functions) with the same jump buffer.
- */
-int setjmp(struct jmpbuf *buf);
-
-/*
- * Reset execution to a jump point, and restore context information according to
- * the jump buffer populated by setjmp().
- */
-void longjmp(struct jmpbuf *buf);
-
-#endif /* __ASSEMBLY__ */
-#endif /* SETJMP_H */
diff --git a/include/lib/libc/aarch64/setjmp_.h b/include/lib/libc/aarch64/setjmp_.h
new file mode 100644
index 0000000..174b3eb
--- /dev/null
+++ b/include/lib/libc/aarch64/setjmp_.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SETJMP__H
+#define SETJMP__H
+
+#define JMP_CTX_X19	0x0
+#define JMP_CTX_X21	0x10
+#define JMP_CTX_X23	0x20
+#define JMP_CTX_X25	0x30
+#define JMP_CTX_X27	0x40
+#define JMP_CTX_X29	0x50
+#define JMP_CTX_SP	0x60
+#define JMP_CTX_END	0x70 /* Aligned to 16 bytes */
+
+#define JMP_SIZE	(JMP_CTX_END >> 3)
+
+#ifndef __ASSEMBLY__
+
+#include <cdefs.h>
+
+/* Jump buffer hosting x18 - x30 and sp_el0 registers */
+typedef uint64_t jmp_buf[JMP_SIZE] __aligned(16);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* SETJMP__H */
diff --git a/include/lib/libc/setjmp.h b/include/lib/libc/setjmp.h
new file mode 100644
index 0000000..5661201
--- /dev/null
+++ b/include/lib/libc/setjmp.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SETJMP_H
+#define SETJMP_H
+
+#include <setjmp_.h>
+
+#ifndef __ASSEMBLY__
+
+#include <cdefs.h>
+
+int setjmp(jmp_buf env);
+__dead2 void longjmp(jmp_buf env, int val);
+
+#endif /* __ASSEMBLY__ */
+#endif /* SETJMP_H */
diff --git a/lib/aarch64/setjmp.S b/lib/libc/aarch64/setjmp.S
similarity index 72%
rename from lib/aarch64/setjmp.S
rename to lib/libc/aarch64/setjmp.S
index 9060cb7..9d9eb49 100644
--- a/lib/aarch64/setjmp.S
+++ b/lib/libc/aarch64/setjmp.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,10 +12,7 @@
 	.globl	longjmp
 
 /*
- * int setjmp(struct jmpbuf *buf);
- *
- * Sets a jump point in the buffer specified in x0. Returns 0 to the caller when
- * when setting up the jump, and 1 when returning from the jump.
+ * int setjmp(jmp_buf env);
  */
 func setjmp
 	mov	x7, sp
@@ -34,9 +31,7 @@
 
 
 /*
- * void longjmp(struct jmpbuf *buf);
- *
- * Return to a jump point setup by setjmp()
+ * void longjmp(jmp_buf env, int val);
  */
 func longjmp
 	ldp	x7, xzr, [x0, #JMP_CTX_SP]
@@ -60,6 +55,7 @@
 
 	mov	sp, x7
 
-	mov	x0, #1
+	ands	x0, x1, x1 /* Move val to x0 and set flags */
+	cinc	x0, x0, eq /* If val is 0, return 1 */
 	ret
 endfunc longjmp
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index 1276f5c..e1b5560 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -1,10 +1,10 @@
 #
-# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-LIBC_SRCS	:=	$(addprefix lib/libc/,	\
+LIBC_SRCS	:=	$(addprefix lib/libc/,		\
 			abort.c				\
 			assert.c			\
 			exit.c				\
@@ -25,5 +25,10 @@
 			strnlen.c			\
 			strrchr.c)
 
+ifeq (${ARCH},aarch64)
+LIBC_SRCS	+=	$(addprefix lib/libc/aarch64/,	\
+			setjmp.S)
+endif
+
 INCLUDES	+=	-Iinclude/lib/libc		\
 			-Iinclude/lib/libc/$(ARCH)	\
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 73b84c3..4a264d7 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -206,6 +206,22 @@
 
 endef
 
+# MAKE_S_LIB builds an assembly source file and generates the dependency file
+#   $(1) = output directory
+#   $(2) = source file (%.S)
+#   $(3) = library name
+define MAKE_S_LIB
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+	$$(ECHO) "  AS      $$<"
+	$$(Q)$$(AS) $$(ASFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
 
 # MAKE_C builds a C source file and generates the dependency file
 #   $(1) = output directory
@@ -263,7 +279,7 @@
 
 endef
 
-# MAKE_LIB_OBJS builds both C source files
+# MAKE_LIB_OBJS builds both C and assembly source files
 #   $(1) = output directory
 #   $(2) = list of source files
 #   $(3) = name of the library
@@ -272,6 +288,10 @@
         $(eval REMAIN := $(filter-out %.c,$(2)))
         $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
 
+        $(eval S_OBJS := $(filter %.S,$(REMAIN)))
+        $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+        $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S_LIB,$(1),$(obj),$(3))))
+
         $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
 endef
 
diff --git a/services/std_svc/sdei/sdei_dispatch.S b/services/std_svc/sdei/sdei_dispatch.S
index a7a4a40..8449e4b 100644
--- a/services/std_svc/sdei/sdei_dispatch.S
+++ b/services/std_svc/sdei/sdei_dispatch.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,7 +9,7 @@
 	.globl	begin_sdei_synchronous_dispatch
 
 /*
- * void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer);
+ * void begin_sdei_synchronous_dispatch(jmp_buf *buffer);
  *
  * Begin SDEI dispatch synchronously by setting up a jump point, and exiting
  * EL3. This jump point is jumped to by the dispatcher after the event is
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index b8799cd..fa1d3d2 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,7 @@
 typedef struct sdei_dispatch_context {
 	sdei_ev_map_t *map;
 	uint64_t x[SDEI_SAVED_GPREGS];
-	struct jmpbuf *dispatch_jmp;
+	jmp_buf *dispatch_jmp;
 
 	/* Exception state registers */
 	uint64_t elr_el3;
@@ -236,7 +236,7 @@
  * SDEI client.
  */
 static void setup_ns_dispatch(sdei_ev_map_t *map, sdei_entry_t *se,
-		cpu_context_t *ctx, struct jmpbuf *dispatch_jmp)
+		cpu_context_t *ctx, jmp_buf *dispatch_jmp)
 {
 	sdei_dispatch_context_t *disp_ctx;
 
@@ -347,7 +347,7 @@
 	unsigned int sec_state;
 	sdei_cpu_state_t *state;
 	uint32_t intr;
-	struct jmpbuf dispatch_jmp;
+	jmp_buf dispatch_jmp;
 	const uint64_t mpidr = read_mpidr_el1();
 
 	/*
@@ -529,7 +529,7 @@
 	cpu_context_t *ns_ctx;
 	sdei_dispatch_context_t *disp_ctx;
 	sdei_cpu_state_t *state;
-	struct jmpbuf dispatch_jmp;
+	jmp_buf dispatch_jmp;
 
 	/* Can't dispatch if events are masked on this PE */
 	state = sdei_get_this_pe_state();
@@ -595,9 +595,9 @@
 	return 0;
 }
 
-static void end_sdei_synchronous_dispatch(struct jmpbuf *buffer)
+static void end_sdei_synchronous_dispatch(jmp_buf *buffer)
 {
-	longjmp(buffer);
+	longjmp(*buffer, 1);
 }
 
 int sdei_event_complete(bool resume, uint64_t pc)
diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h
index 1486431..8cc66e7 100644
--- a/services/std_svc/sdei/sdei_private.h
+++ b/services/std_svc/sdei/sdei_private.h
@@ -243,6 +243,6 @@
 int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
 		void *cookie);
 bool can_sdei_state_trans(sdei_entry_t *se, sdei_action_t act);
-void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer);
+void begin_sdei_synchronous_dispatch(jmp_buf *buffer);
 
 #endif /* SDEI_PRIVATE_H */