File: initcall.h

package info (click to toggle)
optee-os 4.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,960 kB
  • sloc: ansic: 444,388; asm: 12,922; python: 3,719; makefile: 1,681; sh: 238
file content (148 lines) | stat: -rw-r--r-- 6,447 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * Copyright (c) 2014, Linaro Limited
 */

#ifndef __INITCALL_H
#define __INITCALL_H

#include <scattered_array.h>
#include <tee_api_types.h>
#include <trace.h>

struct initcall {
	TEE_Result (*func)(void);
#if TRACE_LEVEL >= TRACE_DEBUG
	int level;
	const char *func_name;
#endif
};

#if TRACE_LEVEL >= TRACE_DEBUG
#define __define_initcall(type, lvl, fn) \
	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \
					       struct initcall) = \
		{ .func = (fn), .level = (lvl), .func_name = #fn, }
#else
#define __define_initcall(type, lvl, fn) \
	SCATTERED_ARRAY_DEFINE_PG_ITEM_ORDERED(type ## call, lvl, \
					       struct initcall) = \
		{ .func = (fn), }
#endif

#define preinitcall_begin \
			SCATTERED_ARRAY_BEGIN(preinitcall, struct initcall)
#define preinitcall_end SCATTERED_ARRAY_END(preinitcall, struct initcall)

#define early_initcall_begin \
			SCATTERED_ARRAY_BEGIN(early_initcall, struct initcall)
#define early_initcall_end \
			SCATTERED_ARRAY_END(early_initcall, struct initcall)

#define service_initcall_begin \
			SCATTERED_ARRAY_BEGIN(service_initcall, struct initcall)
#define service_initcall_end \
			SCATTERED_ARRAY_END(service_initcall, struct initcall)

#define driver_initcall_begin \
			SCATTERED_ARRAY_BEGIN(driver_initcall, struct initcall)
#define driver_initcall_end \
			SCATTERED_ARRAY_END(driver_initcall, struct initcall)

#define finalcall_begin	SCATTERED_ARRAY_BEGIN(finalcall, struct initcall)
#define finalcall_end	SCATTERED_ARRAY_END(finalcall, struct initcall)

/*
 * The preinit_*(), *_init() and boot_final() macros are used to register
 * callback functions to be called at different stages during
 * initialization.
 *
 * Functions registered with preinit_*() are always called before functions
 * registered with *_init().
 *
 * Functions registered with boot_final() are called before exiting to
 * normal world the first time.
 *
 * Without virtualization this happens in the order of the defines below.
 *
 * However, with virtualization things are a bit different. boot_final()
 * functions are called first before exiting to normal world the first
 * time. Functions registered with boot_final() can only operate on the
 * nexus. preinit_*() functions are called early before the first yielding
 * call into the partition, in the newly created partition. *_init()
 * functions are called at the first yielding call.
 *
 *  +-------------------------------+-----------------------------------+
 *  | Without virtualization        | With virtualization               |
 *  +-------------------------------+-----------------------------------+
 *  | At the end of boot_init_primary_late() just before the print:     |
 *  | "Primary CPU switching to normal world boot"                      |
 *  +-------------------------------+-----------------------------------+
 *  | 1. call_preinitcalls()        | In the nexus, final calls         |
 *  | 2. call_initcalls()           +-----------------------------------+
 *  | 3. call_finalcalls()          | 1. nex_*init*() / boot_final()    |
 *  +-------------------------------+-----------------------------------+
 *  | "Primary CPU switching to normal world boot" is printed           |
 *  +-------------------------------+-----------------------------------+
 *                                  | A guest is created and            |
 *                                  | virt_guest_created() is called.   |
 *                                  | After the partition has been      |
 *                                  | created and activated.            |
 *                                  +-----------------------------------+
 *                                  | 2. call_preinitcalls()            |
 *                                  +-----------------------------------+
 *                                  | When the partition is receiving   |
 *                                  | the first yielding call           |
 *                                  | virt_on_stdcall() is called.      |
 *                                  +-----------------------------------+
 *                                  | 3. call_initcalls()               |
 *                                  +-----------------------------------+
 */

#define preinit_early(fn)		__define_initcall(preinit, 1, fn)
#define preinit(fn)			__define_initcall(preinit, 2, fn)
#define preinit_late(fn)		__define_initcall(preinit, 3, fn)

#define early_init(fn)			__define_initcall(early_init, 1, fn)
#define early_init_late(fn)		__define_initcall(early_init, 2, fn)
#define service_init_crypto(fn)		__define_initcall(service_init, 1, fn)
#define service_init(fn)		__define_initcall(service_init, 2, fn)
#define service_init_late(fn)		__define_initcall(service_init, 3, fn)
#define driver_init(fn)			__define_initcall(driver_init, 1, fn)
#define driver_init_late(fn)		__define_initcall(driver_init, 2, fn)
#define release_init_resource(fn)	__define_initcall(driver_init, 3, fn)

/*
 * These nex_* init-calls are provided for drivers and services that reside
 * in the nexus in case of virtualization. The init-calls are performed
 * before exiting to the non-secure world at the end of boot
 * initialization. In case of virtualization the init-calls are based on
 * final calls, while otherwise are the same as the non-nex counterpart.
 */
#ifdef CFG_NS_VIRTUALIZATION
#define nex_early_init(fn)		__define_initcall(final, 1, fn)
#define nex_early_init_late(fn)		__define_initcall(final, 2, fn)
#define nex_service_init(fn)		__define_initcall(final, 3, fn)
#define nex_service_init_late(fn)	__define_initcall(final, 4, fn)
#define nex_driver_init(fn)		__define_initcall(final, 5, fn)
#define nex_driver_init_late(fn)	__define_initcall(final, 6, fn)
#define nex_release_init_resource(fn)	__define_initcall(final, 7, fn)
#else
#define nex_early_init(fn)		early_init(fn)
#define nex_early_init_late(fn)		early_init_late(fn)
#define nex_service_init(fn)		service_init(fn)
#define nex_service_init_late(fn)	service_init_late(fn)
#define nex_driver_init(fn)		driver_init(fn)
#define nex_driver_init_late(fn)	driver_init_late(fn)
#define nex_release_init_resource(fn)	release_init_resource(fn)
#endif

#define boot_final(fn)			__define_initcall(final, 8, fn)

void call_preinitcalls(void);
void call_early_initcalls(void);
void call_service_initcalls(void);
void call_driver_initcalls(void);
void call_finalcalls(void);

#endif