BL31: Introduce Publish and Subscribe framework

This light-weight framework enables some EL3 components to publish
events which other EL3 components can subscribe to. Publisher can
optionally pass opaque data for subscribers. The order in which
subscribers are called is not defined.

Firmware design updated.

Change-Id: I24a3a70b2b1dedcb1f73cf48313818aebf75ebb6
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h
new file mode 100644
index 0000000..9a85480
--- /dev/null
+++ b/include/lib/el3_runtime/pubsub.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PUBSUB_H__
+#define __PUBSUB_H__
+
+#define __pubsub_start_sym(event)	__pubsub_##event##_start
+#define __pubsub_end_sym(event)		__pubsub_##event##_end
+
+#ifdef __LINKER__
+
+/* For the linker ... */
+
+#define __pubsub_section(event)		__pubsub_##event
+
+/*
+ * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler
+ * contexts. In linker context, this collects pubsub sections for each event,
+ * placing guard symbols around each.
+ */
+#define REGISTER_PUBSUB_EVENT(event) \
+	__pubsub_start_sym(event) = .; \
+	KEEP(*(__pubsub_section(event))); \
+	__pubsub_end_sym(event) = .
+
+#else /* __LINKER__ */
+
+/* For the compiler ... */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cdefs.h>
+#include <stddef.h>
+
+#define __pubsub_section(event)		__section("__pubsub_" #event)
+
+/*
+ * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols
+ * exported by the linker required for the other pubsub macros to work.
+ */
+#define REGISTER_PUBSUB_EVENT(event) \
+	extern pubsub_cb_t __pubsub_start_sym(event)[]; \
+	extern pubsub_cb_t __pubsub_end_sym(event)[]
+
+/*
+ * Have the function func called back when the specified event happens. This
+ * macro places the function address into the pubsub section, which is picked up
+ * and invoked by the invoke_pubsubs() function via. the PUBLISH_EVENT* macros.
+ */
+#define SUBSCRIBE_TO_EVENT(event, func) \
+	pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = func
+
+/*
+ * Iterate over subscribed handlers for a defined event. 'event' is the name of
+ * the event, and 'subscriber' a local variable of type 'pubsub_cb_t *'.
+ */
+#define for_each_subscriber(event, subscriber) \
+	for (subscriber = __pubsub_start_sym(event); \
+			subscriber < __pubsub_end_sym(event); \
+			subscriber++)
+
+/*
+ * Publish a defined event supplying an argument. All subscribed handlers are
+ * invoked, but the return value of handlers are ignored for now.
+ */
+#define PUBLISH_EVENT_ARG(event, arg) \
+	do { \
+		pubsub_cb_t *subscriber; \
+		for_each_subscriber(event, subscriber) { \
+			(*subscriber)(arg); \
+		} \
+	} while (0)
+
+/* Publish a defined event with NULL argument */
+#define PUBLISH_EVENT(event)	PUBLISH_EVENT_ARG(event, NULL)
+
+/* Subscriber callback type */
+typedef void* (*pubsub_cb_t)(const void *arg);
+
+#endif	/* __LINKER__ */
+#endif	/* __PUBSUB_H__ */