1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2014, Linaro Limited
4  */
5 
6 #ifndef INITCALL_H
7 #define INITCALL_H
8 
9 #include <scattered_array.h>
10 #include <tee_api_types.h>
11 #include <trace.h>
12 
13 struct initcall {
14 	TEE_Result (*func)(void);
15 #if TRACE_LEVEL >= TRACE_DEBUG
16 	int level;
17 	const char *func_name;
18 #endif
19 };
20 
21 #if TRACE_LEVEL >= TRACE_DEBUG
22 #define __define_initcall(type, lvl, fn) \
23 	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \
24 					       struct initcall) = \
25 		{ .func = (fn), .level = (lvl), .func_name = #fn, }
26 #else
27 #define __define_initcall(type, lvl, fn) \
28 	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \
29 					       struct initcall) = \
30 		{ .func = (fn), }
31 #endif
32 
33 #define preinitcall_begin \
34 			SCATTERED_ARRAY_BEGIN(preinitcall, struct initcall)
35 #define preinitcall_end SCATTERED_ARRAY_END(preinitcall, struct initcall)
36 
37 #define initcall_begin	SCATTERED_ARRAY_BEGIN(initcall, struct initcall)
38 #define initcall_end	SCATTERED_ARRAY_END(initcall, struct initcall)
39 
40 #define finalcall_begin	SCATTERED_ARRAY_BEGIN(finalcall, struct initcall)
41 #define finalcall_end	SCATTERED_ARRAY_END(finalcall, struct initcall)
42 
43 /*
44  * The preinit_*(), *_init() and boot_final() macros are used to register
45  * callback functions to be called at different stages during
46  * initialization.
47  *
48  * Functions registered with preinit_*() are always called before functions
49  * registered with *_init().
50  *
51  * Functions registered with boot_final() are called before exiting to
52  * normal world the first time.
53  *
54  * Without virtualization this happens in the order of the defines below.
55  *
56  * However, with virtualization things are a bit different. boot_final()
57  * functions are called first before exiting to normal world the first
58  * time. Functions registered with boot_final() can only operate on the
59  * nexus. preinit_*() functions are called early before the first yielding
60  * call into the partition, in the newly created partition. *_init()
61  * functions are called at the first yielding call.
62  *
63  *  +-------------------------------+-----------------------------------+
64  *  | Without virtualization        | With virtualization               |
65  *  +-------------------------------+-----------------------------------+
66  *  | At the end of boot_init_primary_late() just before the print:     |
67  *  | "Primary CPU switching to normal world boot"                      |
68  *  +-------------------------------+-----------------------------------+
69  *  | 1. call_preinitcalls()        | In the nexus                      |
70  *  | 2. call_initcalls()           +-----------------------------------+
71  *  | 3. call_finalcalls()          | 1. call_finalcalls()              |
72  *  +-------------------------------+-----------------------------------+
73  *  | "Primary CPU switching to normal world boot" is printed           |
74  *  +-------------------------------+-----------------------------------+
75  *                                  | A guest is created and            |
76  *                                  | virt_guest_created() is called.   |
77  *                                  | After the partition has been      |
78  *                                  | created and activated.            |
79  *                                  +-----------------------------------+
80  *                                  | 2. call_preinitcalls()            |
81  *                                  +-----------------------------------+
82  *                                  | When the partition is receiving   |
83  *                                  | the first yielding call           |
84  *                                  | virt_on_stdcall() is called.      |
85  *                                  +-----------------------------------+
86  *                                  | 3. call_initcalls()               |
87  *                                  +-----------------------------------+
88  */
89 
90 #define preinit_early(fn)		__define_initcall(preinit, 1, fn)
91 #define preinit(fn)			__define_initcall(preinit, 2, fn)
92 #define preinit_late(fn)		__define_initcall(preinit, 3, fn)
93 
94 #define early_init(fn)			__define_initcall(init, 1, fn)
95 #define early_init_late(fn)		__define_initcall(init, 2, fn)
96 #define service_init(fn)		__define_initcall(init, 3, fn)
97 #define service_init_late(fn)		__define_initcall(init, 4, fn)
98 #define driver_init(fn)			__define_initcall(init, 5, fn)
99 #define driver_init_late(fn)		__define_initcall(init, 6, fn)
100 #define release_init_resource(fn)	__define_initcall(init, 7, fn)
101 
102 #define boot_final(fn)			__define_initcall(final, 1, fn)
103 
104 void call_preinitcalls(void);
105 void call_initcalls(void);
106 void call_finalcalls(void);
107 
108 #endif
109