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 early_initcall_begin \
38 			SCATTERED_ARRAY_BEGIN(early_initcall, struct initcall)
39 #define early_initcall_end \
40 			SCATTERED_ARRAY_END(early_initcall, struct initcall)
41 
42 #define service_initcall_begin \
43 			SCATTERED_ARRAY_BEGIN(service_initcall, struct initcall)
44 #define service_initcall_end \
45 			SCATTERED_ARRAY_END(service_initcall, struct initcall)
46 
47 #define driver_initcall_begin \
48 			SCATTERED_ARRAY_BEGIN(driver_initcall, struct initcall)
49 #define driver_initcall_end \
50 			SCATTERED_ARRAY_END(driver_initcall, struct initcall)
51 
52 #define finalcall_begin	SCATTERED_ARRAY_BEGIN(finalcall, struct initcall)
53 #define finalcall_end	SCATTERED_ARRAY_END(finalcall, struct initcall)
54 
55 /*
56  * The preinit_*(), *_init() and boot_final() macros are used to register
57  * callback functions to be called at different stages during
58  * initialization.
59  *
60  * Functions registered with preinit_*() are always called before functions
61  * registered with *_init().
62  *
63  * Functions registered with boot_final() are called before exiting to
64  * normal world the first time.
65  *
66  * Without virtualization this happens in the order of the defines below.
67  *
68  * However, with virtualization things are a bit different. boot_final()
69  * functions are called first before exiting to normal world the first
70  * time. Functions registered with boot_final() can only operate on the
71  * nexus. preinit_*() functions are called early before the first yielding
72  * call into the partition, in the newly created partition. *_init()
73  * functions are called at the first yielding call.
74  *
75  *  +-------------------------------+-----------------------------------+
76  *  | Without virtualization        | With virtualization               |
77  *  +-------------------------------+-----------------------------------+
78  *  | At the end of boot_init_primary_late() just before the print:     |
79  *  | "Primary CPU switching to normal world boot"                      |
80  *  +-------------------------------+-----------------------------------+
81  *  | 1. call_preinitcalls()        | In the nexus, final calls         |
82  *  | 2. call_initcalls()           +-----------------------------------+
83  *  | 3. call_finalcalls()          | 1. boot_final() / nex_*init*()    |
84  *  +-------------------------------+-----------------------------------+
85  *  | "Primary CPU switching to normal world boot" is printed           |
86  *  +-------------------------------+-----------------------------------+
87  *                                  | A guest is created and            |
88  *                                  | virt_guest_created() is called.   |
89  *                                  | After the partition has been      |
90  *                                  | created and activated.            |
91  *                                  +-----------------------------------+
92  *                                  | 2. call_preinitcalls()            |
93  *                                  +-----------------------------------+
94  *                                  | When the partition is receiving   |
95  *                                  | the first yielding call           |
96  *                                  | virt_on_stdcall() is called.      |
97  *                                  +-----------------------------------+
98  *                                  | 3. call_initcalls()               |
99  *                                  +-----------------------------------+
100  */
101 
102 #define preinit_early(fn)		__define_initcall(preinit, 1, fn)
103 #define preinit(fn)			__define_initcall(preinit, 2, fn)
104 #define preinit_late(fn)		__define_initcall(preinit, 3, fn)
105 
106 #define early_init(fn)			__define_initcall(early_init, 1, fn)
107 #define early_init_late(fn)		__define_initcall(early_init, 2, fn)
108 #define service_init_crypto(fn)		__define_initcall(service_init, 1, fn)
109 #define service_init(fn)		__define_initcall(service_init, 2, fn)
110 #define service_init_late(fn)		__define_initcall(service_init, 3, fn)
111 #define driver_init(fn)			__define_initcall(driver_init, 1, fn)
112 #define driver_init_late(fn)		__define_initcall(driver_init, 2, fn)
113 #define release_init_resource(fn)	__define_initcall(driver_init, 3, fn)
114 
115 #define boot_final(fn)			__define_initcall(final, 1, fn)
116 
117 /*
118  * These nex_* init-calls are provided for drivers and services that reside
119  * in the nexus in case of virtualization. The init-calls are performed
120  * before exiting to the non-secure world at the end of boot
121  * initialization. In case of virtualization the init-calls are based on
122  * final calls, while otherwise are the same as the non-nex counterpart.
123  */
124 #ifdef CFG_NS_VIRTUALIZATION
125 #define nex_early_init(fn)		boot_final(fn)
126 #define nex_early_init_late(fn)		__define_initcall(final, 2, fn)
127 #define nex_service_init(fn)		__define_initcall(final, 3, fn)
128 #define nex_service_init_late(fn)	__define_initcall(final, 4, fn)
129 #define nex_driver_init(fn)		__define_initcall(final, 5, fn)
130 #define nex_driver_init_late(fn)	__define_initcall(final, 6, fn)
131 #define nex_release_init_resource(fn)	__define_initcall(final, 7, fn)
132 #else
133 #define nex_early_init(fn)		early_init(fn)
134 #define nex_early_init_late(fn)		early_init_late(fn)
135 #define nex_service_init(fn)		service_init(fn)
136 #define nex_service_init_late(fn)	service_init_late(fn)
137 #define nex_driver_init(fn)		driver_init(fn)
138 #define nex_driver_init_late(fn)	driver_init_late(fn)
139 #define nex_release_init_resource(fn)	release_init_resource(fn)
140 #endif
141 
142 void call_preinitcalls(void);
143 void call_early_initcalls(void);
144 void call_service_initcalls(void);
145 void call_driver_initcalls(void);
146 void call_initcalls(void);
147 void call_finalcalls(void);
148 
149 #endif
150