xref: /rk3399_ARM-atf/include/lib/el3_runtime/pubsub.h (revision 8e743bcd6a69bce2ac782319951061c69798558d)
1*8e743bcdSJeenu Viswambharan /*
2*8e743bcdSJeenu Viswambharan  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3*8e743bcdSJeenu Viswambharan  *
4*8e743bcdSJeenu Viswambharan  * SPDX-License-Identifier: BSD-3-Clause
5*8e743bcdSJeenu Viswambharan  */
6*8e743bcdSJeenu Viswambharan 
7*8e743bcdSJeenu Viswambharan #ifndef __PUBSUB_H__
8*8e743bcdSJeenu Viswambharan #define __PUBSUB_H__
9*8e743bcdSJeenu Viswambharan 
10*8e743bcdSJeenu Viswambharan #define __pubsub_start_sym(event)	__pubsub_##event##_start
11*8e743bcdSJeenu Viswambharan #define __pubsub_end_sym(event)		__pubsub_##event##_end
12*8e743bcdSJeenu Viswambharan 
13*8e743bcdSJeenu Viswambharan #ifdef __LINKER__
14*8e743bcdSJeenu Viswambharan 
15*8e743bcdSJeenu Viswambharan /* For the linker ... */
16*8e743bcdSJeenu Viswambharan 
17*8e743bcdSJeenu Viswambharan #define __pubsub_section(event)		__pubsub_##event
18*8e743bcdSJeenu Viswambharan 
19*8e743bcdSJeenu Viswambharan /*
20*8e743bcdSJeenu Viswambharan  * REGISTER_PUBSUB_EVENT has a different definition between linker and compiler
21*8e743bcdSJeenu Viswambharan  * contexts. In linker context, this collects pubsub sections for each event,
22*8e743bcdSJeenu Viswambharan  * placing guard symbols around each.
23*8e743bcdSJeenu Viswambharan  */
24*8e743bcdSJeenu Viswambharan #define REGISTER_PUBSUB_EVENT(event) \
25*8e743bcdSJeenu Viswambharan 	__pubsub_start_sym(event) = .; \
26*8e743bcdSJeenu Viswambharan 	KEEP(*(__pubsub_section(event))); \
27*8e743bcdSJeenu Viswambharan 	__pubsub_end_sym(event) = .
28*8e743bcdSJeenu Viswambharan 
29*8e743bcdSJeenu Viswambharan #else /* __LINKER__ */
30*8e743bcdSJeenu Viswambharan 
31*8e743bcdSJeenu Viswambharan /* For the compiler ... */
32*8e743bcdSJeenu Viswambharan 
33*8e743bcdSJeenu Viswambharan #include <arch_helpers.h>
34*8e743bcdSJeenu Viswambharan #include <assert.h>
35*8e743bcdSJeenu Viswambharan #include <cdefs.h>
36*8e743bcdSJeenu Viswambharan #include <stddef.h>
37*8e743bcdSJeenu Viswambharan 
38*8e743bcdSJeenu Viswambharan #define __pubsub_section(event)		__section("__pubsub_" #event)
39*8e743bcdSJeenu Viswambharan 
40*8e743bcdSJeenu Viswambharan /*
41*8e743bcdSJeenu Viswambharan  * In compiler context, REGISTER_PUBSUB_EVENT declares the per-event symbols
42*8e743bcdSJeenu Viswambharan  * exported by the linker required for the other pubsub macros to work.
43*8e743bcdSJeenu Viswambharan  */
44*8e743bcdSJeenu Viswambharan #define REGISTER_PUBSUB_EVENT(event) \
45*8e743bcdSJeenu Viswambharan 	extern pubsub_cb_t __pubsub_start_sym(event)[]; \
46*8e743bcdSJeenu Viswambharan 	extern pubsub_cb_t __pubsub_end_sym(event)[]
47*8e743bcdSJeenu Viswambharan 
48*8e743bcdSJeenu Viswambharan /*
49*8e743bcdSJeenu Viswambharan  * Have the function func called back when the specified event happens. This
50*8e743bcdSJeenu Viswambharan  * macro places the function address into the pubsub section, which is picked up
51*8e743bcdSJeenu Viswambharan  * and invoked by the invoke_pubsubs() function via. the PUBLISH_EVENT* macros.
52*8e743bcdSJeenu Viswambharan  */
53*8e743bcdSJeenu Viswambharan #define SUBSCRIBE_TO_EVENT(event, func) \
54*8e743bcdSJeenu Viswambharan 	pubsub_cb_t __cb_func_##func##event __pubsub_section(event) = func
55*8e743bcdSJeenu Viswambharan 
56*8e743bcdSJeenu Viswambharan /*
57*8e743bcdSJeenu Viswambharan  * Iterate over subscribed handlers for a defined event. 'event' is the name of
58*8e743bcdSJeenu Viswambharan  * the event, and 'subscriber' a local variable of type 'pubsub_cb_t *'.
59*8e743bcdSJeenu Viswambharan  */
60*8e743bcdSJeenu Viswambharan #define for_each_subscriber(event, subscriber) \
61*8e743bcdSJeenu Viswambharan 	for (subscriber = __pubsub_start_sym(event); \
62*8e743bcdSJeenu Viswambharan 			subscriber < __pubsub_end_sym(event); \
63*8e743bcdSJeenu Viswambharan 			subscriber++)
64*8e743bcdSJeenu Viswambharan 
65*8e743bcdSJeenu Viswambharan /*
66*8e743bcdSJeenu Viswambharan  * Publish a defined event supplying an argument. All subscribed handlers are
67*8e743bcdSJeenu Viswambharan  * invoked, but the return value of handlers are ignored for now.
68*8e743bcdSJeenu Viswambharan  */
69*8e743bcdSJeenu Viswambharan #define PUBLISH_EVENT_ARG(event, arg) \
70*8e743bcdSJeenu Viswambharan 	do { \
71*8e743bcdSJeenu Viswambharan 		pubsub_cb_t *subscriber; \
72*8e743bcdSJeenu Viswambharan 		for_each_subscriber(event, subscriber) { \
73*8e743bcdSJeenu Viswambharan 			(*subscriber)(arg); \
74*8e743bcdSJeenu Viswambharan 		} \
75*8e743bcdSJeenu Viswambharan 	} while (0)
76*8e743bcdSJeenu Viswambharan 
77*8e743bcdSJeenu Viswambharan /* Publish a defined event with NULL argument */
78*8e743bcdSJeenu Viswambharan #define PUBLISH_EVENT(event)	PUBLISH_EVENT_ARG(event, NULL)
79*8e743bcdSJeenu Viswambharan 
80*8e743bcdSJeenu Viswambharan /* Subscriber callback type */
81*8e743bcdSJeenu Viswambharan typedef void* (*pubsub_cb_t)(const void *arg);
82*8e743bcdSJeenu Viswambharan 
83*8e743bcdSJeenu Viswambharan #endif	/* __LINKER__ */
84*8e743bcdSJeenu Viswambharan #endif	/* __PUBSUB_H__ */
85